systemd/systemd-boot
systemd-boot, formerly known as gummiboot (rubber dinghy), is a minimal UEFI boot manager.
Features
- Bootloader integration with systemd provided by the bootctl command.
- Ability to select next boot.
- Easy and simple configuration files which can be generated automatically.
- Auto add Windows and EFI firmware setup entries.
- Change timeout, default entry, edit kernel command line options on the fly from the boot menu.
Pre-Deployment Considerations
The Boot Loader Specification outlines a standard for bootloaders to follow. This specification is one of the methods used by systemd-boot to determine the location of the ESP and XBOOTLDR partitions.
When using XBOOTLDR, the ESP is used to store the bootloader's PE32+ files (.efi files) and their configuration files, while the XBOOTLDR partition is used to store Linux kernels, initramfs, and configuration files.
The Boot Loader Specification is not yet widely adopted by other bootloaders.
Use partitioning tools to create an XBOOTLDR partition with Partition Type GUID bc13c2ff-59e6-4262-a352-b275fd6f7172
, and then format that partition with any file system that the target EFI implementation supports (or can be made to support). All EFI implementations support the use of FAT filesystems.
- If using fdisk, the Partition Type GUID can be set using the t command to change the partition type, and then selecting 136 to set it to "Linux extended boot".
- If using gdisk, it can be set using the t command to change the partition type code, and then specifying hex code EA00 to set it to "XBOOTLDR partition".
The Boot Loader Specification recommends that, when a XBOOTLDR partition exists, it be mounted at /boot, and the ESP, at /efi. These should be mounted using an autofs or automount implementation so that they are only mounted when needed.
There are many mechanisms for implementing this; for OpenRC users, the sys-fs/autofs package can be used. For systemd users, either adding the x-systemd.automount
option to the /etc/fstab entry for the XBOOTLDR and ESP partitions, creating a systemd automount unit, or Discoverable Partitions Specification automatically created mounts can be used.
bootctl looks for the XBOOTLDR partition is at /boot. If it is mounted elsewhere, the
--boot-path
option must be supplied.Installation
systemd-boot is included within sys-apps/systemd and, for users of non-systemd-init systems, sys-apps/systemd-utils.
Kernel
Because systemd-boot can only load EFI executables, the desired kernel must support EFI stub (CONFIG_EFI_STUB=y):
Processor type and features --->
[*] EFI runtime service support
[*] EFI stub support
[ ] EFI mixed-mode support
OpenRC
Install the sys-apps/systemd-utils package with the boot USE flag enabled:
root #
mkdir -p /etc/portage/package.use
root #
echo "sys-apps/systemd-utils boot kernel-install" >> /etc/portage/package.use/systemd-utils
root #
emerge --ask --oneshot --verbose sys-apps/systemd-utils
systemd
For versions of systemd >= 254, emerge sys-apps/systemd with the boot USE flag enabled:
root #
mkdir -p /etc/portage/package.use
root #
echo "sys-apps/systemd boot" >> /etc/portage/package.use/systemd
root #
emerge --ask --oneshot --verbose sys-apps/systemd
For older versions, the gnuefi USE flag toggles this functionality:
root #
mkdir -p /etc/portage/package.use
root #
echo "sys-apps/systemd gnuefi" >> /etc/portage/package.use/systemd
root #
emerge --ask --oneshot --verbose sys-apps/systemd
Installation to the ESP (EFI system partition)
First ensure that the system has booted in UEFI mode - if following command returns an error the system is not booted in UEFI mode:
root #
ls /sys/firmware/efi/efivars
systemd, when partitions are configured according to the Discoverable Partitions Specification, can automatically mount the ESP to /efi and the XBOOTLDR partition to /boot.
Then, use bootctl to install systemd-boot to the ESP:
root #
bootctl install
bootctl will attempt to automatically identify an ESP mounted at /efi, /boot, or /boot/efi (in that order). If the ESP is mounted elsewhere, pass the
--esp-path
option to specify the appropriate location.Configuration
Overview:
- Main configuration for systemd-boot is done in file /loader/loader.conf of the EFI System Partition (ESP).
- Boot menu entries are generated for each file ending with .conf located in /loader/entries of the ESP.
- EFI PE32+ executable files (including kernel EFI stubs) and initramfs files can be placed anywhere in the ESP.
loader.conf
Although its syntax is well documented in loader.conf(5), here is the example:
default gentoo-sources-kernel
timeout 3
# editor no
The name of the default entry is the file name of the menu entry file, as created in the next section, without the .conf suffix.
Menu entry files
The boot menu will show one entry for each .conf file.
Following is an example menu entry file named "gentoo-sources-kernel" where the kernel and initramfs are at /efi/vmlinuz and /efi/initramfs respectively, assuming that the ESP is mounted at /efi like in the example from the Handbook:
title Gentoo Linux
linux /vmlinuz
initrd /initramfs
options root=/dev/sda3 quiet
For more options please refer to the Bootloader Specification
Systemd's kernel-install
can be used to automate the process of generating menu entry files (and initramfs) whenever make install
is called during a kernel build. It is enabled with the systemd-boot flag on sys-kernel/installkernel:
sys-kernel/installkernel systemd systemd-boot
root #
emerge --ask sys-kernel/installkernel
The options documented in kernel-install(8) can be used to customize the installed menu entries.
As an example, the kernel cmdline can be customized by updating /etc/kernel/cmdline:
root=/dev/sda3
quiet
Unified Kernel Images
Unified kernel images (UKIs) do not require a bootloader entry. Systemd-boot automatically discovers UKIs in the EFI/Linux directory on the EFI System Partition. If custom options should be applied when booting the UKI then it is possible to automate adding a bootloader entry with these custom options using a kernel-install plugin:
#!/usr/bin/env bash
COMMAND="${1}"
KERNEL_VERSION="${2}"
BOOT_DIR_ABS="${3}"
KERNEL_IMAGE="${4}"
if [[ "${KERNEL_INSTALL_LAYOUT}" != "uki" ]]; then
exit 0
fi
if [[ ${COMMAND} == add ]]; then
cat > "${BOOT_DIR_ABS}/loader/entries/1-gentoo-uki-${KERNEL_VERSION}.conf" <<- EOF
title Gentoo
linux /EFI/Linux/${ENTRY_TOKEN}-${KERNEL_VERSION}.efi
options <my custom options>
sort-key <my custom sort key>
EOF
elif [[ ${COMMAND} == remove ]]; then
rm -f "${BOOT_DIR_ABS}/loader/entries/1-gentoo-uki-${KERNEL_VERSION}.conf"
fi
The default entry, increase/decrease timeout, edit command line options, and change resolution are accessible right from boot menu. Refer to systemd-boot(7)’s KEY-BINDINGS section for keyboard shortcuts.
Usage
Secure Boot
If the secureboot USE flag is enabled on sys-apps/systemd or sys-apps/systemd-utils, Portage recognizes the SECUREBOOT_SIGN_KEY and SECUREBOOT_SIGN_CERT environment variables which allow specifying a key (or pkcs11 URI) and certificate to sign the built EFI executable for use with Secure Boot. When bootctl install or bootctl update are called the signed version will be installed to the EFI System Partition.
To successfully boot with Secure Boot enabled the firmware must be configured to accept the used certificate. Alternatively sys-boot/shim can be used to chain-load systemd-boot, the Shim binary is pre-signed with the 3rd-party Microsoft certificate which is accepted by default on most motherboards.
SECUREBOOT_SIGN_KEY="..."
SECUREBOOT_SIGN_CERT="..."
At the time of this writing, the Shim is hard-coded to load and run the file named grubx64.efi. This problem can be circumvented by simply copying file EFI\systemd\systemd-bootx64.efi in the ESP to the directory where the Shim is installed, and renaming the file grubx64.efi. See the section below for a phase hook that automates this process.
ESP file update process
Although updates to the systemd-boot related files are maintained by Portage, it will still be necessary for bootloader related files within the EFI System Partition to be updated each time the package manager updates the files within the package. This will provide important feature enhancement and bug fixes to the files within the ESP.
systemd service
systemd users can simply enable the service unit systemd-boot-update - if a handbook installation was completed this is probably already enabled. systemd-boot-update will check if the installed systemd-boot is outdated every time the system boots and will update it if required.
root #
systemctl enable --now systemd-boot-update.service
Portage hook
Using a Portage hook (ebuild phase function[1]), systemd-boot can be automatically updated whenever the package is updated.
The following phase hook file will update systemd-boot and also set it up to work with Shim if this package is installed.
post_pkg_postinst() {
# Sanity check
if [[ "$(bootctl is-installed)" == "yes" ]]; then
ebegin "Updating systemd-boot"
bootctl --no-variables --graceful update
eend ${?} || ewarn "Updating systemd-boot failed"
# If shim is installed, copy it to ESP as well
if use secureboot; then
if has_version sys-boot/shim; then
ebegin "Updating shim"
local return=0
local bootpath=$(bootctl -p)
local sdbootpath=${bootpath}/EFI/systemd/systemd-bootx64.efi
local grub4shimpath=${bootpath}/EFI/BOOT/grubx64.efi
local shim=${EROOT}/usr/share/shim/BOOTX64.EFI
local mm=${EROOT}/usr/share/shim/mmx64.efi
# Copy shim to ${ESP}/BOOT/BOOTX64.efi
cp "${shim}" "${bootpath}/EFI/BOOT/" || ( ewarn "Failed to install shim" && return=1 )
# And copy the corresponding MokManager
cp "${mm}" "${bootpath}/EFI/BOOT/" || ( ewarn "Failed to install MokManager" && return=1 )
# Copy systemd-boot to where shim looks for the bootloader
cp ${sdbootpath} ${grub4shimpath} || ( ewarn \
"Failed to copy systemd-boot to location expected by shim" && return=1)
eend ${return} || ewarn "Updating shim failed"
else
ewarn "sys-boot/shim is not installed! Ensure that your key is"
ewarn "registered with the system firmware or secure boot might fail!"
fi
fi
else
elog "No installation of systemd-boot detected, not updating"
elog "systemd-boot. If the system is using systemd-boot as the"
elog "bootloader then update it manually with: bootctl update."
fi
}
See also
- Systemd — a modern SysV-style init and rc replacement for Linux systems.
- UEFI — a firmware standard for boot ROM designed to provide a stable API for interacting with system hardware. On x86 it replaced the legacy BIOS.