Dual Boot OpenBSD with Systemd-boot

Updated on

"Absolute OpenBSD" courtesy of varmaden.

Introduction

I run archlinux with systemd-boot as a bootloader (as opposed to for example grub). I wasn’t able to find anyone online having installed openbsd with systemd-boot, which is a bit expected since systemd fans typically don’t use *bsd. In this little guide, I’ll go through how I dual-booted openbsd alongside my linux install, all while using systemd-boot.

Background

For those unfamiliar, there used to be an operating system called “unix”, released by Bell Labs (later AT&T). Due to awesome anti-trust law, this operating system was forced to become open source, and is the foundation for almost every existing OS, except windows.

Berkley Software Distribution (BSD), was a project by UCBerkley to extend the capabilities of Unix 7. It used to be a commercial project, but by 1995 there were 3 main forks:

  • FreeBSD, the open source version of BSD, with the most users and largest support.
  • NetBSD, which had a great networking stack.
  • OpenBSD, a security focused BSD forked from NetBSD.

Linux was pretty young at the time, so it wasn’t clear that it’d end up absolutely dominating the OS market in a decade. The critical difference between *BSD and Linux is that *BSD is a continuation of the original Unix 7, while Linux started from scratch while being heavily Unix-inspired. Both are POSIX compliant, which makes them able to handle a lot of the same tools. *BSD tend to centralize things, for example they all have very extensive documentation in a single spot.

*BSD offers a nice look into history, while also giving a different perspective on the design of operating systems. I would not recommend using it as a daily driver to anyone; linux is far better.

For this guide, I mostly followed the openbsd faq, which is deceptively named, since it’s pretty much the openbsd equivalent of a handbook.

Prerequisites

You should already have a working linux install running systemd-boot. Mine mounts the efi partition on /boot, which I’ll be using, though I think some systems might use /boot/efi. If not, you can install it following the archwiki, it’s like one command.

My layout looks like this right now:

$ lsblk -o name,label,fstype,mountpoint,fsused,size,state
NAME        LABEL        FSTYPE MOUNTPOINT FSUSED  SIZE  STATE
nvme0n1                                    476.9G        live
├─nvme0n1p1              vfat   /boot      646.8M  1023M
├─nvme0n1p2 home         btrfs  /home      58.8G   185.3G
├─nvme0n1p3 arch-root    btrfs  /          36.9G   46.6G
├─nvme0n1p4 fedora-root  btrfs             46.6G
├─nvme0n1p5 suse-root    btrfs             46.6G
└─nvme0n1p6 debian-root  btrfs             46.6G

You’re going to need some empty space, ideally at least 30gb. In my case, I don’t need those last 2 distros anymore, so I’ll delete those.

Partitioning

A linux “partition” is what openbsd calls a “slice”. A linux “logical partition” is what openbsd calls a “partition”, which it makes using disklabel(8).

On linux, I typically make 2 partitions: one for /, and one for /home. This makes it really easy to quickly reinstall the system without losing all your important data. This makes logical volumes not all that important. Openbsd however wants a lot more partitions that just 2, since it uses different mounting permissions as a security measure. See here. Thankfully, all of these will be openbsd “partitions”, so from the linux point of view, we only need to make 1 linux partition for all of this.

I fear fdisk, so I use parted:

sudo parted /dev/nvme0n1 print free  # Print out the situation
sudo parted /dev/nvme0n1 rm 5  # Remove partitions I don't need (very optional)
sudo parted /dev/nvme0n1 rm 6
sudo parted /dev/nvme0n1 mkpart primary 300GB 450GB  # Make the openbsd partition
sudo parted /dev/nvme0n1 name 5 openbsd  # Set a name for your convenience

NVRAM

Nvram is what tells your computer what to boot. We don’t need to mess with it yet, but it’s a good idea to see what it looks like right now.

$ efibootmgr --verbose  | rg Boot
BootCurrent: 0002
BootOrder: 0002,0003,0000,001B,0019,0017,0018,0001,001A,001C,001D,001E
Boot0000* Fedora    HD(1,GPT,8f3a1e7b-9c2d-4a5f-b8e1-a3d7f9c4e2b8,0x800,0x1ff800)/\EFI\fedora\shimx64.efi
Boot0001* Windows Boot Manager  HD(1,MBR,0x4d9a8b2c,0x18c000,0x7800)/\EFI\Microsoft\Boot\bootmgfw.efi7348234a4f5753000100088000088230780000004200430044004f0042004a004500430054003d007b00390064006500610038003600320063002d0035006300640064002d0034006500370800000002342033204034234404d034200d0003246200330034003400640034003700390035007d0000004bdf0100000010000000040000007fff0400
Boot0002* Linux Boot Manager    HD(1,GPT,2b7e9f1a-3c8d-4e9a-b5f2-c7d8e1a3b9f4,0x800,0x1ff800)/\EFI\systemd\systemd-bootx64.efi
Boot0003* debian    HD(1,GPT,8f3a1e7b-9c2d-4a5f-b8e1-a3d7f9c4e2b8,0x800,0x1ff800)/\EFI\debian\shimx64.efi
Boot0010 Setup  FvFile(d4a8e2b7-1c9f-4d8a-3e7b-9f2a8d4c1e6f)
Boot0011 Boot Menu  FvFile(f3b9e1a8-2d7c-5e9b-4f8a-1d3c7e9b2a4f)
Boot0012 Diagnostic Splash Screen   FvFile(e2c8d1b9-3e7a-6f8b-5d9c-2a1e7b8f3c9d)
Boot0013 Lenovo Diagnostics FvFile(a9d3e7b1-4f8c-5e9a-6d7b-8f2c1e9b3a7d)

