My FreeBSD Install Notes

I just reinstalled FreeBSD on my computer, and this time I decided to take notes

I just got done reinstalling FreeBSD on my desktop computer. The reason is not important. I like FreeBSD, but the process to get it where I want it is a little bit tedious. FreeBSD provides a base operating system that you're expected to mold to your needs, which can be daunting, and is definitely time consuming. You're rewarded with an operating system that is, essentially, your own.

While the FreeBSD handbook is great (no, really!), and should absolutely be required reading for anyone interested in learning more about some common things you might want to do with a FreeBSD installation, it deals with a lot of tasks in general terms. That's partly because FreeBSD is flexible enough that if the guide were to be comprehensive, it would be... well, it'd be huge.

There are some HOWTOs out there that show you how to do common things. HOWTOs are great1 but they have at least two problems: 1. If you follow the HOWTO to the letter, you end up with a setup identical to the author's, which is a fine place to start, but you might not learn much, and 2. If you deviate from the HOWTO before you know what you're doing because you want to customize the end result, you might end up with a broken project that you have no idea how to fix.

When I first decided to install FreeBSD some time ago, I found A FreeBSD Desktop HOWTO on cooltrainer.org that looked like a roadmap that would get me to my destination, so I followed it and installed the author's FreeBSD installation. It was a good place to start exploring the World of FreeBSD™.

But time rolls on, and the guide stopped getting updates. I still use it as a general outline and a set of reminders, but I've deviated from it enough that I feel like I should just take my own notes, make some adjustments, and put them someplace I can reference the next time I decide to install FreeBSD.

This is not technically a HOWTO. It's a record of installing and configuring FreeBSD that Works for Me™. I'll try to keep it as up-to-date as I can since I'm using it for my own reference, but I make no promises. Feel free to follow along.

Installed Hardware

My current rig is as follows:

  • Motherboard: Asus TUF GAMING X570-PLUS (Wi-Fi)
  • CPU: AMD Ryzen 9 3900x
  • RAM: 2x Corsair Vengeance RGB Pro 32GB (2x16GB) DDR4 3200 (PC4-25600) C162
  • Video: MSI NVIDIA GTX 1660 SUPER3
  • Storage: 2x250GB NVME drives, 1x500GB SSD, 1x4TB HDD

Download and prepare media

Go to the main FreeBSD site and download the appropriate .iso. In my case, it's the amd64 iso. Prepare media with whatever method you want (if you're running Linux, probably you'll want to use dd to copy it to a USB drive, if you're under Windows, you'll probably want to use something like Etcher). Boot from your drive and get ready to run through the installation process.

Pre-installation

Boot from your prepared media. Select normal boot → installation → select your keymap (US). Choose a computer name4

Choosing what to install

I install everything. I'm not a programmer, so I'll probably never use base-dbg, kernel-dbg, lib32-dbg, or tests, but disk space is cheap and these components aren't that big. I'll need the kernel source for building the Nvidia driver later, and I'll be using the ports tree.

Configure the network

I have a DHCP server installed, so I'll use that. Select the Interface → configure IPv4 → configure DHCP. I don't have any IPv6 on my network yet, so I won't bother with that. Verify that the network configuration looks sane (i.e. the IP and DNS look about how you expect)

Choose a mirror

I'm in the US, so ftp1.us.freebsd.org is probably a good choice

Disks

Partitions

I'm going to do this the hard way and choose Manual partitioning. Delete all partitions (unless you're reinstalling FreeBSD or you're doing something else) divvy them up however you want. For this install, I'm making the first NVME drive my root drive with a 32GB swap partition at the end. With the amount of RAM in this machine and its anticipated workload, I don't expect the swap partition to be touched, and having a swap file be smaller than my physical RAM means that I give up the ability to hibernate my computer. I'm using the second NVME drive as my /home folder, a 500GB SSD as a scratch drive for when I decide to make videos (mounted at /scratch), and a 4.0TB drive for storing the gigantic ball of mud full of files of files I've accreted over the years (mounted at /outerspace5,6).

