‹ jan0sch.de

FreeBSD upgrading the bootloader on UEFI boots


If you upgrade your FreeBSD installation you should also upgrade your bootloader (bootcode) too. However in many cases you don’t need to, so you might never have done it. ;-) However if you’re booting from a ZFS pool which you upgrade to a newer version than the bootloader can handle then you’re in for trouble.

An example is upgrading directly from FreeBSD 13.2 to 14.0 which resulted in problems for quite some people that forgot to update the bootloader. The regular examples are however always directed at legacy (BIOS) boot scenarios. There is nothing wrong booting via BIOS but you might be in an environment where the system is booted via UEFI.

But how do we find out?

Luckily for us there is a tool called efibootmgr that we can run:

# efibootmgr -v
Boot to FW : false
BootCurrent: 0004
Timeout    : 1 seconds
BootOrder  : 0004, 0005, 0001, 0002
+Boot0004* UEFI OS HD(...)/File(\EFI\BOOT\BOOTX64.EFI)
                      ada0p1:/EFI/BOOT/BOOTX64.EFI (null)
 Boot0005* UEFI OS HD(...)/File(\EFI\BOOT\BOOTX64.EFI)
                      ada1p1:/EFI/BOOT/BOOTX64.EFI (null)
 Boot0001* Hard Drive ...
 Boot0002* CD/DVD Drive ...

The example above shows us that we’re booting on a two disk system (likely a mirror) using UEFI.

Ok, but what do we need to do? Well, for UEFI it is as simple as copying the loader.efi file from the updated FreeBSD distribution to the appropriate places.

On a single disk system you only need to worry about the partition of the type efi (use gpart show to find it) which can be mounted via mount_msdosfs. For systems using RAID or mirror functionality we need to touch the EFI partition on every disk, but first things first.

Attention! Sometimes the EFI partition that was booted from is already mounted under /boot/efi! Please check if this is the case. Especially if you get mount errors when trying to mount it (the partition) to another place.

The basic procedure is as follows:

  1. find out which EFI partitions exist via: gpart show
  2. mount it: mount -t msdosfs /dev/BLABLA /mnt
  3. copy bootloader: cp -a /boot/loader.efi /mnt/efi/boot/bootx64.efi
  4. only if freebsd/loader.efi exists on EFI partition: cp -a /boot/loader.efi /mnt/efi/freebsd/loader.efi
  5. unmount it: umount /mnt/tmp

Nice, but I have a multiple disk array and get funny boot errors from time to time!

I experienced these too on one system and the reason was that the EFI partition was correct on the first disk but not on the others! To fix it the other EFI partitions needed formatting and copying of the data.

Basic procedure for broken partitions (/dev/BROKEN1 till /dev/BROKEN3):

# newfs_msdos -F 32 -c 1 /dev/BROKEN1
# mount -t msdosfs /dev/BROKEN1 /mnt
# mkdir -p /mnt/efi/boot
# cp -a /boot/loader.efi /mnt/tmp/efi/boot/bootx64.efi
# mkdir -p /mnt/efi/freebsd
# cp -a /boot/loader.efi /mnt/tmp/efi/freebsd/loader.efi
# umount /mnt

And then repeat for BROKEN2 and BROKEN3. And that should be it. :-)

Upgrading the bootloader should be done with each major upgrade.