I've gathered information primarily from:
- https://forums.freebsd.org/threads/uefi-gpt-dual-boot-how-to-install-freebsd-with-zfs-alongside-another-os-sharing-the-same-disk.75734/
- http://kev009.com/wp/2016/07/freebsd-uefi-root-on-zfs-and-windows-dual-boot/
- https://wiki.freebsd.org/RootOnZFS/GPTZFSBoot
These instructions are closest to the first link above, but differ in important ways:
- Unlike the first two links above (and other sources), everything except the partitioning and filesystem setup use the installer. This requires, among other things, mounting the target filesystem in a specific location.
- I set up GELI encryption with a password-only
- I try to give more details on the bootloader setup. I assume you're not afraid of the bootloader if you're trying to triple-boot FreeBSD with Windows and Linux, but even most people in that group aren't experts on the UEFI boot process or multi-stage bootloaders
Install Windows.
Notes:
- You might want to have a local-only account, instead of being forced to sign into a Microsoft account: https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account
- On a blank drive, Windows 11's installer will create 4 GPT partitions when you tell it to create one. This is annoying but expected (and partly necessary, as we'll discuss when we talk bootloaders).
- On the upside, the 100MB EFI system partition it creates is roomy enough that all the booloader stuff we want to do fits there.
Install FreeBSD.
FreeBSD's installer doesn't have any automated support for sharing disks with another OS. There's a "manual" partitioning tool, but it's at least somewhat broken; some errors send you back to the start of installation, and I've seen it segfault.
If you're using a desktop, multiple hard drives is the way to go. But if you're trying to do this on a laptop like me, you may only have a single storage device.
The solution is to use the installer for almost everything, but when it comes time for partioning and filesystem creation, we'll drop to a shell and set that up manually. But we'll do it in such a way that we can resume and finish everything but the bootloader with the regular installer.
- Boot from the installation media
- Go through the installation process normally, until you get to the screen that asks you to choose between automatic ZFS, automatic UFS, manual partitioning, or a terminal. Choose the terminal option.
- Load the ZFS kernel module:
kldload zfs
- Force 4KB sectors (for perf):
sysctl vfs.zfs.min_auto_ashift=12
- If you get a complaint about this sysctl not existing, you forgot to load the zfs module
- Figure out which device is your hard drive. For me this was
nda0
. You can usually tell from a quick look at thegpart show
output- From now on I'll use
<DEV>
to refer to this.
- From now on I'll use
- Create a swap partition. This command creates a 16GB swap, but generally specify your RAM size:
gpart add -a 4k -l swap -s 16G -t freebsd-swap nda0
- Create a single partition for your ZFS pool, adjusting size according to your needs:
gpart add -a 4k -l zfs -t freebsd-zfs nda0
- Make sure to leave space for the third OS, which you haven't installed yet!
- Check which partition numbers are your swap and ZFS partitions. This should be visible in the
gpart show
output (which shows the partition types; presumably you only have two FreeBSD-related partitions right now)- From now on, I'll use
<S>
to refer to the number of your swap partition. This was 5 for me. - From now on, I'll use
<Z>
to refer to the number of your ZFS partition. This was 6 for me.
- From now on, I'll use
- Set up GELI encryption
- This is optional, but of course, highly recommended. Another option to consider is adjusting the instructions below to create an encrypted ZFS pool for your main user, but right now this is a little awkward on FreeBSD (e.g., you must log in on the terminal at least once to decrypt your home directory before you can log in via an X session manager, for example). I've done this, and it's not terrible, but I personally find the GELI password-at-boot a little less awkward.
- It's also possible to do this in a way that requires a USB key with a secret on it. I tend to lose these a lot, so I'm just sticking with a password.
- Let's initialize the volume; run the following command, hit enter, type your password, hit enter again, and then type 'EOF':
geli init -b -s 4096 -J - /dev/<DEV>p<Z> << EOF
- After the command above, and entering a password, and then EOF, the system may pause for a moment, hang in there
- ... attach, explain .geli extension
- Create the zpool:
zpool create -f -o altroot=/mnt -O atime=off -m none zroot /dev/<DEV>p<Z>.geli
- If you want compression, also pass
-O compress=lz4
- If you want compression, also pass
- Now we create a filesystem hierarchy, with different ZFS datasets for different mount points. If you're relatively new to ZFS and haven't thought about this: this makes it easy to revert part of the system to an old snapshot without losing everything (e.g., rolling back a borked upgrade without losing changes to your home directory). It's similar to the reasons to put different things on different partitions in older Linux setups.
zfs create -o mountpoint=none zroot/ROOT
- ...