I use MBR for all of the drives except for the 4TB drive where I have to use GPT (the next time I'm probably going to use GPT everywhere). I have used BSD labels in the past, but I don't any more. Labels make cleaner device names (/dev/ada0 vs. /dev/ada0/ada0s1), but they make it difficult to reuse the drives in a Linux box. The drive tools in the Linux distributions I tried silently failed when they tried to format the drives, but the installation continued as normal. Except it wasn't normal and the distribution could no longer boot. I replaced two hard drives before figuring it out (a tool like gparted can handle these 'dangerously dedicated' drives).

I haven't jumped on the ZFS bandwagon yet. I know it's wonderful, but I couldn't figure out how to make it work with my drive configuration. I also take frequent backups, so I'm okay with UFS for now.

Cleaning up

Download the installation packages, set a root password, set a timezone, set date and time.

Choosing which services to enable

I usually select sshd (for remote access), moused (for a console mouse), ntpd (for keeping the clock updated) to start at boot time, and powerd (for CPU frequency scaling). I leave dumpdev enabled in case I need it, and leave everything else off (which is just ntpdate and local_unbound).

System hardening

This machine is going to be exclusively used at home on a network maintained by me, so I'm not going to worry too much about hardening the system. I will enable random PIDs and I'll disable sendmail (so it doesn't send me reports I'll never read).

Adding users

Don't run as root

You shouldn't run your system as root. Bad Things™ can and will happen if you are the superuser all the time. This comes from experience. You should add a user account to do your everyday things, and you should only become root as needed.

The process for adding a new user in the FreeBSD installer is straightforward, but it has a lot of steps. Follow the prompts, accepting the defaults (unless you know what you're doing). The only exception is that I want to add my everyday user to the groups wheel operator video. wheel, so I can su to root when I need it, operator so I can shutdown and do other things without having to become root, and video to get access to accelerated video (technically this is redundant since the user is already in the wheel group).

Lastly, install the handbook, exit, and reboot.

First Boot

We're now in our FreeBSD system proper (and if we're not, we need to back up and try again). Time to do some initial configuration.

Enabling UTF-8

FreeBSD supports UTF-8 (good!), but it's not configured out of the box (annoying!). That's easy enough to fix. Log in as root (or su to root) and edit the /etc/login.conf file. Use ee, included in the base system (you can use vi if you already know how to use it). We'll add other editors later. Look for the line that reads :umask=022:, add a slash at the end and add a line for the locale you want. It should look like this:

:umask=022:\
:charset=UTF-8:\
:lang=en_US.UTF-8:

After making changes to this file, su to root and run cap_mkdb /etc/login.conf to make the changes take effect. As long as there are no errors, log out, and log back in. Run locale to make sure that the changes took effect. If you want to use another locale for some reason, run locale -a to list all the locales available to you.

The cooltrainer guide also recommends that you add the following lines to /etc/profile for "non login shell" uses. Let's do that, too.

LANG=en_US.UTF-8; export LANG
CHARSET=UTF-8; export CHARSET

Log out and log back in and run the locale command to make sure that your new locale settings are correct and you don't have any errors.

Checking for updates

This is a good time to check for updates. Run freebsd-update fetch as root to check for updates and freebsd-update install, also as root, to install any that it finds. If your installation media is old, there are probably a lot.

Tuning and drivers

The cooltrainer guide suggests some interesting tweaks for 'tuning'. However, when I checked a fresh install, the default values were sometimes already higher then what the guide suggests setting them to. For instance, the guide suggests setting kern.ipc.shmmax=67108864 and kern.ipc.shmall=32768, but on my system, they were set to kern.ipc.shmmax=536870912 and kern.ipc.shmall=131072, kern.maxfiles was already set to 2092988 instead of the suggested 200000, and kern.ipc.shm_allow_removed=1, which is apparently needed for Chromium, was already set by default. I need to research these values and what they do further, but the only changes I made to my /etc/sysctl.conf was to add the line to 'enhance desktop responsiveness under high CPU use'. The default value of 80 worked okay until I started compiling ports (see below), which made the GUI slow and unresponsive. And the other change was to 'allow users to mount disks' (it's covered later in the guide, but I decided to do it all at once)7,8

/etc/sysctl.conf
kern.sched.preempt_thresh=224
vfs.usermount=1

The same thing went for /boot/loader.conf. Several of the suggested modules either didn't seem to exist or they were already built in to the kernel. I tested by trying to kldload all of the modules listed in the cooltrainer.org /boot/loader section and the ones that didn't load didn't get added. I also worked ahead and loaded the cuse module for webcams, the snd_driver module for audio support, linux for the Linuxulator, and ext2fs so I can access the backup drive I made under Linux. My /boot/loader.conf looks something like this:

/boot/loader.conf

# tweaks for desktop use
kern.ipc.shmseg=1024
kern.ipc.shmmni=1024
kern.maxproc=100000
# filesystems in userspace
fusefs_load="YES"
# amd thermal sensors
amdtemp_load="YES"
# tmp filesystem
tmpfs_load="YES"
# unicode support on removable media
libiconv_load="YES"
libmchain_load="YES"
cd9660_iconv_load="YES"
msdosfs_iconv_load="YES"
# sound driver
snd_driver_load="YES"
# webcam
cuse_load="YES"
# linux support
linux_load="YES"
# linux filesystem support
ext2fs_load="YES"

There are still a few tweaks I can make once I know a little bit more about what I'm doing (like figuring out what the 'shmseg' and 'shmmni' settings do and why I would want them set there), and some of this stuff could be excised. Do I really need Unicode support for CDs? Probably not, but it doesn't hurt to leave that stuff enabled for now.

More system configuring

Next, I'm going to edit /etc/rc.conf to verify that SSH is enabled, and then to enable some stuff that I know I'm going to need later. It's also a good idea to add the -g flag to ntpd so that it can make large time jumps. At least I assume it is. My feeling is that this is probably only useful one time: if you're coming from a Windows install (or you dual boot, but if you do that, you shouldn't have your CMOS clock set to UTC). I doubt that it hurts anything to leave it enabled all the time. I'm also going to enable dbus and hald for installing xorg later, linux for the Linux emulator, and webcamd for using a webcam. A couple of these programs aren't installed yet, but I'll take care of that later. I'm also going to make changes to some devfs stuff soon, so we can make those changes, too.

It's tedious and error-prone to make the large insertions below to various files. If possible, it's convenient to ssh in from a GUI-based system and copy/paste the edits in. You can kind of copy and paste with moused, but it's a little more tedious than I would like. Another option is to jump the gun and install X and a web browser to make copying/pasting a little easier, but that involves doing things in a weird order, and you might miss a step somewhere else.

/etc/rc.conf
sendmail_enable="NONE"
hostname="shiva"
ifconfig_re0="DHCP"
sshd_enable="YES"
moused_enable="YES"
ntpdate_enable="YES"
ntpd_flags="-g"
powerd_enable="YES"
devfs_system_ruleset="devfsrules_common"
dumpdev="AUTO"
linux_enable="YES"
hald_enable="YES"
dbus_enable="YES"
webcamd_enable="YES"
/etc/devfs.rules
[devfsrules_common=7]
add path 'ad[0-9]\*'    mode 666
add path 'ada[0-9]\*'   mode 666
add path 'da[0-9]\*'    mode 666
add path 'acd[0-9]\*'   mode 666
add path 'cd[0-9]\*'    mode 666
add path 'mmcsd[0-9]\*' mode 666
add path 'pass[0-9]\*'  mode 666
add path 'xpt[0-9]\*'   mode 666
add path 'ugen[0-9]\*'  mode 666
add path 'usbctl'       mode 666
add path 'usb/\*'       mode 666
add path 'lpt[0-9]\*'   mode 666
add path 'ulpt[0-9]\*'  mode 666
add path 'unlpt[0-9]\*' mode 666
add path 'fd[0-9]\*'    mode 666
add path 'uscan[0-9]\*' mode 666
add path 'video[0-9]\*' mode 666
add path 'tuner[0-9]*'  mode 666
add path 'dvb/\*'       mode 666
add path 'cx88*'        mode 0660
add path 'cx23885*'     mode 0660 # CX23885-family stream configuration device
add path 'iicdev*'      mode 0660
add path 'uvisor[0-9]*' mode 0660

I need to bone up on the devfs settings here, but it looks like it goes through and sets up a bunch of permissions for a bunch of devices that someone might want to plug into their system. This is copied verbatim from the cooltrainer guide (it looks like it's very similar to other desktop guides around, so it may be cargo-culted from time immemorial), until I have time to tweak this further, I'll keep it as-is.

The same goes for adding the following lines to the /etc/devfs.conf file, which changes permissions of things at boot time. This is also copied verbatim from the cooltrainer guide until I can adjust it as needed (do I really need to bother with optical media permissions on a system that will likely never have an optical media drive attached to it?).

/etc/devfs.conf
# Allow all users to access optical media
perm    /dev/acd0       0666
perm    /dev/acd1       0666
perm    /dev/cd0        0666
perm    /dev/cd1        0666
     
# Allow all USB Devices to be mounted
perm    /dev/da0        0666
perm    /dev/da1        0666
perm    /dev/da2        0666
perm    /dev/da3        0666
perm    /dev/da4        0666
perm    /dev/da5        0666
     
# Misc other devices
perm    /dev/pass0      0666
perm    /dev/xpt0       0666
perm    /dev/uscanner0  0666
perm    /dev/video0     0666
perm    /dev/tuner0     0666
perm    /dev/dvb/adapter0/demux0    0666
perm    /dev/dvb/adapter0/dvr       0666
perm    /dev/dvb/adapter0/frontend0 0666

/etc/fstab

Now is probably a good time to check the /etc/fstab file and add some entries for things that we'll need later. We'll need proc and fdesc for programs that expect them, and we'll want linprocfs, and tmpfs for the Linux emulator. The cooltrainer guide has a typo here, but the entries from the package installation message seem to be correct.

/etc/fstab
proc            /proc           procfs  rw      0       0
fdesc           /dev/fd         fdescfs rw,auto,late    0       0
linprocfs       /compat/linux/proc      linprocfs       rw      0       0
linsysfs        /compat/linux/sys       linsysfs        rw      0       0
tmpfs           /compat/linux/dev/shm   tmpfs   rw,mode=1777    0       0

I recommend testing these new mount points before rebooting your computer. Just in case there's a typo somewhere and the computer refuses to boot (it's fixable, but it's tedious and annoying). mount proc, mount fdesc, etc. A note that you won't be able to mount the Linux stuff until the Linux kernel module is loaded, so a kldload linux64 is needed first.

Whew! Now it's finally time to start installing software!

Installing software

One of the first things you have to decide is if you want to install packages or ports. Both have advantages and disadvantages. I like screwing around with ports because, even though I'm not a programmer, it's fun to watch the build process happen, and it's fun to watch compiler output whiz by as stuff compiles. Compiling can take just shy of forever, even on fast systems, and can break in exciting ways. Packages might be a better choice if you're not a tinkerer.

To get the latest ports tree, run portsnap fetch extract to fetch the latest ports snapshot and extract it in the usual place. Later on, you can use update instead of extract to just update the ports tree without having to extract the whole thing again. It's faster and it saves some write cycles on your SSD.

To use ports, find the port you want, go into its directory, run make config-recursive to set whatever compile options you want for the port and all of its 'leaf ports' (other ports that your chosen port needs to build and/or work). You might want to run make config-recursive repeatedly because some of the leaf ports might have brought in other leaf ports that you will have to configure. Keep running make menuconfig until you don't get prompted to configure anything else. Then type make install clean and the program will be downloaded and compiled right before your eyes!

Compiling ports this way is tedious and time consuming, especially when they get updated. I like to use a tool like portmaster to handle some of this stuff for me (from ports/ports-mgmt/portmaster). Also handy is tmux so I can have something compiling in one window while I fart around in another one. Old hands might suggest that you use virtual TTYs for that, and that works, too, but I know I'll need tmux later, so might as well install it now.

The thing about portmaster is that it sometimes stops in the middle of a big build (say, KDE) to ask you if you want to delete the download files that were just used to install your software. You probably do eventually, but I like to keep the install going and I'll clean up later. It's super annoying to kick off an install job that expect to take a couple of hours, walk away from your computer, and come back to discover that the install stopped ten minutes in because portmaster is asking you if you want to delete something. I use portmaster -D portname which skips asking me to clean files. That does mean that I have to remember to run portmaster --clean-distfiles -y once in a while to clean up stale downloaded files (the -y option just answers 'yes' to all the prompts asking me if I really want to delete stuff).

I also use portmaster -Da to check for an update to my installed software after getting the latest ports tree. That checks all the software on my machine for upgrades and also defers deleting the downloaded source files until later when I remember to do it (i.e. when my hard drive is full).

You should also get in the habit of checking the file /usr/ports/UPDATING before every portmaster -Da. It lists problems you're likely to come across and how to fix them.

Removing software

Removing software is easy. You can go into the port folder and type make deinstall if you want, but that can get tedious. It's more efficient to use pkg tools to do that. So, pkg delete packagename to delete a package, and pkg autoremove which removes unused and outdated packages from your system.

Installing a GUI

As much as I like doing things from the CLI, I've grown font of GUIs, so it's time to start installing one.

First use portmaster to install x11/xorg, and then run startx. Assuming you see graphics, you can look at installing some other ancillary software that you might want, like a login manager and a different window manager, but before doing all that, you may need to install three packages for your video card: x11/nvidia-driver, nvidia-settings, and nvidia-xconfig. Users of AMD cards will need to look into drm-kmod.

Once those are installed, run nvidia-xconfig to have it generate a usable X configuration (this wasn't necessary when I had a Radeon card in this system, and it's annoying that I have to do it for Nvidia. It's double-annoying that I have to re-run it when I change my monitor situation).

Login manager and window manager

For a login manager, I'm using x11/slim. I don't like Slim much, but I like most of the other login managers that I've tried less.

I tried Windowmaker as suggested by the cooltrainer guide, and liked it a lot, even though it's slow, outdated, and has quirky issues. But I'm also trying to learn a little more about editors/emacs for some reason. I decided to try EXWM.

To use EXWM, we need to install the EXWM package in Emacs (see the EXWM home page). Then we need to tell X to start Emacs when logging in. The easiest way to do that is to create a exwm.desktop in the /usr/local/share/xsessions folder (note that the xsessions folder might not exist and might need to be created). My exwm.desktop file looks like this:

exwm.desktop
[Desktop Entry]
Encoding=UTF-8
Name=EXWM
Exec=/usr/local/bin/emacs
Comment=This session logs you into emacs
Type=Application

You can also use this as a template for setting up slim to be able to start up window managers like window maker that don't install their own .desktop files

You'll also want to edit your user's .xinitrc file in your home folder to add the line:

~.xinitrc
exec $1

That way it will actually start the window manager you selected instead of doing nothing. Protip: if Slim complains that it can't execute the login command, that probably means you either fouled up your .desktop file or, more likely, it means that you forgot to select a session with the F1 key before logging in. Slim doesn't remember the last session you used and if you don't pick one, it whines about it.

Testing the GUI setup

Now that everything is (hopefully) configured, we can manually load the nvidia driver

kldload nvidia-modeset

Manually start slim

service slim onestart

Log in as your user, and your chosen window manager or desktop environment should appear!

Assuming that everything worked, we can enable slim by appending the following line to /etc/rc.conf

slim_enable="YES"

And the following line to /boot/loader.conf

nvidia-modeset_load="YES"

(Yes, I'm aware that there other other ways to load the Nvidia module, but this is the method I'm using)

Internationalization

I have two goals here: I sometimes pretend to study Japanese, so I want to be able to input some Japanese language stuff once in a while. And if I visit a site in a language I don't know using characters I can't read, I'd rather see the characters instead of ☐☐☐

The second one can be solved by installing a bunch of fonts. The cooltrainer tutorial has a decent list, though some are obsolete and some are unfetchable or otherwise broken. I can probably pare this down further, since I don't usually bother with having a lot of fonts installed on my system, and I don't mess with fonts all that much, but I installed a (large) subset of the suggested fonts.

portmaster -D chinese/arphicttf chinese/font-std hebrew/culmus hebrew/elmar-fonts japanese/font-ipa japanese/font-ipa-uigothic japanese/font-ipaex japanese/font-kochi japanese/font-migmix japanese/font-migu japanese/font-mona-ipa japanese/font-motoya-al japanese/font-mplus-ipa japanese/font-sazanami japanese/font-shinonome japanese/font-takao japanese/font-ume japanese/font-vlgothic x11-fonts/hanazono-fonts-ttf japanese/font-mikachan x11-fonts/droid-fonts-ttf x11-fonts/doulos x11-fonts/ubuntu-font x11-fonts/isabella x11-fonts/khmeros x11-fonts/padauk x11-fonts/stix-fonts x11-fonts/charis x11-fonts/urwfonts-ttf russian/koi8r-ps x11-fonts/geminifonts x11-fonts/cyr-rfx x11-fonts/paratype x11-fonts/gentium-plus

Inputting other languages is a little harder. I went with the tag-team of ibus and anthy (I've also used fcitx, and it worked great, too), which required modifying my .bashrc (since I use Bash (even though I haven't installed it yet)) and my .xinitrc. Conveniently, they used the same modifications (which is probably wrong, but it's working for now, and I might need to revisit this and change it someday).

portmaster -D textproc/ibus japanese/anthy japanese/ibus-anthy
~.bashrc
export XIM=ibus
export GTK_IM_MODULE=ibus
export QT_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export XIM_PROGRAM="ibus-daemon"
export XIM_ARGS="--daemonize --xim"
~.xinitrc
export XIM=ibus
export XMODIFIERS="@im=ibus"
export GTK_IM_MODULE="ibus"
export QT_IM_MODULE="ibus"
export XIM_PROGRAM="ibus-daemon"
export XIM_ARGS="--daemonize --xim"
ibus-daemon --daemonize --xim

I won't bother going into how to configure ibus or anthy here. I'm sure you can figure it out.

The rest

Assuming everything went well, we're now, finally, to the point where we can start installing the bulk of the software we're going to use. I had originally thought I was going to put a list of the software that I installed, but if anyone is following along at home, I didn't want my list to look like a list of endorsements. The flip side, of course, is that if you're coming to FreeBSD (or Linux or whatever) cold, you might not know where to begin, and a list of the software I use could be a starting point. I'm aware of this, too, so maybe I'll change my mind someday. Until that day comes, though, the list of applications I like to use are in a separate file somewhere safe9

If you're following along with the cooltrainer guide, you might notice that I skipped a bunch of stuff. There are reasons for that. I didn't install Virtualbox, for example, because the last few times I tried to use it, I couldn't get sound to work and I gave up using it for anything.

These notes will probably always be a work in progress, but I'm going to avoid adding a 'this website is under construction dot gif' to the bottom of it, because, really, aren't most websites constantly under construction anyway?

Thanks

I also wanted to thank the author of the cooltrainer guide and the authors of the FreeBSD forum posts I scavenged to get me comfortable enough with it to install and use it without too much heartburn. And also for everyone who makes FreeBSD possible. I sometimes forget to thank people who do things like create useful things and then give them to the world for free, so I try to fix that wherever I can.

Footnotes

  1. Citation needed
  2. This is an enormous amount of overkill for what I'm going to use this machine for, but I had some gift cards and some store credit, so I shot the moon
  3. I originally tried running this with an AMD RX 590 because AMD seems to be better Free Software citizens, but the driver didn't work very well. I had an RX 580 that worked better, but still had issues with stuff like Blender and xscreensaver, so I reluctantly went back to NVIDIA.
  4. See RFC 1178
  5. I originally called this drive 'space' because it gave me space for the stuff I collected, but it also sounded like 'space' in the stellar sense. I eventually renamed it to 'outerspace' as a nod to Fraggle Rock
  6. I go back and forth on whether to make /scratch and /outerspace subfolders of my home folder. Putting it in my home folder makes it cleaner, but putting it at the root makes the file paths shorter (some of the folders get really deep. I should probably clear that out Someday™)
  7. I think I get why the guide is laid out the way it is, it's supposed to be a generic all-purpose guide to installing FreeBSD, and it's broken down into logical sections. However, I found it annoying to edit the same file in different places throughout, so I decided to edit each file as few times as possible. I wasn't always successful.
  8. I go back and forth on allowing users to mount disks. On one hand, I think that it's better for security if root is the only user that has the power to mount and unmount disks, but on the other hand, I expect that I'm going to be the only one using my desktop computer, and being able to mount and unmount stuff like USB drives is convenient.
  9. Okay, it's written on a scrap of paper on my desk. I racked my brain and wrote down the software I used or pretended to use regularly and then wrote it all down as a checklist so I wouldn't forget anything (I forgot several things).


Read more FreeBSD articles · Go back to the homepage