Update of the bootcodes for a GPT scheme (x64 architecture)

This how-to is about the update of the bootcodes on FreeBSD as it's little to no documented. It only covers the GPT scheme and is intended for people with little knowledge of FreeBSD.


Edit: I wrote a script that gives the right commands to type after inspecting your system and can eventually executes them. Take a look at: https://github.com/Emrion/uploaders

Run this script and ask questions in that thread: https://forums.freebsd.org/threads/...gure-how-to-update-the-freebsd-loaders.94237/



When to update?
At each upgrade of the system whenever it's a minor or a major one.

In general, the system is compatible with the bootcodes of version-1. So personally, I do it just after the upgrade is finished.

GPT or MBR?
The command gpart show will answer to this. You will see either GPT or MBR at the first line of output. If you are on a MBR scheme, you can leave this how-to (and think about a reinstallation with GPT).

What is/are my booting partitions?
Again, gpart show will give you the answers. You can have only efi booting or only legacy BIOS booting or both.

In this example, the root disk has both booting capabilities:
Code:
gpart show -p
=>       40  104857520    ada0  GPT  (50G)
         40     409600  ada0p1  efi  (200M)
     409640       1024  ada0p2  freebsd-boot  (512K)
     410664        984          - free -  (492K)
     411648    4194304  ada0p3  freebsd-swap  (2.0G)
    4605952  100249600  ada0p4  freebsd-zfs  (48G)
  104855552       2008          - free -  (1.0M)

Here, you see the disk-name (ada0) and the partition scheme (GPT). You have an efi partition for efi booting and a freebsd-boot partition for BIOS booting. Note the partition-name (under disk-name) you have to update and its partition-number. In the example, it's ada0p1 (partition-number is 1) & ada0p2 (partition-number is 2).

Note also the root partition type, whether it is a zfs (freebsd-zfs) or an ufs one (freebsd-ufs). It's a zfs root partition in this example.

Here we go:

Update of the efi bootcode on a GPT scheme with an installation that was made before 13.0-RELEASE (root user):

Code:
mount -t msdosfs /dev/partition-name /mnt
cp /boot/loader.efi /mnt/efi/boot/bootx64.efi
umount /mnt

So, following the example, it's: mount -t msdosfs /dev/ada0p1 /mnt

This annoyance happens if the system has been installed from a 12.0 or previous RELEASE disk. It's the way loader.efi was copied into this partition. You legacy a FAT12 msdosfs that doesn't take all the available space (200 MiB).

So, you must change the file system, reformat it in Windows terms. You need first to unmount the partition:
umount /mnt
Then:
Code:
newfs_msdos -F16 /dev/partition-name
mount -t msdosfs /dev/partition-name /mnt
mkdir -p /mnt/efi/boot
cp /boot/loader.efi /mnt/efi/boot/bootx64.efi
umount /mnt
Where partition-name is ada0p1 in the example.

DO NOT REBOOT BEFORE loader.efi IS ACTUALLY COPIED AT THE RIGHT PLACE

Important note: if you started with a 13.0-RELEASE installation, the partition where the efi loader resides is mounted on /boot/efi. In this case, you cannot mount the partition on /mnt. mount will answer "Device is busy".

So, the procedure becomes:
Code:
cp /boot/loader.efi /boot/efi/efi/boot/bootx64.efi

Very important note: if you started with FreeBSD 14, the installer has activated a EFI boot entry that refers to this loader: /efi/freebsd/loader.efi. It means the system won't boot anymore on the default /efi/boot/bootx64.efi. So, update the file bootx64.efi will have no effect. I think it's safer to update both bootcodes.
Code:
cp /boot/loader.efi /boot/efi/efi/freebsd/loader.efi


Update of the BIOS bootcode on a GPT scheme if the root partition is a freebsd-zfs type (root user):

gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i partition-number disk-name
Following the given example, it's: gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 ada0


Update of the BIOS bootcode on a GPT scheme if the root partition is a freebsd-ufs type (root user):

gpart bootcode -b /boot/pmbr -p /boot/gptboot -i partition-number disk-name


