Linux UEFI boot
How to setup a Linux system that it boot via UEFI?EFI System Partition
- Create a GPT partition table: use the
g
command in fdisk - Create an EFI System Partition (ESP) of sufficient size (e.g. 500MB) to hold grub binaries, kernel and initramfs/initrd: use the
t
command in fdisk and select type 1 - Format the ESP as FAT32 and give it a nice label:
mkfs.vfat -F 32 /dev/sda1 fatlabel /dev/sda1 BOOT
- Create all your other partitions for the root filesystem and swap if you need as usual
The UEFI firmware will look for the ESP in the GPT and boot grub from it. UEFI boot does not require a BIOS Boot Partition (BBP) to hold the grub binary. In fact some UEFI firmwares do not like it when a BBP is present (HPE server for example) and will refuse to look for an ESP! So better remove the BBP.
FAT32 filesystems support no ownership, no permissions and no symlinks. So you can't create the infamous /boot/boot -> .
symlink.
Installing Grub
Boot a kernel with at least EFIVAR_FS=Y or EFI_VARS=Y. It's fine to boot via legacy/CSM/non-EFI for that. This is required to be able to install the UEFI boot loader.Mount the ESP under /boot and install the grub EFI binary on it with:
grub-install --target=x86_64-efi --efi-directory=/boot --removable
Create a suitable grub config file /boot/grub/grub.cfg
:
default=0 timeout=3 # provides video modes insmod efi_gop menuentry 'Linux 5.14' { search --no-floppy --set=root --label BOOT linux /linux-5.14.4 root=LABEL=ROOT rootfstype=ext4 ro net.ifnames=0 initrd /intel-uc.img /initrd.img } menuentry 'UEFI Firmware Settings' { fwsetup }
- Note how we use the label to find the boot partition.
- Note how we use a label for the root filesystem too. This uses syntax recognized by
mount
, assuming your init script in initrd passes that string to mount. - Note how kernel, intel microcode and initrd path use absolute path with respect to the filesystem on the ESP boot partition.
Install a kernel
The kernel needs to support at least these UEFI options:EFI=Y EFIVAR_FS=Y EFI_PARTITION=Y FB_EFI=Y
The EFI_VARS option is old and no longer required. Modern systems use only EFIVAR_FS.
See my Kernel Config Guide for more.
Copy the normal kernel binary to /boot. Make sure the name is consistent with the linux line in grub.cfg. Don't forget your initrd and you are ready to boot!
Firmware menu
Some UEFI firmwares (Tianocore, HPE servers) have an option to configure the boot menu entries and boot order. It may be necessary to add such a custom entry that specifies to loadEFI/BOOT/BOOTX64.EFI
.
Booting from USB Stick
If you are not confident of converting your system yet and just want to try and play, or for other reasons such as the lack of space for a FAT partition you can also use a different disk or USB stick. Just do the GPT formating and make a FAT partition on it and mount that under /boot to install Grub. You then probably have to tell your BIOS/Firmware to boot from it.This way you can safely play without touching an existing working system.
UEFI under QEMU/KVM
For virtual machines under QEMU you need the Tianocore Open Virtual Machine Firmware. Gentoo's package is calledsys-firmware/edk2-ovmf
and installs into
/usr/share/edk2-ovmf/
.
Start qemu with options like these:
qemu-system-x86_64 -machine q35,accel=kvm,smm=on \ -cpu host \ -boot menu=on \ -global driver=cfi.pflash01,property=secure,value=on \ -drive if=pflash,format=raw,unit=0,file=/usr/share/edk2-ovmf/OVMF_CODE.fd,readonly=on \ -drive if=pflash,format=raw,unit=1,file=OVMF_VARS.fd \ ...
- Only recent q35 machines support it!
- Provide the OVMF_CODE.fd as the first readonly pflash device.
- Provide a writeable copy of OVMF_VARS.fd to hold the UEFI firmware state (EFI variables) across reboots as the second pflash device.
- Enable the boot menu (press ESC during boot to enter it) to be able to configure the firmware. The fwsetup Grub entry also enters that menu.
- Provide the disk images as usual via virtio like: -drive file=image.qcow2,if=virtio,cache=none,aio=io_uring
EFI/BOOT/BOOTX64.EFI
file.