EFI stub

From Gentoo Wiki
(Redirected from EFI stub kernel)
Jump to:navigation Jump to:search
Other languages:
Resources
This article has some todo items:
  • CONFIG_PM_STD_PARTITION for hibernation

The (U)EFI firmware present in many computers functions as a boot manager, allowing systems to boot by the use of a compatible EFI bootloader. By making the Linux kernel itself such a bootloader, called an EFI stub. This configuration boots without the need for secondary bootloader. This article provides instructions on configuring and installing kernels in the EFI System Partition (ESP) of a computer running in EFI mode.

Kernel configuration

EFI stub support

The following kernel configuration options must be enabled:

KERNEL Enable EFI stub support for Kernels 6.1+
Processor type and features  --->
    [*] EFI runtime service support
    [*]     EFI stub support
    [ ]     EFI mixed-mode support (OPTIONAL)
Note
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.
Note
For Distribution kernels (except gentoo-kernel-bin) the kernel settings go to savedconfig or /etc/kernel/config.d.

Root partition configuration

In order to boot directly from UEFI, the kernel or its initramfs needs to know where to find the root partition of the system to be booted. When using a bootmanager like grub the kernel gets its information where to find its root partition from the bootmanager via command line parameter. When using a stub kernel two options can be used to give the kernel this information - choose one of these options:

Option 1: Configuring it into the kernel

KERNEL Root Partiton information for Kernels 6.1+
Processor type and features  --->
    [*] Built-in kernel command line
    (root=PARTUUID=adf55784-15d9-4ca3-bb3f-56de0b35d88d ro)
Important
The value adf55784-15d9-4ca3-bb3f-56de0b35d88d is an example and must be replaced with the value of the real root partition. It 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"
The partition's PARTUUID is distinct from the filesystem's UUID. The UUID refers to the unique filesystem partition and must be used with a initramfs, while the PARTUUID refers to the disk partition and can be used when booting a kernel.

Option 2: Configuring it into UEFI

To add an entry with kernel command line arguments:

root #efibootmgr --create --disk /dev/sda --label "Gentoo EFI Stub" --loader "\EFI\example\bzImage.efi" -u "root=/dev/sda3"
Important
Setting the root location using a PARTUUID, or (filesystem) UUID when using a initramfs, is generally preferable and less error prone.

Installation

Kernel

Tip
Optional: If an EFI System Partition (ESP) does not exist, please follow the steps to set it up first.

With the kernel configured with EFI Stub support (assuming that ESP is mounted at /efi). In some systems /efi/efi already exists and must then be used (in lowercase). It is recommended to create a separate directory below /efi/EFI (or /efi/efi if already exist). In the following the name example is used:

root #mkdir -p /efi/EFI/example

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.efi
Tip
It is recommended when upgrading the kernel to keep an older version which is proven to work:
user $tree -L 3 /efi
 /efi
 └── EFI
     └── example
         ├── bzImage-6.1.67.efi
         └── bzImage-6.1.70.efi

EFI firmware configuration

With the kernel file at /efi/EFI/example/bzImage.efi, a boot entry can be added with:

root #efibootmgr --create --disk /dev/sda --label "Gentoo EFI Stub" --loader "\EFI\example\bzImage.efi"

More examples can be found in efibootmgr.

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 witn sbsign, part of app-crypt/sbsigntools:

root #sbsign --key {db key} --cert {db cert} /efi/EFI/example/bzImage.efi

More information is available at Secure Boot.

Additional: Kernel with initramfs

When using a kernel with an external initramfs (as CPIO archive) additional steps are necessary. There is always an initramfs file when building a dist-kernel or when 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. This file must must be copied also into the ESP:

root #cp /path/to/my/initramfs/myinitrd.cpio.gz /efi/EFI/example/initrd.cpio.gz

Now the kernel needs the information where to find it, and the initramfs needs the information where to find its root partition. UEFI must give both information:

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 Forums post explains it in more detail - and solved some user errors:

Forums topic - Booting UEFI without Grub

When using Early Userspace Mounting the Generating the Initramfs and Using a Stub Kernel sections explains it in more detail.

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 it verifies the kernel, a simplified boot process and EFI partition, and it being easier to load the kernel by hand (because callers no longer need to specify the initramfs). Disadvantages are reduced flexibility, the ease of making a mistake, and using an unconventional boot setup.

Warning
If your initramfs contains Microcode, then it is critical for security that it is receiving updates. When embedded, the initramfs can't be updated 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 clean
    is not being run before rebuilding the kernel,
    root #rm usr/initramfs_data.cpio
    is run to clear the cached initramfs CPIO archive that remains from the last build.
  • When the initramfs has an update, the kernel is rebuilt and reinstalled.
  • If the initramfs is managed by sys-apps/portage, the initramfs is updated before the kernel.

The kernel supports both CPIO files (for example, 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 should be substituted with /path/to/my/initramfs/myinitrd.cpio.gz if the former case is desired (it usually is, unless you are using a Custom Initramfs).

KERNEL Embedding the initramfs into the kernel
General Setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (/usr/src/initramfs) Initramfs source file(s)

To ensure everything is functioning correctly, the kernel may be booted without the initrd command line argument.

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. A second possibility is to work with an additional UEFI entry. Before installing a new kernel, the current one can be copied from /efi/EFI/example/ to /efi/EFI/backup. The second UEFI entry was also created with efibootmgr. In this example, other names were used:

root #efibootmgr
BootCurrent: 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)

Troubleshooting

Tip
Some rare (U)EFI implementations do not accept individual EFI entries. In this case it often works to use the removable media boot path, see Efibootmgr #removable media for details. E.g. this command will copy the kernel for a 64 bit UEFI:
root #cp /usr/src/linux/arch/x86/boot/bzImage /efi/EFI/boot/bootx64.efi
Be advised that this is against the (U)EFI specification, as it will circumvent the (U)EFI boot selection on internal drives (which are configured using EFI boot entries).
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 efibootmgr and 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

External resources

References