I have now to speak about the case of a zfs mirror. This is what you get with a guided installation (Auto (ZFS) with "mirror" selected). Here is an example, a mirror on two disks:

Code:
gpart show                                               
=>        40  3907029088  ada0  GPT  (1.8T)                                
          40        1024     1  freebsd-boot  (512K)                      
        1064         984        - free -  (492K)                          
        2048     4194304     2  freebsd-swap  (2.0G)                      
     4196352  3902832640     3  freebsd-zfs  (1.8T)                        
  3907028992         136        - free -  (68K)                            
                                                                           
=>        40  3907029088  ada1  GPT  (1.8T)                                
          40        1024     1  freebsd-boot  (512K)                      
        1064         984        - free -  (492K)                          
        2048     4194304     2  freebsd-swap  (2.0G)                      
     4196352  3902832640     3  freebsd-zfs  (1.8T)                        
3907028992 136 - free - (68K)

zpool status                                             
  pool: zroot                                                              
state: ONLINE                                                                                 
config:                                                                    
                                                                           
        NAME        STATE     READ WRITE CKSUM                             
        zroot       ONLINE       0     0     0                             
          mirror-0  ONLINE       0     0     0                             
            ada0p3  ONLINE       0     0     0                             
            ada1p3  ONLINE       0     0     0

If your zfs root system is on a mirror, you have to update bootcodes on all disks that belonging to this mirror. Because in case of failure of the main disk, the others disks have to provide the booting.

In this example, there is no efi booting, just BIOS booting. So, at each upgrade I will execute:
Code:
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
 
Last edited:
Thank you very much for the detailed description of how to update bootcode.
I have a clarifying question recording efi bootcode and mirrored zfs-root as described above.

I have installed Freebsd 13/stable on a zfs-mirror (using the auto setting during install), the efi boot partition is therefore mirrored on both drives in the mirror, but the installer only seems to install boot code into the first drive. The efi portion on the second drive is not a msdosfs partion.

Code:
# gpart show nvd0 nvd1
=>        40  1875384928  nvd0  GPT  (894G)
          40      532480     1  efi  (260M)
      532520        1024     2  freebsd-boot  (512K)
      533544         984        - free -  (492K)
      534528    16777216     3  freebsd-swap  (8.0G)
    17311744  1858072576     4  freebsd-zfs  (886G)
  1875384320         648        - free -  (324K)

=>        40  1875384928  nvd1  GPT  (894G)
          40      532480     1  efi  (260M)
      532520        1024     2  freebsd-boot  (512K)
      533544         984        - free -  (492K)
      534528    16777216     3  freebsd-swap  (8.0G)
    17311744  1858072576     4  freebsd-zfs  (886G)
  1875384320         648        - free -  (324K)

# file -s /dev/nvd0p1 /dev/nvd1p1
/dev/nvd0p1: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "BSD4.4  ", sectors/cluster 32, root entries 512, sectors/FAT 65, sectors/track 63, heads 255, sectors 532480 (volumes > 32 MB), serial number 0xf4bb07f6, unlabeled, FAT (16 bit)
/dev/nvd1p1: data

Is there any reason for not having the bootcode on the second disk in the mirror, I would assume that I would not be able to boot if the first disk goes away for some reason?
Do I need to create this by myself?

Thank you very much for the help
 
Seems the nvd1p1 partition isn't formated. So you have to do it, create the directories and copy the loader:

Code:
newfs_msdos -F16 /dev/nvd1p1
mount -t msdosfs /dev/nvd1p1 /mnt
mkdir -p /mnt/efi/boot
cp /boot/loader.efi /mnt/efi/boot/bootx64.efi
umount /mnt
 
In general, the system is compatible with the bootcodes of version-1. So personally, I do it just after the upgrade is finished.
But what if the system is upgraded from a very old version. I assume that you need to update the bootcode before the first shutdown, which occurs after freebsd-update upgrade -r <release>; freebsd-update install. Is it right?
 
Yes. But, if it is a very old version, maybe you won't have enough room in the corresponding partitions.

In some cases, it's simpler to reinstall the whole system (and not only for this specific problem).
 
