Unified kernel image
A unified kernel image (UKI) is a single executable which can be booted directly from UEFI firmware, or automatically sourced by boot-loaders with little or no configuration.
A unified kernel image allows to incorporate all or a subset of the following:
- an EFI stub loader like systemd-stub,
- the kernel command line,
- microcode,
- an initramfs image,
- a kernel image,
- a splash screen.
The resulting executable, and therefore all these elements together can then be easily signed for use with Secure Boot.
Supported architectures
A unified kernel image requires a stub loader, e.g. systemd-stub. Currently systemd-stub is available for amd64, x86 and arm64. On arm64 the kernel must be configured with CONFIG_EFI_ZBOOT=y since systemd-stub does not support decompressing the kernel image and as such the kernel must be built with its own decompressor (zboot). This config option exists since kernel version 6.1, and is enabled in version 6.5 and up of gentoo-kernel-bin . In sys-kernel/gentoo-kernel and sys-kernel/vanilla-kernel this option is enabled when the secureboot USE flag is enabled. It may also be configured manually:
/etc/kernel/config.d/zboot.confCONFIG_EFI_ZBOOT=y
Dependency installation
First one needs a "stub loader", which is provided by systemd-stub. Openrc users have to install sys-apps/systemd-utils , and systemd users need the boot USE flag on sys-apps/systemd .
To generate a Unified Kernel Image (UKI), one needs Dracut or systemd's ukify tool. Notice ukify cannot generate initramfs, while Dracut can.
Dracut users needs the uki flag on sys-kernel/installkernel .
To use ukify, set the ukify USE flag for sys-apps/systemd, and the USE flags uki and ukify for sys-kernel/installkernel.
Configuration
Dracut
The installkernel plugin of Dracut will automatically pick up the layout setting and generate a UKI. (Then a seperate initramfs file won't be prepared). This can be set in install.conf as follows:
/usr/lib/kernel/install.conflayout=uki initrd_generator=dracut uki_generator=dracut
A Unified Kernel Image may contain a kernel command line, specified via /etc/dracut.conf. Note that any kernel command line supplied by the bootloader overrides this include command line, except when Secure Boot is enabled:
/etc/dracut.confkernel_cmdline="..."
/etc/kernel/cmdline is not used when generating Unified Kernel Images with Dracut! This file is used by ukify and when generating entries for systemd-boot.
Secure Boot
To automatically sign the generated UKI for use with Secure Boot:
/etc/dracut.confuefi_secureboot_cert="..." uefi_secureboot_key="..."
For example, when using keys generated by app-crypt/sbctl :
/etc/dracut.confuefi_secureboot_cert="/var/lib/sbctl/keys/db/db.pem" uefi_secureboot_key="/var/lib/sbctl/keys/db/db.key"
To use a PKCS11 URI instead of a plain key file:
/etc/dracut.confuefi_secureboot_cert="..." uefi_secureboot_key="pkcs11:..." uefi_secureboot_engine="pkcs11"
To successfully boot with Secure Boot enabled the Boot Loader should also be signed if one is used. This can be done using the sbsign tool from app-crypt/sbsigntools . Additionally, the UEFI firmware should be configured to accept the used key, this can be done manually or alternatively app-crypt/sbctl can be used to automatically generate and enroll a set of keys. It is also possible to use shim as a pre-loader that is already signed with the 3rd-party Microsoft key, accepted by default on most UEFI enabled motherboards.
Ukify
Since sys-apps/systemd version 253 in 2023, the ukify tool can be used to generate a unified kernel image. When ukify is used, the included kernel command line is configured in /etc/kernel/cmdline. Note that any kernel command line supplied by the bootloader overrides this include command line, except when Secure Boot is enabled.
Secure Boot
To automatically sign the generated UKI for use with Secure Boot:
/etc/kernel/uki.conf[UKI] SecureBootSigningTool=sbsign SecureBootPrivateKey=... SecureBootCertificate=...
To use a PKCS11 URI instead of a plain key file:
/etc/kernel/uki.conf[UKI] SecureBootSigningTool=sbsign SecureBootPrivateKey=pkcs11:... SecureBootCertificate=... SigningEngine=pkcs11
Measured Boot
To instruct ukify to pre-calculate and sign PCR values for use with Measured Boot:
/etc/kernel/uki.conf[PCRSignature:initrd] PCRPrivateKey=... PCRPublicKey=... Phases=enter-initrd [PCRSignature:system] PCRPrivateKey=... PCRPublicKey=... Phases=enter-initrd:leave-initrd enter-initrd:leave-initrd:sysinit enter-initrd:leave-initrd:sysinit:ready
Kernel installation
With the above configurations, a UKI kernel will automatically be generated and installed. This means it is regardless whether one installs Gentoo's distributed kernel or manually run make install in the kernel's source.
Kernel will be installed as e.g. /boot/EFI/Linux/4098b3f648d74c13b1f04ccfba7798e8-6.10.11-gentoo-dist. The format is <machine-id>-<version number> + suffix.
Boot Loaders
systemd-boot and rEFInd
systemd-boot and rEFInd dynamically detect the UKIs installed in the Linux directory on the EFI System Partition, no further configuration is required. Though users of rEFInd might want to enable the refind USE flag on sys-kernel/installkernel to ensure rEFInd will use the correct icon for the installed UKI.
When rEFInd is configured to search for kernels in /boot for example, UKI kernels can be stored there, too.
GRUB
GRUB is capable of loading a UKI payload using the chainloader command. Any parameters entered at the end of the chainloader command will be passed to the kernel.
For example:
/etc/grub.d/40_custommenuentry 'Gentoo GNU/Linux, with Linux 6.11.5-gentoo' {
uki_path=/EFI/Linux/8e6dfbd2da15a3abb3e1a5a862dd78f3-6.11.3.efi
export uki_path
search --set=root --efidisk-only --file $uki_path
chainloader $uki_path root=LABEL=linux rootflags=subvol=@gentoo rootfstype=btrfs ro quiet splash
}
EFI stub
Unified kernel images can also be booted directly from UEFI firmware without the use of any boot loader. Efibootmgr can be used to add or remove boot menu entries for unified kernel images:
root #efibootmgr --create --disk /dev/sdX --part partition_number --label "Gentoo Linux x.y.z" --loader 'EFI\Linux\linux-x.y.z-gentoo.efi' --unicodeAutomated EFI stub booting
Many vendors do not follow the UEFI specification exactly. As a result, automated EFI stub booting, as described below, is not guaranteed to work on all systems. For such systems, a light-weight EFI chain-loading solution that is guaranteed to work on all UEFI systems is systemd-boot.
Systemd kernel-install
app-emulation/virt-firmware contains the kernel-bootcfg tool to assist in the creation and removal of UEFI boot entries for unified kernel images. To set this up, enable the uki , efistub and systemd USE flags on sys-kernel/installkernel and then enable the init service provided by app-emulation/virt-firmware :
For systemd systems:
root #systemctl enable --now kernel-bootcfg-boot-successful.serviceFor OpenRC systems:
root #rc-update add kernel-bootcfg-boot-successful defaultThe systemd USE flag on sys-kernel/installkernel is required, but this flag does not force a dependency on the systemd init system. The dependencies are satisfied by the boot and kernel-install flags on sys-apps/systemd-utils , as such this also works on OpenRC systems.
UEFI boot entries for Unified Kernel Images will now be automatically created and removed. To create one for the currently running kernel the kernel must be reinstalled using either emerge --config gentoo-kernel{,-bin} (for distribution kernels) or make install (for manually managed kernels).
When sys-boot/shim is installed and present on to the EFI System Partition, kernel-bootcfg will register unified kernel images for booting via shim. This may be useful for users who wish to boot unified kernel images with Secure Boot enabled, without registering custom keys in the system's firmware. To setup kernel-bootcfg to use shim, install it to the EFI System Partition, while substituting x64 for the system's UEFI architecture and ${ESP} for the mount point of the EFI System Partition:
root #emerge --ask sys-boot/shimroot #cp /usr/share/shim/BOOTX64.EFI ${ESP}/EFI/Gentoo/shimx64.efi
root #cp /usr/share/shim/mmx64.efi ${ESP}/EFI/Gentoo/mmx64.efi
In addition to automated registration via installkernel, it is also possible to register a new UKI manually:
root #kernel-bootcfg --add-uki ${ESP}/EFI/Linux/linux-x.y.z-gentoo-dist.efi --title x.y.z-gentoo-dist --onceThe --once argument will register the new entry, but not add it to the boot order yet. Instead it will instruct the system to boot the new UKI on the next reboot once (i.e. set the BootNext EFI variable). Upon a successful boot the kernel-bootcfg-boot-successful init service will then add the new UKI to the top of the boot order.
And to manually remove an entry for a given UKI:
root #kernel-bootcfg --remove-uki ${ESP}/EFI/Linux/linux-x.y.z-gentoo-dist.efiTraditional installkernel
For non-systemd systems, automated EFI Stub booting is implemented using sys-boot/uefi-mkconfig . To set this up, enable the uki and efistub USE flags and disable the systemd USE flag on sys-kernel/installkernel . Then reinstall the kernel. uefi-mkconfig will boot new entries via Shim if sys-boot/shim is installed and the shim EFI executable is present in the same directory as the kernel images (i.e. ESP/EFI/Linux).
See also
- 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.
- Efibootmgr — a tool for managing UEFI boot entries.
- Secure Boot — an enhancement of the security of the pre-boot process of a UEFI system.
- Shim — an alternative method of managing accepted Secure Boot keys without touching the UEFI firmware settings
- Dracut — an initramfs infrastructure and aims to have as little as possible hard-coded into the initramfs.
- EFI stub