Skip to main content

Boot Loader

systemd-boot

systemd comes with systemd-boot already, so no additional packages need to be installed.

Install

ATTENTION: By default, systemd-boot will install itself to either of the well-known ESP locations, e.g. /efi, /boot, or /boot/efi. If your ESP is located somewhere else pass the localtion with the --esp-path parameter.

Install systemd-boot to your EFI System Partition and set it as a boot loader entry in your firmware:

bootctl install

Configure

systemd-boot has two configs:

  • one for the loader itself located at $ESP/loader/loader.conf
  • one for each individual boot entry located at $ESP/loader/entries/*.conf

Loader

NOTE: For a full list of options and their explanation refer to loader.conf(5) § OPTIONS

Key Value Description
default file name The default selected entry (e.g. arch.conf)
timeout number Seconds until the default entry is booted (e.g. 3)
auto-entries boolean Show or hide other boot entries found by scanning the boot partition
auto-firmware boolean Show or hide "Reboot into firmware" entry
console-mode number/string Resolution of the console (e.g. keep to keep the resolution selected by firmware)

An example loader configuration could look something like this:

default       arch
timeout       3
auto-entries  1
auto-firmware 1
console-mode  keep

Boot entry

NOTE: For a full list of options and their explanation refer to the Boot Loader Specification. All paths are relative to the path of your ESP.

Bootloader entry for the main kernel, located at $ESP/loader/entries/arch.conf (assuming $ESP is mounted at /boot):

title	Arch Linux
linux	/vmlinuz-linux
initrd	/amd-ucode.img
initrd	/initramfs-linux.img
options	root=/dev/mapper/vg0-lv_root rw quiet splash rootflags=subvol=@
Key Value Description
title string The name of the entry in the boot menu
linux path Location of the Linux kernel (relative to ESP)
initrd path Location of the Linux initrd image (relative to ESP)
options string Kernel command line parameters
Unified kernel images

When using a unified kernel image, any image ending with *.efi placed under $ESP/EFI/Linux/ will be automatically picked up by systemd-boot along with the metadata embedded in that image (e.g. title, version, etc.)

In case you store your images someplace else, you will need to supply the efi key instead of initrd in your entry *.conf:

title	Arch Linux
efi     /EFI/Arch/linux.efi

EFISTUB

EFISTUB is a method of booting the kernel directly as an EFI executable by the firmware without the need to use a boot loader. This can be useful in cases where you want to reduce the attack surface a boot loader can introduce, or you intend to only ever boot one image. However, some UEFI firmware implementations can be flaky, so this isn't always practical.

Install

To be able to manipulate EFI boot variables install efibootmgr:

pacman -S efibootmgr

Configure

WARNING: efibootmgr can only be run as root!

efibootmgr cannot overwrite existing boot entries and will disregard the creation of a boot entry if one with the same label already exists. If this is the case, delete the boot entry you want to replace first by listing current boot entries:

efibootmgr

This will list all boot entries currently stored in your firmware's EFI variables. To delete an entry, note it's 4-digit boot entry order and instruct efibootmgr to delete it:

efibootmgr -Bb XXXX

To create a new entry efibootmgr needs to know the disk and partition where the kernel image resides on the ESP.

In this example the ESP is the first partition of the block device /dev/nvme0n1. Kernel parameters are part of the -u option. The partition that holds your root file system needs to be passed as a persistent block device name (see: Arch Wiki: Persistent block device naming).

NOTE: If you use LVM, you can supply device mapper paths as these already are persistent.

You can get the persistent block device name with the blkid command, i.e. to get the UUID of the second partition on /dev/nvme0n1:

blkid -s UUID -o value /dev/nvme0n1p2

For ease of scriptability, save the values to environment variables:

ASSUMPTIONS: rootfs is on /dev/nvme0n1, there is a swap partition, file system is btrfs and microcode is AMD.

export ROOT=$(blkid -s UUID -o value /dev/nvme0n1p2)
export SWAP=$(blkid -s UUID -o value /dev/nvme0n1p3)
export CMDL="root=UUID=$ROOT resume=UUID=$SWAP rw quiet splash rootflags=subvol=@ add_efi_memmap initrd=\\\amd-ucode.img initrd=\\\initramfs-linux.img"

Then create the boot entry to load the kernel directly:

efibootmgr -c -L "Arch Linux" -d /dev/nvme0n1 -p 1 -l /vmlinuz-linux -u $CMDL -v

When using a unified kernel image you can instead just point to the image without specifying any kernel parameters via the -u option:

ATTENTION: If Secure Boot is enabled and the command line parameters are embedded in the unified kernel image, any attempt to override them by supplying the -u option anyways will be ignored.

efibootmgr -c -L "Arch Linux" -d /dev/nvme0n1 -p 1 -l "EFI\Linux\archlinux-linux.efi" -v