systemd/systemd-boot

From Gentoo Wiki
Jump to:navigation Jump to:search

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 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.

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

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

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

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

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 menu entries

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:

FILE /etc/portage/package.use/sd-boot
sys-kernel/installkernel systemd systemd-boot
root #emerge --ask sys-kernel/installkernel

The options documented in kernel-install(8) can be used to customise the installed menu entries.

As an example, the kernel cmdline can be customised by updating /etc/kernel/cmdline:

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

FILE /etc/kernel/install.d/95-uki-with-custom-opts.install
#!/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

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(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.

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 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.

FILE /etc/portage/env/sys-apps/systemd-utilssystemd-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
}

See also

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

External resources