FreeBSD on XPS 13: Part 2

Posted on | 948 words | ~5 mins

In Part 1, I installed FreeBSD on my Dell XPS 13, configured wireless networking, and created a new boot environment. In this part, I’ll install some of the software that I need and start on the configuration of the system.

Display Resolution

When I bought this laptop, I opted for a variant with a QHD+ screen. In hindsight, I wish I hadn’t done that. While the HiDPI situation in Linux has improved over the past few years, the experience is still far from seamless, and the situation in Windows isn’t much better. Only macOS seems to have done it right, so unless you’re using a Mac, these days I’d suggest sticking with a 1080p screen (or 1440p if it’s large).

The text on my screen was pretty tiny at this point and it was starting to hurt my eyes, so I decided to try and fix that. A quick look at the vt man page showed that there was an option to override the graphics mode used, however it required a KMS video driver. As mentioned in the previous part, the integrated graphics in my laptop were too recent to be supported by the i915 driver in the kernel, so I had to install the drm-next-kmod port:

# cd /usr/ports/graphics/drm-next-kmod
# make config-recursive
# make install

I then configured the kernel module to be loaded at boot in /etc/rc.conf:


After that, I was able to make the necessary changes in /boot/loader.conf to change the graphics mode used by vt (and disable the bell while I was at it):


After rebooting, I was met with much more reasonably-sized text. Yes!

Giving Up Root

It’s considered bad practice to run everything as root, so now that I could see what I was typing I decided it was time to install and configure sudo. This is pretty easy and just consists of installing sudo from ports, adding myself to the sudo group, and uncommenting the necessary line in the sudoers file:

# cd /usr/ports/security/sudo
# make config-recursive
# make install
# pw groupadd sudo -M james
# visudo

With that done, I logged out and logged back in as my user rather than root.

Doing Ports Properly

So far, I’d been installing ports by cding into their directory and invoking make. While that works, it gets a bit unwieldy, especially when you need to work out which ports have updates available (and which ports need rebuilding to make use of those updates). To make all of that easier, I decided to install the portmaster port which makes it all much easier:

# cd /usr/ports/ports-mgmt/portmaster
# sudo make config-recursive
# sudo make install

From now on, installing ports should be much easier! This seemed like a good point to make a new boot environment and boot into it.

Config, Editors, Shells, etc

Given the amount of time we put into tweaking our dotfiles until they’re just right, it amazes me how many people don’t version control them. In the past, I used to keep my dotfiles in a git repository along with a script to create the required symlinks to them. A lot of people use GNU Stow to achieve the same thing. However, last year I discovered this neat little trick that allows you to keep your dotfiles in git using no additional tooling aside from a little shell alias. Before starting to install and configure shells and editors and the like, I installed git and set it up to track my dotfiles:

# sudo portmaster devel/git
# git config --global "<name>"
# git config --global "<email address>"
# git init --bare $HOME/.cfg
# alias config='git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
# config config --local status.showUntrackedFiles no

Next up, I needed to install an editor. For the past couple of years, I’ve been using Visual Studio Code, which seems to be quite fast despite being electron based and has an excellent collection of extensions. Unfortunately, electron doesn’t have FreeBSD support (although that issue suggests it may land in ports soon!), so I had to go with my backup editor, (neo)vim. Neovim was in ports (seeing a pattern here?), so it was easy to install, configure, and add to my dotfile version control:

# sudo portmaster editors/neovim
# mkdir -p ~/.config/nvim
# nvim ~/.config/nvim/init.vim
# config add ~/.config/nvim/init.vim

With an editor in place, it was time to install my shell of choice, zsh. I then configured my .zshrc (remembering to add the config alias from above), added it to version control, changed my default shell, and logged out and back in so it would all take effect:

# sudo portmaster shells/zsh
# nvim ~/.zshrc
# config add ~/.zshrc
# chsh -s /usr/local/bin/zsh
# exit

I was pretty much finished with this part, but I still needed to get my dotfiles pushed to a remote to make sure I didn’t lose them. First I generated an SSH key and added it to my GitHub account:

# ssh-keygen -t rsa -b 4096
# cat ~/.ssh/

Of course, typing the passphrase for the key every time I use it is a pain, so I installed keychain, a front-end to ssh-agent, and added it to my .zhsrc:

# sudo portmaster security/keychain
# echo 'eval `keychain --eval --agents ssh id_rsa`' >> ~/.zshrc
# config add ~/.zshrc
# eval `keychain --eval --agents ssh id_rsa`

Finally, I could add the remote, commit my dotfiles, and push:

# config remote add origin <URL>
# config commit
# config push -u origin master

With all of that out of the way, it seemed like a good opportunity to make a new boot environment and boot into it (they’re pretty cheap on storage, so you can use lots of them).