[322 views]

[]

[ads]

Linux UEFI boot

How to setup a Linux system that it boot via UEFI?

EFI System Partition

  1. Create a GPT partition table: use the g command in fdisk
  2. 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
  3. Format the ESP as FAT32 and give it a nice label:
    mkfs.vfat -F 32 /dev/sda1
    fatlabel /dev/sda1 BOOT
    
  4. 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 to hold the grub binary.

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
}
  1. Note how we use the label to find the boot partition.
  2. 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.
  3. 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!

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 called sys-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 \
 ...