EFI stub
- CONFIG_PM_STD_PARTITION for hibernation
An EFI (boot) stub[1] is a kernel that is an EFI executable (i.e., can boot directly from UEFI); EFI stub kernels may boot with or without a bootloader.
Kernel configuration
EFI stub support
The following kernel configuration options must be enabled:
Processor type and features --->
[*] EFI runtime service support Search for <code>CONFIG_EFI</code> to find this item.
[*] EFI stub support Search for <code>CONFIG_EFI_STUB</code> to find this item.
[ ] EFI mixed-mode support (OPTIONAL) Search for <code>CONFIG_EFI_MIXED</code> to find this item.
EFI mixed-mode support is only required to boot a 64-bit kernel from 32-bit firmware if the CPU supports 64-bit mode and EFI handover is enabled.
Installation
Automated
Since UEFI implementations differ between vendors, EFI Stub booting is not guaranteed to work for all UEFI systems; ensure a backup boot method is available before attempting (automated) EFI Stub booting.
Automated EFI stub booting is provided by sys-kernel/installkernel when the efistub USE flag is enabled; this relocates the regular boot layout from /boot to the EFI/Gentoo directory on the ESP.
Systemd kernel-install
When both the efistub and systemd USE flags are enabled on sys-kernel/installkernel, kernel-install calls kernel-bootcfg from app-emulation/virt-firmware to add or remove a boot entry for the installed or removed kernel. Installkernel is called automatically by the kernel's make install or by the Distribution Kernels' post-install phase; therefore, no special action is required when installing a new kernel, though the kernel-bootcfg-boot-successful init service from app-emulation/virt-firmware should be enabled to automatically make an entry for a new kernel permanent when it successfully boots.
For systemd systems:
root #systemctl enable --now kernel-bootcfg-boot-successful.serviceFor OpenRC systems:
root #rc-update add kernel-bootcfg-boot-successful defaultWhen the to-be-registered kernel image is not a Unified Kernel Image (UKI), a kernel command line for the new entry is read from:
- /etc/kernel/cmdline, or
- /usr/lib/kernel/cmdline, or
- /proc/cmdline
in this order. In addition, the initrd= kernel command line argument is automatically added if an initramfs was generated while installing the kernel. If on the other hand the to-be-registered kernel is a UKI, then no command line is added to the new entry; instead, the command line built into the UKI is used and the contents of this built-in command line are usually read from the same files when the UKI is generated.
The initramfs and kernel command line may also be embedded into the kernel: see the sections below for more information.
Traditional installkernel
When the efistub USE flag is enabled on sys-kernel/installkernel but the systemd USE flag is disabled Installkernel calls uefi-mkconfig from sys-boot/uefi-mkconfig to dynamically update the UEFI configuration; if the shim EFI executable is present in the same directory as the kernel image, the kernels will be chainloaded via Shim.
Manual
With the kernel configured with EFI Stub support and assuming the ESP is mounted at /efi, create a separate directory below /efi/EFI:
root #mkdir -p /efi/EFI/exampleOn some systems /efi/EFI or /efi/efi (in lowercase) may already exist (assuming the ESP is mounted at /efi). The FAT file system of the ESP is not case-sensitive, but case-preserving (VFAT); with the default VFAT mount options, the above command will work in both cases. See the case sensitivity section in the FAT article for further details.
The kernel is created from the current kernel directory and copied to the new directory. This will install the kernel to /efi/EFI/example/bzImage.efi:
/usr/src/linux #make && make modules_install && cp arch/x86/boot/bzImage /efi/EFI/example/bzImage.efiIt is recommended when upgrading the kernel to keep an older version which is known to work:
user $tree -L 3 /efi /efi
└── EFI
└── example
├── bzImage-6.1.67.efi
└── bzImage-6.1.70.efiRoot partition configuration
To boot directly from UEFI, the kernel or its initramfs must know where to find the root partition of the system to be booted; when using a bootmanager like grub, the kernel gets the root's path from the bootmanager via the command line; when using a stub kernel, two options may be used to give the kernel this information - choose one of these options:
Option 1: Configuring it into the kernel
Processor type and features --->
[*] Built-in kernel command line
(root=PARTUUID=adf55784-15d9-4ca3-bb3f-56de0b35d88d rw)
The value adf55784-15d9-4ca3-bb3f-56de0b35d88d is an example and must be replaced with the real root's UUID, which can be obtained by using the blkid command:
root #blkid | grep sda3
/dev/sda3: UUID="d1e0c1e0-3a40-42c5-8931-cfa2c7deae32" TYPE="ext4" PARTUUID="adf55784-15d9-4ca3-bb3f-56de0b35d88d"
Option 2: Configuring it into UEFI
To add an entry with command line arguments:
root #efibootmgr --create --disk /dev/sda --label "Gentoo EFI Stub" --loader "\EFI\example\bzImage.efi" -u "root=/dev/sda3"When using a initramfs, setting the root location using a PARTUUID or (filesystem) UUID is generally preferable and less error prone.
More examples may be found in Creating a boot entry.
Optional: Kernel with initramfs
When using a kernel with an external initramfs (as a CPIO archive), additional steps are necessary. There is always an initramfs file when building a dist-kernel or using genkernel; when using a dist-kernel, this initramfs is named "initrd" and is in /usr/src/linux-6.1.57-gentoo-dist/arch/x86/boot/initrd and it must be copied into the ESP:
root #cp /path/to/my/initramfs/myinitrd.cpio.gz /efi/EFI/example/initrd.cpio.gzNow the kernel needs its initramfs, and the initramfs needs its root; UEFI must provide both:
root #efibootmgr -c -d /dev/sda -p 1 -L "Gentoo EFI Stub" -l '\EFI\example\bzImage.efi' -u 'root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx initrd=\EFI\example\initrd.cpio.gz'A Forum post explains in more detail, solving some user errors in the process: Forums topic - Booting UEFI without Grub
When using Early Userspace Mounting, the Generating the Initramfs and Using a Stub Kernel sections also provide a more thorough explanation.
Optional: Embedded initramfs
It's also possible to embed the initramfs directly into the kernel. Advantages include: the initramfs being verified by Secure Boot when verifying the kernel, a simplified boot process and EFI partition, and making loading the kernel by hand easier (because callers needn't specify the initramfs). Disadvantages include reduced flexibility, potential mistakes, and an unconventional boot setup.
If your initramfs contains Microcode, it is critical (for security) that it receives updates; when embedded, the initramfs can't update independently of the kernel and a kernel rebuild will be necessary every time the initramfs is updated. In particular, please ensure that if:
root #make cleanroot #rm usr/initramfs_data.cpio- When the initramfs has an update, the kernel is rebuilt and reinstalled.
- If the initramfs is managed by sys-apps/portage, it is updated before the kernel.
The kernel supports both CPIO files (e.g., as produced by Dracut) and source directories (which are to be compressed into a CPIO archive). The following shows the latter with /usr/src/initramfs; however, it should be substituted with /path/to/my/initramfs/myinitrd.cpio.gz if the former case is desired (it usually is, unless using a Custom Initramfs).
General Setup --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
(/usr/src/initramfs) Initramfs source file(s)
EFI configuration
To ensure everything is functioning properly, the kernel may be booted without the initrd command line argument.
To create the UKI entry:
root #efibootmgr --create --disk /dev/sda --label "Gentoo EFI Stub" --loader "\EFI\example\bzImage.efi"Optional: Booting without dedicated UEFI entry
UEFI specifies that when booting from a particular ESP, the default behavior is to load an EFI executable from a specific path, dependent on the host architecture: for example, on an AMD64 system, an EFI stub placed at $(ESP)\efi\boot\bootx64.efi would be automatically loaded when booting from that ESP.
Combined with setting the relevant drive's boot priority, this setup can automatically boot the kernel upon power-on without entering a boot menu whilst still preserving the option to do so if desired.
This can be used to circumvent the use of efibootmgr and the creation of UEFI entries with the cost of less flexibility; it runs the risk of rendering the system unbootable if a new, broken kernel were to be installed to the default path.
Backup kernel
It is recommended to always have a backup kernel; if a bootmanager like grub is already installed, it should not be uninstalled because grub can boot a stub kernel just like a normal kernel. Another possibility working with an additional UEFI entry: before installing a new kernel, the current one can be copied from /efi/EFI/example to /efi/EFI/backup. In the example below, other names were used and the second UEFI entry was created with efibootmgr:
root #efibootmgrBootCurrent: 0002 Timeout: 1 seconds BootOrder: 0002,0000,0001 Boot0000* Secure HD(1,GPT,0adcbfee-21aa-42ea-9a9a-2e53bd05e6a2,0x800,0x7f800)/File(\EFI\secure\bzImage.efi) Boot0001* gentoo HD(1,GPT,0adcbfee-21aa-42ea-9a9a-2e53bd05e6a2,0x800,0x7f800)/File(\EFI\gentoo\grubx64.efi) Boot0002* Backup HD(1,GPT,0adcbfee-21aa-42ea-9a9a-2e53bd05e6a2,0x800,0x7f800)/File(\EFI\backup\bzImage.efi)
Microcode loading
When using a kernel without an initramfs, it is recommended to load the microcode described in the following articles:
Optional: Signing for Secure Boot
If Secure Booting this kernel, it must be signed with sbsign, part of app-crypt/sbsigntools:
root #sbsign --key {db key} --cert {db cert} /efi/EFI/example/bzImage.efiMore information is available at Secure Boot.
It is not possible to EFI Stub boot via sys-boot/shim due to the vanilla EFI Stub missing the required .sbat sbat section; as such, the used signing keys must be registered directly with the UEFI firmware to EFI Stub boot with Secure Boot enabled. See the UKI wiki page for an alternate EFI Stub boot method that supports booting via shim.
Troubleshooting
Some rare UEFI implementations do not accept individual EFI entries; in this case, it often works to use the removable media boot path, see EFI System Partition #removable media for details. For example, this command will copy the kernel for an amd64 UEFI:
root #cp /usr/src/linux/arch/x86/boot/bzImage /efi/EFI/boot/bootx64.efiIf command /usr/lib/kernel/postinst.d/95-efistub-uefi-mkconfig.install fails during the first install (no EFI kernel found), use mkdir /efi/Gentoo to create an empty folder.
- Older kernels compiled with gcc:10 crashed at boot (bug #721734#c4).
- Users of sys-kernel/gentoo-kernel-bin can specify the root partition path with the
root=parameter using efibootmgr:
root #efibootmgr -c -L "Gentoo Linux" -l '\EFI\Gentoo\bootx64.efi' -u 'root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' - To create a boot entry with hibernation on swap partition:
root #efibootmgr -c -L "Gentoo Linux" -l '\EFI\Gentoo\bootx64.efi' -u 'root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX resume=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' 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.
- Architecture specific kernel configuration (AMD64 Handbook)
- REFInd — a boot manager for UEFI platforms.
- Unified Kernel Image — a single executable which can be booted directly from UEFI firmware, or automatically sourced by boot-loaders with little or no configuration.
External resources
- Linux Kernel Documentation on EFI Stub
- EFI Stub - booting without a bootloader Blog posting which this article is partially based on.
- EFI bootloaders listing alternative ways to boot a UEFI system.
- Gentoo Forums: Suspend and Hibernate with UEFI
- http://www.kroah.com/log/blog/2013/09/02/booting-a-self-signed-linux-kernel/