Somehow I've managed to mostly not care about UEFI until now. On my new laptop, I decided I should give it a go. There are some small benefits, nothing life changing, but booting multiple OSes is a lot easier especially if they are UEFI native, and you get a nice frame buffer the boot manager can use as will the OS before starting graphically (and after, if you don't have accelerated graphics drivers).

For reference, how I run FreeBSD desktop/laptop: digital-life

Thanks to

Most of this was cribbed from the following sources:

Install Windows 10 or other UEFI OS

It's easiet if you install any other co-habiting OS first. Most OS installers assume they own the entire computer, and don't let you know much about what they are really doing, especially when manipulating booting.

Windows creates a large 100MB EFI partition, plenty of room for refind and other boot loaders.

Leave free space during the installer or shrink the partition using Windows Disk Manager.

Boot into a FreeBSD 11+ live environment

We just need a live FreeBSD enviroment to conduct our manual install. Make sure it is 11.0 or newer for UEFI boot1 zfs support.

The USB images with FreeBSD 11.0 and later -CURRENT snapshots have UEFI support integrated so they are directly bootable on UEFI machines. You could also use a CD/DVD or netboot.

Enable sshd, if needed

If you want to copy/paste from this blog to the machine being installed, bring up SSH.

mkdir /tmp/etc /tmp/root
mount_unionfs /tmp/etc /etc
mount_unionfs /tmp/root /root
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
service sshd onestart

Bring up a network interface

We'll need to grab refind during the installation.

Get a dhcp lease on your NIC or see the handbook for wireless setup

dhclient em0

Partition the drive

Add a couple GPT partitions. I'm doing a non-ZFS swap so I can coredump the kernel when doing FreeBSD development.

gpart add -a 4K -l swap0 -s 16G -t freebsd-swap nvd0
gpart add -a 4K -l zfs0 -t freebsd-zfs nvd0

Create a 4k aligned zpool

Standard practice these days, 4k align everything even if it's not a 4k-native disk.

Create a mountpoint and the inital zpool.

kldload zfs
sysctl vfs.zfs.min_auto_ashift=12
mkdir /tmp/zroot
zpool create -f -o altroot=/tmp/zroot -O compress=lz4 -O atime=off -m none zroot /dev/gpt/zfs0
zpool export zroot

Boot environment compatible ZFS datasets

Nest the root dataset under ROOT so we can use boot environments in the future with beadm

zpool import -o altroot=/tmp/zroot zroot
zfs create -o mountpoint=none zroot/ROOT
zfs create -o mountpoint=/ zroot/ROOT/default
zfs create -o mountpoint=/tmp -o exec=on -o setuid=off zroot/tmp
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 -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
zpool set bootfs=zroot/ROOT/default zroot
chmod 1777 /tmp/zroot/tmp
chmod 1777 /tmp/zroot/var/tmp

Perform a manual install of the distribution

This is pretty easy.

cd /tmp/zroot
ln -s usr/home home
tar xvJpf /usr/freebsd-dist/base.txz
tar xvJpf /usr/freebsd-dist/lib32.txz
tar xvJpf /usr/freebsd-dist/kernel.txz

Set a few things up

Set some common configuration. You may also wish to set up networking, enable SSH, etc in the altroot rc.conf.

echo 'zfs_enable="YES"' >> /tmp/zroot/etc/rc.conf
echo 'dumpdev="AUTO"' >> /tmp/zroot/etc/rc.conf
echo 'powerd_enable="YES"' >> /tmp/zroot/etc/rc.conf
echo 'sendmail_enable="NONE"' >> /tmp/zroot/etc/rc.conf
echo 'zfs_load="YES"' >> /tmp/zroot/boot/loader.conf
echo 'kern.geom.label.disk_ident.enable="0"' >> /tmp/zroot/boot/loader.conf
echo 'kern.geom.label.gptid.enable="0"'  >> /tmp/zroot/boot/loader.conf
printf "/dev/gpt/swap0\tnone\tswap\tsw\t0\t0\n" >> /tmp/zroot/fstab
tzsetup -C /tmp/zroot
chroot /tmp/zroot/ passwd

Install refind

UEFI has lots of bells and whistles. We're going to use the refind boot manager. I'm relying on the "fallback" efi loader, bootx64.efi. You may need to toggle things around in your system's firmware for that to work, or teach the EFI NVRAM about refind. See the refind site for more details.

cd /tmp
mkdir /tmp/efi
mount_msdosfs /dev/gpt/EFI%20system%20partition /tmp/efi/
cd /tmp/efi/EFI/Boot
mv bootx64.efi bootx64-windows-10.efi
cp /boot/boot1.efi bootx64-freebsd.efi
cp -a /tmp/refind-bin-0.10.3/refind/icons .
cp -a /tmp/refind-bin-0.10.3/refind/refind_x64.efi bootx64.efi
cp /tmp/refind-bin-0.10.3/refind/refind.conf-sample refind.conf

As good hygiene, you might consider updating bootx64-freebsd.efi whenever a point release is done. You could also keep an eye out for refind updates. This is easily done since it's just a DOS filesystem.

Configure refind and add menu entries

Set the values of timeout, and scanfor to manual to speed things up a bit in refind.conf.

Then add a couple entries:

cat << EOF >> refind.conf

menuentry "FreeBSD/amd64 -CURRENT" {
    loader \EFI\Boot\bootx64-freebsd.efi
    icon \EFI\Boot\icons\os_freebsd.png

menuentry "Windows 10 Professional x64" {
    loader \EFI\Boot\bootx64-windows-10.efi
    icon \EFI\Boot\icons\os_win.png

Finish, reboot and enjoy!

That's it. Unmount the efi partition and reboot.

umount /tmp/efi

You should be greeted by refind, otherwise take a look through your firmware boot order and make sure the firmware nvram for Windows Bootmanager isn't first.


Keep an eye out for GELI full disk encryption on top of ZFS on root.

Don't forget to do the swap partition as well.


comments powered by Disqus