In some cases, it's simpler to reinstall the whole system (and not only for this specific problem).
In the past, I often reinstalled the whole system due to certain circumstances, such as moving to a new computer, HDD failure, changing the partition scheme, switching to a different type of filesystem, etc.

Are there any other cases when it's easier to reainstall the whole system instead of upgrading?
 
Are there any other cases when it's easier to reainstall the whole system instead of upgrading?
VMs, Cloud images. Those are typically installed and configured with automated tools anyway. Make sure you disconnect your data from the OS. As long as your data is on another disk (or partition, pool, SAN/NAS, whatever) you could just wipe the OS, reinstall, configure what you need, reattach the data and be up and running again.
 
The FreeBSD Handbook now has seven sections in Chapter 24.

New:

{links removed ?}

The following manuals describe the upgrade process of bootcode and boot loaders: gpart(8), gptboot(8), gptzfsboot(8), and loader.efi(8).
 
Last edited:
… a mere list of manpages is not what I expect from a handbook.

I feel the same.

A few months ago, when reports of bootcode-related problems were frequent, I might have had an idea what to write. Now it's like a distant memory, my mind's on other things.

bsduck Emrion if you can think of a suitable addition to 24.3, maybe add a patch file (as a suggestion) to the bug before it closes.
 
Seems the nvd1p1 partition isn't formated. So you have to do it, create the directories and copy the loader:

Code:
newfs_msdos -F16 /dev/nvd1p1
mount -t msdosfs /dev/nvd1p1 /mnt
mkdir -p /mnt/efi/boot
cp /boot/loader.efi /mnt/efi/boot/bootx64.efi
umount /mnt
i installed 13.2 first, then (source) upgraded to 14.0
should i create both folders/files efi/boot/bootx64.efi and efi/freebsd/loader.efi


Code:
newfs_msdos -F16 /dev/ada1p1
mount -t msdosfs /dev/ada1p1 /mnt
mkdir -p /mnt/efi/boot
cp /boot/loader.efi /mnt/efi/boot/bootx64.efi
mkdir -p /mnt/efi/freebsd
cp /boot/loader.efi /mnt/efi/freebsd/loader.efi
umount /mnt

file -s /dev/ada0p1 /dev/ada1p1
/dev/ada0p1: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "BSD4.4  ", sectors/cluster 32, root entries 512, sectors/FAT 65, sectors/track 63, heads 16, sectors 532480 (volumes > 32 MB), serial number 0x9cc41c01, unlabeled, FAT (16 bit)
/dev/ada1p1: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "BSD4.4  ", sectors/cluster 32, root entries 512, sectors/FAT 65, sectors/track 63, heads 16, sectors 532480 (volumes > 32 MB), serial number 0x3875130e, unlabeled, FAT (16 bit)
 
i installed 13.2 first, then (source) upgraded to 14.0
should i create both folders/files efi/boot/bootx64.efi and efi/freebsd/loader.efi
Yes. For the shake of curiosity, what's the output of # efibootmgr -v?
 
Yes. For the shake of curiosity, what's the output of # efibootmgr -v?

Code:
efibootmgr -v
Boot to FW : false
BootCurrent: 0000
Timeout    : 5 seconds
BootOrder  : 0000, 0002, 0003, 0004, 0005
+Boot0000* FreeBSD HD(1,GPT,a95f81b0-3560-11ee-bb6b-a036bcc8b189,0x28,0x82000)/File(\EFI\FREEBSD\LOADER.EFI)
                      gpt/efiboot0:/EFI/FREEBSD/LOADER.EFI /boot/efi//EFI/FREEBSD/LOADER.EFI
 Boot0002* UEFI OS HD(1,GPT,a95f81b0-3560-11ee-bb6b-a036bcc8b189,0x28,0x82000)/File(\EFI\BOOT\BOOTX64.EFI)
                      gpt/efiboot0:/EFI/BOOT/BOOTX64.EFI /boot/efi//EFI/BOOT/BOOTX64.EFI
 Boot0003* UEFI:CD/DVD Drive BBS(0x81,,0x0)
 Boot0004* UEFI:Removable Device BBS(0x82,,0x0)
 Boot0005* UEFI:Network Device BBS(0x83,,0x0)