Here, systemd-boot is Boot0002*, where the * indicates it’s bootable. Now I actually deleted fedora, windows, and debian boot managers. In fact, the windows one must have been from the previous owner of this laptop. Since they don’t exist, it’ll always end up falling back to systemd-boot through trial and error.

I decided to delete the first few, but leave the debian ones for reference:

sudo efibootmgr --bootnum 0000 --delete-bootnum
sudo efibootmgr --bootnum 0001 --delete-bootnum

Getting to the Install

I downloaded install78.iso for amd64 from here and copied it onto a usb stick with:

please dd bs=4M if=/dev/shm/install78.iso of=/dev/sda conv=fsync oflag=direct status=progress

F12 for the boot manager and we’ll hit openbsd. The boot loader on openbsd gives me a command line-like interface, but it’s actually the boot menu. Here I’ll type boot to boot into the installer (I think it should have automatically done that after 3s). I went with the (I)nstall option.

Installing OpenBSD

Getting Internet

I don’t want to deal with wifi firmware, I opted to use ethernet. To setup my internet connection, I used:

sudo ifconfig em0 inet 10.42.43.161/24
route add default 10.42.43.1
ping 9.9.9.9  # Check for internet
echo 'nameserver 9.9.9.9' | cat - /etc/resolv.conf > somefile
mv somefile /etc/resolv.conf
ping archlinux.org  # Check for dns resolving

The rest was pretty straightforward, up until the partitioning. Generally it was something like:

DNS domain = my.domain
DNS nameserver = 9.9.9.9
sshd = yes
xwindow = no
com0 = no
setup a user
root access to sshd = no

Partitioning the Slice

Now comes the scary partitioning. We can’t mess up here, since that’ll overwrite our linux install.

It’s asking me for a disk, with 3 options: sd0, sd1, sd3. Using the ? I see that sd0 is my nvme drive, so clearly we’re dealing with that one. sd1 is the usb stick I copied the install78.iso onto, and sd3 is some sdcard.

It now asks how the installation should proceed on this disk, with mbr, gpt, and custom. I chose (C)ustom, since I want it in a specific slice on that disk, which is slice 5. Selecting that, it gives us a suggested auto partitioning of that slice.

Now take a careful look at the auto partitioning. Partition c is actually just the disk, it’s not a real partition. It’s there to identify the metadata of the partition itself, very legacy stuff. There’s also partition i, which has an MSDOS file system (fat32). The odd thing about this one is that the offset for the partition is 0, meaning it’s targeting the start of the disk, well outside of the slice I chose! This seems to be a hack to indicate the efi partition to the openbsd installer. We must leave both of these partitions!

Choose (E)dit, then delete all the partitions except c and i. Unlike linux, we’re going to need a lot more partitions than just / and /home. Refer to here. I went with:

  • /: 10gb
  • /usr: 30gb
  • /tmp: 10gb
  • /var: 5gb
  • /home: 80gb

Installing File Sets

We now need to install our kernel and basic utilities. It will ask for the location of the file sets. If you used the install78.iso image, they’re actually included in the disk image you downloaded! I pointed it at sd1, which is the usb stick with the iso. The defaults should work from here on.

You can also use the http mirror option, but it didn’t end up working for me. When you see

HTTP Server? (hostname or 'done') [cdn.openbsd.org]

You should use one of the http mirrors listed here, but only the domain name! The url path is chosen in the next step.

Booting with Systemd-boot

After rebooting, I needed to hit f12 to get back into the boot menu. If you don’t, you’ll be rebooted right back into openbsd, since it’s inserted itself at the front of the nvram boot order. From the boot menu however, I can find my linux boot loader, which refers to systemd-boot.

Back on linux, I see with efibootmgr -v | rg Boot that openbsd has inserted its entry at number 0000 and at the front of the boot order. I switched the boot order to be systemd-boot (0002) first:

sudo efibootmgr --bootorder 0002,0000,0010,0011

Now we want systemd-boot to also be able to boot up openbsd. This is pretty simple, and can be achieved by adding the following file into /boot/loader/entries/openbsd.conf:

title   OpenBSD 7.8
sort-key openbsd
efi     /EFI/openbsd/bootx64.efi

You should be able to see the efi file we’re targeting up there in /boot/EFI/openbsd/bootx64.efi, otherwise the booting will fail.

Reboot, and you’ll now see a “OpenBSD 7.8” entry on systemd-boot, which is also the boot loader chosen by default on startup.

This entry for openbsd looks really different from the conf files used for linux. This is since systemd-boot can’t actually boot anything but linux, but what it can do is switch to a different boot loader. The efi key in openbsd.conf does exactly that, delegating the boot to openbsd’s boot loader.

Conclusion

I was pleasantly surprised by how easily systemd-boot handles such a foreign and poorly-supported os. Its dead simple configuration highlights how well it focuses on the essentials, which I particularly appreciate for something as critical as a boot loader.

Openbsd itself wasn’t too difficult to install either, with the biggest hurdle being how different the partitioning mindset is from linux. My next blog will be cover the user experience of openbsd itself.