# Update of the bootcodes for a GPT scheme



## Emrion (Apr 30, 2021)

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.

*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:

```
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): 


```
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`



Spoiler: What if FreeBSD complains that there is not enough room to copy /boot/loader.efi?



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:

```
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:

```
cp /boot/loader.efi /boot/efi/efi/boot/bootx64.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:


```
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:

```
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
```


----------



## Ibmosin (Jan 9, 2022)

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.


```
# 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


----------



## Emrion (Jan 9, 2022)

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


```
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
```


----------



## Ibmosin (Jan 10, 2022)

Thank you.

I did some further digging. It is apparently a know problem with the FreeBSD 13 installer, that only the EFI partition on the first drive is formatted and setup.
For reference it is discussed here: https://forums.freebsd.org/threads/freebsd-13-uefi-boot-not-realy-redundant.82346
and a bug has been reported: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=258987


----------



## grahamperrin@ (Feb 6, 2022)

Thanks, 



Ibmosin said:


> … a bug has been reported: …



Also FreeBSD bug 255318 – handbook: Document how to update the bootloader


----------



## Kaminar (Feb 11, 2022)

Emrion said:


> 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?


----------



## Emrion (Feb 11, 2022)

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).


----------



## Kaminar (Feb 17, 2022)

Emrion said:


> 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?


----------



## SirDice (Feb 17, 2022)

Kaminar said:


> 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.


----------



## grahamperrin@ (Apr 3, 2022)

The FreeBSD Handbook now has seven sections in Chapter 24. 

New: 

24.3. Updating Bootcode (split) | <https://docs.freebsd.org/en/books/handbook/book/#updating-bootcode> (non-split)



> The following manuals describe the upgrade process of bootcode and boot loaders: gpart(8), gptboot(8), gptzfsboot(8), and loader.efi(8).


----------



## bsduck (Apr 4, 2022)

I hope it won't stay that short, because a mere list of manpages is not what I expect from a handbook.


----------



## grahamperrin@ (Apr 4, 2022)

bsduck said:


> … 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.


----------