Unreferenced Variables:
 
Ok, so the upgrade to 14.0-RELEASE promoted the /EFI/FREEBSD/LOADER.EFI loader. It did the same on a bare metal machine I recently upgraded (with some mess apparently...) but didn't touch the boot entries on several VMs (VirtualBox on Windows).

Thank you very much.
 
Well described. Thank you! I'll ask a stupid question, but still. I decided to switch from a binary update to an update from the source code. Updated (successfully, according to the handbook) from 14.1 to 14.1p6.
Question: why update the boot code if everything went well? And also: if I jump from 14.1 to 14.2, will there be problems with booting (without updating the boot code) or not?
I use ZFS and root on ZFS.
 
In general, update of the bootcode isn't mandatory unless (and do it before!) you upgrade a zpool (zpool-upgrade(8)). This is when your last FreeBSD upgrade brings a new version of zfs with one or more new features you can enable on your zpool(s). It's reported by zpool status.

But... I think it's a good habit to upgrade the bootcodes even if you don't plan to upgrade your zpool and even you don't use zfs in order to correct some bugs like all update. Also, after several FreeBSD upgrades, if you keep too old bootcodes, you can have some unexpected problems. At least, I experienced one: https://forums.freebsd.org/threads/why-its-important-to-upgrade-efi-boot-bootx64-efi.79503/

Not to speak about how easy it can be done with sysutils/loaders-update.
 
Thank you. I wanted to install your utility, but I don't see the port (no "loaders-update"). Here's what I have on my ports:
# git status
Bash:
On branch 2024Q4
Your branch is up to date with 'origin/2024Q4'.
nothing to commit, working tree clean
# git show
Bash:
commit 9856aba315d9b6cd2e1765aee6495d8a93defad2 (HEAD -> 2024Q4, origin/2024Q4)
Author: Älven <alster@vinterdalen.se>
Date:   Sun Oct 20 15:47:51 2024 +0400
    net/v2ray: update 4.36.2 → 5.22.0, fix CVE-2021-4070
    + Fix CPE information
    https://nvd.nist.gov/vuln/detail/CVE-2021-4070
    PR:             ports/282227
    Approved by:    maintainer timeout
 
(In addition to previous answer)

You can also check sysutils/loaders-update, the port and package at the quarterly branch wil be available next quarter (2025Q1) when the new quarterly branch is "snapshotted" off the main branch (="latest") of the ports tree.

(You can download it from github - loaders-update and just put it in an appropriate directory in your search path; in that case you'll be responsible to manually monitor and update as indicated.)
All new software in ports (and subsequently any packages built from that) are introduced first only in the main branch (aka "latest"); so when on quarterly you'll just have to wait for the new year!
 
DEar EMrion:
thanks. today i have read this post, but below is my step , wish to help some one. thanks.
1. mount freebsd14.2 iso in your current freebsd14.2 online system.
or poweron machine with freebsd14.2 live disk going to shell.
2. as root , we need do this step : cp /boot/loader.efi /boot/efi/efi/freebsd/loader.efi
note :
/boot/loader.efi location was in mount of freebsd14.2 iso, or freebsd14.2 live shell .
/boot/efi/efi/freebsd/loader.efi this location is your current freebsd14.2 online system in the disk.
/dev/gpt/efiboot0 260M 1.3M 259M 1% /boot/efi
your disk efi partiton /dev/gpt/efiboot0 mount in /boot/efi

ok. , you just do cp /boot/loader.efi /boot/efi/efi/freebsd/loader.efi
all done. reboot your current 14.2 system. the alarm will disppear.
this step mean: new freebsd14.2 upgrade loader.efi file. when you upgrade freebsd14.1 to 14.2 . this process is not upgrade loader.efi file. so we will got an alarm. " boot loader is too old ........xxx" . we do it with this manual.

NOTE : don't need to run below step :
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i partition-number disk-name

wish help some one. thanks.

core is : just copy iso of freebsd14.2 efi loader loader.efi to cover current online freebsd14.2 /boot/efi/efi/freebsd/loader.efi as root. the alarm will disappear.... thanks.
 
Back
Top