systemd/systemd-boot
systemd-boot, formerly called gummiboot, is a minimal UEFI boot manager which loads EFI executables.
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 command line options on the fly from the boot menu.
Installation
Since systemd-v220 systemd-boot is included within the sys-apps/systemd package.
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" >> /etc/portage/package.use/systemd-utils
root #
emerge --ask --oneshot --verbose sys-apps/systemd-utils
systemd
(Re)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
Installation to the ESP (EFI system partition)
First make sure the system booted in UEFI mode. If following command gives error, then reboot in UEFI mode.
root #
ls /sys/firmware/efi/efivars
To dual boot with Windows, make sure to use same ESP for both Windows & Linux.
root #
sfdisk --list /dev/sdX | grep EFI
/dev/sdX1 2048 1261567 1259520 615M EFI System /dev/sdX5 487587840 488112127 524288 256M EFI System
In this case there are two ESPs, administrator knows sdX1 is Windows' and sdX5 is Linux's ESP. To dual-boot, install systemd-boot to Windows' ESP.
root #
umount /efi
root #
mount <The ESP here i.e. /dev/sdX1> /efi
root #
bootctl install
Last command will install necessary files into ESP and move systemd-boot to top in boot order.
bootctl will look if the ESP is mounted at /efi, /boot or /boot/efi. If it is mounted elsewhere, an
--esp-path
option specifying its mountpoint's pathname must be used.Migration
OpenRC
Prior to version 250 systemd-boot installation used package sys-boot/systemd-boot
. New method requires users to migrate to package sys-apps/systemd-utils with USE flag boot
enabled.[1]
root #
mkdir -p /etc/portage/package.use
root #
echo "sys-apps/systemd-utils boot" >> /etc/portage/package.use/systemd-utils
root #
emerge --ask --oneshot --verbose sys-apps/systemd-utils
root #
emerge --depclean sys-boot/systemd-boot
systemd
Prior to version 254 systemd-boot was installed by enabling gnuefi
USE flag. But now systemd uses dev-python/pyelftools replacing sys-boot/gnu-efi thus users need to replace USE flag gnuefi
with boot
.[2]
root #
sed -i "s/gnuefi/boot/g" /etc/portage/package.use/systemd
root #
emerge --ask --oneshot --verbose sys-apps/systemd
root #
emerge --depclean sys-boot/gnu-efi
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, here is the example:
/efi/loader/loader.conf
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:
/efi/loader/entries/gentoo-sources-kernel.conf
Menu entry filetitle Gentoo Linux
linux /vmlinuz
initrd /initramfs
options root=/dev/sda3 quiet
For more options please refer to the Bootloader Specification
Automatically generate entries
Manually writing menu entry files every time the kernel is updated can be quite troublesome. There's a way to automatically generate menu entry files just after installing a kernel.
systemd
To set it up, first install the sys-kernel/installkernel-systemd-boot package. Now, when installing a kernel it'll generate menu entry .conf file. As this package uses kernel-install command on the back end, refer to kernel-install to further customize this automation. For example to customize kernel command line, put options into the /etc/kernel/cmdline file:
/etc/kernel/cmdline
root=/dev/sda3
quiet
Then reinstall the kernel. The entry file should be generated in the \loader\entries directory of the EFI System Partition. For sys-kernel/gentoo-kernel-bin, run:
root #
emerge --config sys-kernel/gentoo-kernel-bin
The default entry, increase/decrease timeout, edit command line options, and change resolution are accessible right from boot menu. Refer to systemd-boot’s KEY-BINDINGS section for keyboard shortcuts.
Setting a password
A project called systemd-boot-password exists in order to set a password on the systemd-boot menu. This is to prevent unauthorized changes to the kernel command-line and/or other boot parameters, which could compromise controls around system security. As of 2022-12-13, systemd-boot-password is not available in the ::gentoo ebuild repository, and must be manually installed.
Other secondary bootloaders such as GRUB have password protection features as well.
Usage
Secure Boot
If the secureboot
flag on sys-apps/systemd or sys-apps/systemd-utils is enabled 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 is 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.
/etc/portage/make.conf
make.confSECUREBOOT_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 profile users can simply enable the service unit systemd-boot-update. This way on every boot, the systemd-bootx64.efi file will be copied (overridden) to the ESP:
root #
systemctl enable --now systemd-boot-update.service
Flash storage (i.e. SSD) users might not want to waste few KBs of redundant write cycles which accumulates in wear and tear, so an alternative approach is shown below.
Portage hook
Using a Portage hook (ebuild phase function[3]), the systemd-boot.efi file will only be copied to the ESP when the systemd(-utils) base package has been updated. The following phase hook file will update systemd-boot and also set it up to work with the Shim if this package is installed. If sys-apps/systemd-utils is used instead of sys-apps/systemd adjust the path of the phase hook accordingly.
/etc/portage/env/sys-apps/systemd
systemd-boot update hookpost_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 -x)
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
}
Troubleshooting
Solve low space with extended boot
Placing multiple kernel, initramfs files, (if dual-booting) Windows files on same partition might fill up space and result in errors while installing kernel.
Solution is to have two separate partitions. Bootloaders' PE32+ files (.efi files) and their configuration files, which are small in size, go in the EFI System Partition (ESP), and a new partition, the "Extended Boot Loader Partition" (XBOOTLDR), is used to store Linux kernels, initramfs and configuration files, which are relatively big in size.
Use partitioning tools to create the XBOOTLDR partition with Partition Type GUID bc13c2ff-59e6-4262-a352-b275fd6f7172
, and then format that partition with a FAT filesystem. If using fdisk, this 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 from sys-apps/gptfdisk, 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.
root #
umount -R /boot
root #
umount /efi
root #
mount <The ESP here> /efi
root #
mount <The XBOOTLDR partition here> /boot
root #
bootctl install
bootctl will look if the XBOOTLDR partition is mounted at /boot. If it is mounted elsewhere, a
--boot-path
option specifying its mountpoint's pathname must be used.