Important notes:
1) This tutorial assumes you have the OS you want to dual-boot with already installed on your drive, and that you already have freed up some disk space. Essentially, you will be installing FreeBSD with root-on-ZFS on the remaining free space of the disk, instead of using the entire drive as it's done by default by FreeBSD's installer.
2) This method only works for GPT disk layouts using UEFI mode. Legacy BIOS and MBR disks are not supported. As always, make sure to disable Secure Boot and Fast Boot.
3) Here, we use ada0 (disk 1) for everything, and we assume your disk already has an EFI partition, located in partition 1 (ada0p1). Change it according to your setup, if needed. Run
4) We will create our ZFS Pool with "Stripe" as the Virtual Device type (vdev).
5) After completing installation, to be able to choose what OS to boot you'll need to either install rEFInd boot manager, or use GRUB (assuming the other OS is a Linux distro). I personally recommend rEFInd, but I won't detail how to install it here. Neither will I explain how to alter the GRUB config. Just gonna show you how the respective entries should look like in each case.
6) Finally, I'm not responsible for any problem or data loss you may experience. This tutorial is not an unsafe procedure if you understand what you're doing (especially in regards to selecting the correct disk to install). Anyway, do it at your own risk!
Well, let's start already:
First of all, boot your FreeBSD install USB stick. Proceed installing as usual, until you reach the "Partitioning" stage. Here, choose the "Shell" option, so you can create your swap and ZFS partitions by hand:
# Load the ZFS kernel module:
# Force 4K sectors:
# Create your swap partition (in this case, of 4 GB size):
# Create your ZFS partition to fill the remaining free space:
# Mount a tmpfs to /mnt, where the installer will install the operating system into:
# Create your zroot pool:
# Create your ZFS file system hierarchy:
# Mount your pool:
# Define the default ZFS datasets for root zpool:
zfs create -o mountpoint=/tmp -o exec=on -o setuid=off zroot/tmp # We'll be using tmpfs for /tmp.
# Create a symlink to /usr/home:
# Change /tmp and /var/tmp permissions:
chmod 1777 /mnt/tmp # Not needed now.
# Configure the Boot Environment:
# Instruct FreeBSD to mount ZFS pools during system initialization:
# Add an entry to fstab to use your swap partition (with GELI encryption):
# Add an entry to fstab to use a tmpfs /tmp:
# Mount the existing EFI partition of your disk:
# Copy FreeBSD EFI boot loader to the EFI partition:
*Note: Here we name it "freebsd.efi" instead of the default "bootx64.efi" to avoid any conflict with other systems.
# Unmount EFI:
# Exit Shell Partitioning mode, so bsdinstall can continue and complete the installation:
After finishing the installation, you'll need to add a boot entry for FreeBSD in GRUB or rEFInd:
# For GRUB:
# For rEFInd, add something like this at the end of refind.conf:
That's all. I hope you find it useful. Feel free to create and share an script to automate this hell of a long process!!
EDIT 1: Added some sources:
https://www.freebsd.org/doc/handbook/bsdinstall-partitioning.html
https://wiki.freebsd.org/RootOnZFS/GPTZFSBoot
http://kev009.com/wp/2016/07/freebsd-uefi-root-on-zfs-and-windows-dual-boot/
https://svnweb.freebsd.org/base/release/12.1.0/usr.sbin/bsdinstall/scripts/zfsboot?view=co
EDIT 2:
-Reworded the title for better clarity.
-Added a note about FreeBSD's efi loader name used in this tutorial.
-Removed /tmp from ZFS datasets, to use a tmpfs /tmp instead. This way it provides better performance and doesn't cause troubles with some programs, like Firefox on Wayland, for instance.
1) This tutorial assumes you have the OS you want to dual-boot with already installed on your drive, and that you already have freed up some disk space. Essentially, you will be installing FreeBSD with root-on-ZFS on the remaining free space of the disk, instead of using the entire drive as it's done by default by FreeBSD's installer.
2) This method only works for GPT disk layouts using UEFI mode. Legacy BIOS and MBR disks are not supported. As always, make sure to disable Secure Boot and Fast Boot.
3) Here, we use ada0 (disk 1) for everything, and we assume your disk already has an EFI partition, located in partition 1 (ada0p1). Change it according to your setup, if needed. Run
gpart show
to be sure.4) We will create our ZFS Pool with "Stripe" as the Virtual Device type (vdev).
5) After completing installation, to be able to choose what OS to boot you'll need to either install rEFInd boot manager, or use GRUB (assuming the other OS is a Linux distro). I personally recommend rEFInd, but I won't detail how to install it here. Neither will I explain how to alter the GRUB config. Just gonna show you how the respective entries should look like in each case.
6) Finally, I'm not responsible for any problem or data loss you may experience. This tutorial is not an unsafe procedure if you understand what you're doing (especially in regards to selecting the correct disk to install). Anyway, do it at your own risk!
Well, let's start already:
First of all, boot your FreeBSD install USB stick. Proceed installing as usual, until you reach the "Partitioning" stage. Here, choose the "Shell" option, so you can create your swap and ZFS partitions by hand:
# Load the ZFS kernel module:
kldload zfs
# Force 4K sectors:
sysctl vfs.zfs.min_auto_ashift=12
# Create your swap partition (in this case, of 4 GB size):
gpart add -a 4k -l swap0 -s 4G -t freebsd-swap ada0
# Create your ZFS partition to fill the remaining free space:
gpart add -a 4k -l zfs0 -t freebsd-zfs ada0
# Mount a tmpfs to /mnt, where the installer will install the operating system into:
mount -t tmpfs tmpfs /mnt
# Create your zroot pool:
zpool create -f -o altroot=/mnt -O compress=lz4 -O atime=off -m none zroot /dev/gpt/zfs0
# Create your ZFS file system hierarchy:
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ zroot/ROOT/default
# Mount your pool:
mount -t zfs zroot/ROOT/default /mnt
# Define the default ZFS datasets for root zpool:
zfs create -o mountpoint=/usr -o canmount=off zroot/usr
zfs create zroot/usr/home
zfs create -o setuid=off zroot/usr/ports
zfs create zroot/usr/src
zfs create -o mountpoint=/var -o canmount=off zroot/var
zfs create -o exec=off -o setuid=off zroot/var/audit
zfs create -o exec=off -o setuid=off zroot/var/crash
zfs create -o exec=off -o setuid=off zroot/var/log
zfs create -o atime=on zroot/var/mail
zfs create -o setuid=off zroot/var/tmp
# Create a symlink to /usr/home:
ln -s /usr/home /mnt/home
# Change /tmp and /var/tmp permissions:
chmod 1777 /mnt/var/tmp
# Configure the Boot Environment:
zpool set bootfs=zroot/ROOT/default zroot
# Instruct FreeBSD to mount ZFS pools during system initialization:
echo 'zfs_enable="YES"' >> /mnt/etc/rc.conf
# Add an entry to fstab to use your swap partition (with GELI encryption):
printf "/dev/gpt/swap0.eli\tnone\tswap\tsw\t0\t0\n" >> /tmp/bsdinstall_etc/fstab
# Add an entry to fstab to use a tmpfs /tmp:
printf "tmpfs\t/tmp\ttmpfs\trw,mode=1777\t0\t0\n" >> /tmp/bsdinstall_etc/fstab
# Mount the existing EFI partition of your disk:
mount -t msdosfs /dev/ada0p1 /media
# Copy FreeBSD EFI boot loader to the EFI partition:
cp /boot/boot1.efi /media/efi/boot/freebsd.efi
*Note: Here we name it "freebsd.efi" instead of the default "bootx64.efi" to avoid any conflict with other systems.
# Unmount EFI:
umount /media
# Exit Shell Partitioning mode, so bsdinstall can continue and complete the installation:
exit
After finishing the installation, you'll need to add a boot entry for FreeBSD in GRUB or rEFInd:
# For GRUB:
Code:
menuentry "FreeBSD" { insmod part_gpt insmod fat set root=(hd0,gpt1) chainloader /efi/boot/freebsd.efi }
# For rEFInd, add something like this at the end of refind.conf:
Code:
# FreeBSD menuentry "FreeBSD" { loader /efi/boot/freebsd.efi icon /efi/refind/icons/os_freebsd.png }
That's all. I hope you find it useful. Feel free to create and share an script to automate this hell of a long process!!
EDIT 1: Added some sources:
https://www.freebsd.org/doc/handbook/bsdinstall-partitioning.html
https://wiki.freebsd.org/RootOnZFS/GPTZFSBoot
http://kev009.com/wp/2016/07/freebsd-uefi-root-on-zfs-and-windows-dual-boot/
https://svnweb.freebsd.org/base/release/12.1.0/usr.sbin/bsdinstall/scripts/zfsboot?view=co
EDIT 2:
-Reworded the title for better clarity.
-Added a note about FreeBSD's efi loader name used in this tutorial.
-Removed /tmp from ZFS datasets, to use a tmpfs /tmp instead. This way it provides better performance and doesn't cause troubles with some programs, like Firefox on Wayland, for instance.
Last edited: