Bootloaderless Boot With EFIstub (2024-07-25)

The most prevalent bootloader on Linux is GRUB2, but there are other offerings put there such as LIFO. But did you know that...you don't need a bootloader at all?

UEFI

UEFI, the replacement of the legacy BIOS, is actually capable of selecting and loading kernels directly, which I don't see many people doing. You don't actually need a booatloader with UEFI. The downside is that if you would like to boot other OSs, you'll have to access the UEFI every time you would like to boot something else. But if you only have a single OS installed, I don't see any downsides.

EFIstub

This can be achieved with an EFIstub. An EFIstub is essentially a kernel that is executable by EFI. This may already be built into the kernel you're using if CONFIG_EFI_STUB=y is set. If not... well compiling the kernel will be its own post. The UEFI essentially just needs an entry for the kernel that is being booted. You could do this form withing your UEFI's shell, but I use efibootmgr for this. It can manage UEFI boo entries from within Linux. If the UEFI is configured appropriately and its version supports it, booting the kernel shouldn't be an issue. Note that keeping the kernel that is being booted updated automatically is distro specific so refer to your distro's documentation. Arch's states:

pacman will directly update the kernel that the EFI firmware will read if you mount the ESP to /boot.

So that's what I did.

efibootmgr

Setting the UEFI boot entry is jsut a single command. I wrote a small script that can be used to automate the process. The script sets it up using the UUID of the root partition. It creates an entry and deletes the previous one if it already exists.

#!/bin/sh

# Delete the existing boot entry
efibootmgr -b 0 -B > /dev/null
printf "Deleted boot entry: 0000\n\n"

# Retrieve the UUID for the root partition
ROOT_UUID=$(sudo blkid | grep root | awk -F 'UUID="' '{split($2, a, "\""); print a[1]}')

# Reload the entry with the new UUID
printf "Reloaded entry 0000...\n"
efibootmgr --disk /dev/nvme0n1 --part 1 --create --label "Arch Linux" --loader /vmlinuz-linux --unicode "root=UUID=$ROOT_UUID rw initrd=\initramfs-linux.img rd.driver.blacklist=nouveau nvidia-drm.modeset=1" --verbose --timeout 0 | grep "Boot0000"

After this I select my kernel in the UEFI boot config and I'm good to go. If you use this script remember to use your own kernel boot parameters if you need them and to use the path to the correct disk. In my case its /dev/nvme0n1.

You should have a fast boot and a good time.