Unified Extensible Firmware Interface (UEFI)

Introduction

FreeBSD can boot using UEFI on the amd64, arm64 (both since FreeBSD 10.1 r264095), i386, arm, and riscv platforms. More information is available in uefi(8). Like loader(8), the UEFI loader loader.efi supports booting from GPT UFS and ZFS filesystems and supports GELI in the loader.

Virtualised Development Environment

If you wish to test this code under a virtual environment, UEFI firmware images are available for qemu. Assuming you have a version of qemu greater than 0.9.1, you can download the OVMF images from here. Download the ovmf-x64 rpm file and unpack it with tar xf <ovmf x64 file>.rpm. You'll probably want to copy usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd somewhere more convenient then remove the rest of the extracted files and directories. To test the code I run:

> qemu-system-x86_64 -m 1024 -serial stdio -bios OVMF-pure-efi.fd -hda fat:<path to boot directory>

Alternatively, to test UEFI CD support:

> qemu-system-x86_64 -m 1024 -serial stdio -bios OVMF-pure-efi.fd -cdrom <path to ISO image>

The boot directory contains my built loader.efi as well as any kernel I want to boot.

Real Hardware Gotchas

These are some issues that benno@ ran into when using real hardware (ie, not qemu) in early development:

Bootable UEFI memory stick or Hard Disk

To test UEFI booting on a memory stick or a hard disk, create a GPT partition table with a small EFI partition and the rest of the space dedicated to a FreeBSD UFS partition:

gpart create -s gpt da0
gpart add -t efi -s 40M da0
gpart add -t freebsd-ufs da0
newfs_msdos -F 32 -c 1 /dev/da0p1
mount -t msdosfs /dev/da0p1 /mnt
mkdir -p /mnt/EFI/BOOT
cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.efi
umount /mnt
newfs -U -L FreeBSD /dev/da0p2

Perform the install to the UFS partition, as usual:

mount /dev/da0p2 /mnt
make DESTDIR=/mnt installkernel installworld distribution
echo "/dev/da0p2 / ufs rw 1 1" >> /mnt/etc/fstab
umount /mnt

TODO: Use a label for the root fs instead

Create etc/fstab.

umount /mnt                                                                     

CD/DVD Boot under UEFI

The approach for creating a bootable CD/DVD image for UEFI is to create a FAT filesystem image containing your loader code as it would be laid out in an EFI System Partition. This image is then attached to the CD/DVD image as a non-emulation El Torito boot image. To make an image that is bootable under both legacy BIOS and UEFI, the BIOS image is placed first and the UEFI image is placed as an alternate. More information can be found here.

A sample boot ISO can be created using the following steps.

Create a FAT filesystem image and place our loader in it in the default path that UEFI will look for:

> mkdir -p efiroot/EFI/BOOT
> cp loader.efi efiroot/EFI/BOOT/BOOTX64.efi
> makefs -t msdos -s 40m -o fat_type=32,sectors_per_cluster=1,media_descriptor=248 efiboot.img efiroot

We now have our UEFI boot image. The next step is to make the ISO image. We assume that you have a directory called image containing the file structure you want in your ISO.

> makefs -t cd9660 -o bootimage='i386;efiboot.img' -o no-emul-boot -o rockridge -o label="UEFItest" -o publisher="test" uefi-test.iso image

You should now have an ISO image in uefitest.iso that will boot using UEFI.

The version that is built for FreeBSD 11 snapshots by the release scripts has multiple boot images attached in order to support BIOS and UEFI. You can do something similar by the following:

> makefs -t cd9660 -o 'bootimage=i386;efiboot.img' -o no-emul-boot -o 'bootimage=i386;/boot/cdboot' -o no-emul-boot -o rockridge -o label="UEFItest" -o publisher="test" uefi-test.iso image

Bootable Image from NanoBSD

> cd $TOP/tools/tools/nanobsd/embedded
> sh ../nanobsd.sh -c qemu-amd64-uefi.cfg

The bootable image will be in $TOP/../qemu-amd64-uefi/obj/_.disk.image.qemu-amd64-uefi.qcow2 that you can feed to qemu, as described in the Virtualized Development Environment section above. You can also put it on a USB stick.

Secure Boot

See the SecureBoot page.

Tasks

Create the ESP as a 40MB FAT32 filesystem to maximize compatibility

Done

Improve diagnostics when something goes wrong (e.g. can't allocate memory in early loader stage

Started by bcran@

Verify API usage to maximize compatibility (e.g. corner cases around GetMemoryMap calls)

Started by bcran@

Build 32-bit EFI loader and install as /BOOT/EFI/BOOTIA32.efi

Not Started

Support booting 64-bit FreeBSD on a 64-bit CPU from a 32-bit EFI environment

Not Started

Support side-by-side installation with other OSes: e.g. installing loader as /EFI/FreeBSD/BOOTX64.efi

Done

Filesystem / partition support

Next-stage partition selection

Not Started

Test Results

The amd64 UEFI loader has successfully booted on the following devices:

It is presumed fixed on the following devices:

If you encounter an issue with UEFI boot on a FreeBSD-CURRENT or stable/10 snapshot after r292551 please submit a PR with details. For UEFI issues on FreeBSD 10.2-release or earlier please send an email with details to the freebsd-stable mailing list.

Known Issues

Search for PRs tagged with the UEFI keyword.


CategoryProject

UEFI (last edited 2024-02-17T19:24:13+0000 by ChrisMoerz)