systemd/systemd-boot

From Gentoo Wiki
Jump to:navigation Jump to:search

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):

KERNEL Enable EFI stub support (CONFIG_EFI_STUB)
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.

Note
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:

FILE /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:

FILE /efi/loader/entries/gentoo-sources-kernel.confMenu entry file
title 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:

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

Configuration in boot menu

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.

FILE /etc/portage/make.confmake.conf
SECUREBOOT_SIGN_KEY="..."
SECUREBOOT_SIGN_CERT="..."
Note
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.

FILE /etc/portage/env/sys-apps/systemdsystemd-boot update hook
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 -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
Note
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.

See also

  • Systemd — a modern SysV-style init and rc replacement for Linux systems.

External resources