BTX halted: migrating a FreeBSD server's boot system from MBR/Legacy to UEFI
Always nice to get cryptic boot errors when you mess up an upgrade
Introduction
I'm running a small server with a Supermicro X11SCL-F, a Micron SSD, and some hard disks in an encrypted raidz2 ZFS pool.
Hardware:
# geom disk list nvd0 Geom name: nvd0 Providers: 1. Name: nvd0 Mediasize: 256060514304 (238G) Sectorsize: 512 Mode: r2w2e4 descr: Micron_2200_MTFDHBA256TCK lunid: 000000000000000100a1234567891234 ident: 123456789123 rotationrate: 0 fwsectors: 0 fwheads: 0 # dmidecode [...] Base Board Information Manufacturer: Supermicro Product Name: X11SCL-F Version: 1.01 Serial Number: V12345678900 Asset Tag: To be filled by O.E.M. Features: Board is a hosting board Board is replaceable Location In Chassis: To be filled by O.E.M. Chassis Handle: 0x0003 Type: Motherboard Contained Object Handles: 0
Breaking the server
Let's login to it:
Last login: Mon Jan 9 14:30:49 2023 from myotherserver FreeBSD 13.0-RELEASE-p7 (GENERIC) #0: Mon Jan 31 18:24:03 UTC 2022
Uh oh. This server is outdated! Let's update it:
# freebsd-update -r 13.1-RELEASE upgrade Looking up update.FreeBSD.org mirrors... 2 mirrors found. Fetching metadata signature for 13.0-RELEASE from update2.freebsd.org... done. Fetching metadata index... done. Fetching 1 metadata patches. done. Applying metadata patches... done. Inspecting system... done. The following components of FreeBSD seem to be installed: kernel/generic kernel/generic-dbg src/src world/base world/lib32 The following components of FreeBSD do not seem to be installed: world/base-dbg world/lib32-dbg Does this look reasonable (y/n)? y [...] To install the downloaded upgrades, run "/usr/sbin/freebsd-update install". # /usr/sbin/freebsd-update install Installing updates... Kernel updates have been installed. Please reboot and run "/usr/sbin/freebsd-update install" again to finish installing updates. # reboot
Oh no! the server is not booting anymore!
Consoles: internal video/keyboard [...] BTX halted
SSHing into a live shell
Let's boot a FreeBSD ISO image and get into the shell:
Configure the network:
/sbin/dhclient igb0
Mount the system read/write:
/sbin/mount -u /
Edit /etc/ssh/sshd_config to allow root to login (or create a user and add it to the wheel group if you're one of those people who'd rather die than SSH as root)
Set a password:
/usr/bin/passwd
Start SSH:
/usr/sbin/service sshd onestart
Connect to SSH.
Fixing the boot system
Let's look at the partitions of the boot SSD:
# gpart show nvd0 => 40 500118112 nvd0 GPT (238G) 40 1024 1 freebsd-boot (512K) 1064 984 - free - (492K) 2048 33554432 2 freebsd-swap (16G) 33556480 466561024 3 freebsd-zfs (222G) 500117504 648 - free - (324K)
Looks like I forgot to migrate this server to UEFI. It's still in MBR. That's why it couldn't boot.
Let's fix that!
Delete the legacy boot partition:
# /sbin/gpart delete -i 1 nvd0 nvd0p1 deleted
Add an EFI partition instead:
# /sbin/gpart add -t efi -a 4k -l nvme-efi -i 1 nvd0 nvd0p1 added # gpart show nvd0 => 40 500118112 nvd0 GPT (238G) 40 2008 1 efi (1.0M) 2048 33554432 2 freebsd-swap (16G) 33556480 466561024 3 freebsd-zfs (222G) 500117504 648 - free - (324K)
Format the EFI partition:
# /sbin/newfs_msdos -F 32 -c 1 /dev/gpt/nvme-efi newfs_msdos: 1944 clusters too few clusters for FAT32, need 65525
Oops, we don't have enough space on the partition. Let's shrink the swap partition then:
# /sbin/gpart delete -i 1 nvd0 nvd0p1 deleted # /sbin/gpart delete -i 2 nvd0 nvd0p2 deleted # /sbin/gpart show nvd0 => 40 500118112 nvd0 GPT (238G) 40 33556440 - free - (16G) 33556480 466561024 3 freebsd-zfs (222G) 500117504 648 - free - (324K) # /sbin/gpart add -t efi -a 4k -s 100M -l nvme-efi -i 1 nvd0 nvd0p1 added # /sbin/gpart add -t freebsd-swap -i 2 nvd0 nvd0p2 added # /sbin/gpart show nvd0 => 40 500118112 nvd0 GPT (238G) 40 204800 1 efi (100M) 204840 33351640 2 freebsd-swap (16G) 33556480 466561024 3 freebsd-zfs (222G) 500117504 648 - free - (324K)
Let's format now:
# /sbin/newfs_msdos -F 32 -c 1 /dev/gpt/nvme-efi /dev/gpt/nvme-efi: 201616 sectors in 201616 FAT32 clusters (512 bytes/cluster) BytesPerSec=512 SecPerClust=1 ResSectors=32 FATs=2 Media=0xf0 SecPerTrack=63 Heads=255 HiddenSecs=0 HugeSectors=204800 FATsecs=1576 RootCluster=2 FSInfo=1 Backup=2
Let's mount the partition and copy the EFI boot system into it:
# /bin/mkdir -p /mnt/boot/efi # /sbin/mount -t msdosfs /dev/gpt/nvme-efi /mnt/boot/efi # /bin/mkdir -p /mnt/boot/efi/EFI/BOOT # /bin/cp /boot/loader.efi /mnt/boot/efi/EFI/BOOT/BOOTX64.efi
Reboot:
# /sbin/umount /mnt/boot/ # /sbin/reboot
Configuring the BIOS and booting
Configure the BIOS to boot the UEFI partition we just created
Alright, we reached the bootloader. It's a success!