EFI stub kernel

From Gentoo Wiki
Jump to: navigation, search

The (U)EFI firmware present in many newer computers can function as bootloader, allowing systems to boot without needing an additional software bootloader.

It should be noted that EFI stub kernels can not load an initramfs if it is specified in CONFIG_CMDLINE. Check out efibootmgr, CONFIG_INITRAMFS_SOURCE or a separate bootloader (gummiboot/GRUB2) if an initramfs is a must-have.


Create a partition of type "EFI System partition", which is EF00 on GPT and EF on MBR. Using gdisk:

root #gdisk /dev/sda
Command (? for help): n
Partition number (1-128, default 1): 1
First sector: (enter desired start sector and size, 100 MB should be plenty)
Command (? for help): t
Partition number (1-2): 1
Hex code or GUID (L to show codes, Enter = 8300): EF00
Command (? for help): w

Create a FAT32 filesystem inside:

root #mkfs.vfat -F 32 /dev/sda1

If the mkfs.vfat command is not present (part of sys-fs/dosfstools), the Busybox version can be used instead:

root #busybox mkfs.vfat /dev/sda1
The gdisk utility comes with the sys-apps/gptfdisk package.



In order to boot directly from UEFI, the kernel needs to have CONFIG_EFI_STUB support enabled:

KERNEL Enable EFI stub support
Processor type and features  --->
    [*] EFI runtime service support 
    [*]   EFI stub support

UEFI does not pass kernel parameters to the kernel during normal boot, so they must be hardcoded them via CONFIG_CMDLINE. to boot a root partition located at /dev/sda2 input the following text in the kernel configuration:

KERNEL Enable built-in kernel parameters
Processor type and features  --->
    [*] Built-in kernel command line

For GPT systems, using root=PARTUUID= might be preferable. To find out use gdisk:

root #gdisk /dev/sda
Command (? for help): i
Partition number (1-5): 2
Partition unique GUID: (pass the ID that is shown here to the kernel)
Command (? for help): q
The partition's UUID is distinct from the filesystem's UUID.


EFI Stub can load an initramfs and pass it to the kernel, but this requires passing a parameter from the EFI bootloader (ie. initrd=\efi\boot\myinitrd.img). This parameter cannot be built into CONFIG_CMDLINE as outlined above. This may defeat the purpose of using EFI stub since many users prefer it as a way to avoid the necessity of a bootloader and/or dealing with efibootmgr. Another possibility is to embed the initramfs directly into the kernel image. In order to do this:

  • Generate the initramfs using a preferred method (Genkernel, Dracut, etc.);
  • Ensure the image is not compressed (just a cpio archive). Genkernel and Dracut both have command line switches for this;
  • Rename the initramfs with a .cpio extension, the kernel requires this to embed a cpio archive. The kernel image (with the cpio archive within it) will still be compressed as usual.
  • Ensure that the initramfs has the correct read-permissions for the user building the kernel. Most users build the kernel as the root user and may skip this step.
    • Be aware that Dracut makes the initramfs image readable only by the root user, so if the kernel was built as any other user adjust its permissions as needed. Failing to do so (and ignoring the kernel build warnings) will result in a kernel with no embedded initramfs which will leave the system potentially unbootable.
KERNEL Build in the initramfs CPIO archive
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    (/boot/initramfs-3.12.21-gentoo-r1.cpio) Initramfs source file(s)
  • Install the kernel on the EFI partition.

However, if passing an initramfs as a boot parameter is still desired, the only way it can be done is by using efibootmgr (GRUB2 will not work). An external initramfs has some advantages over building the initramfs directly into the kernel (see the kernel help on CONFIG_INITRAMFS_SOURCE for details on its limitations). In fact, both a built-in and external initramfs can be used simultaneously. Create and install the initramfs with Genkernel, Dracut, by hand, etc. Install the kernel as outlined in the Installation section below. Then:

root #cp /boot/vmlinuz-3.14.14-gentoo /mnt/EFI/EFI/Boot/bootx64.efi
root #cp /boot/initramfs-3.14.14-gentoo.img /mnt/EFI/EFI/Boot/initramfs.img
root #efibootmgr --create --part 1 --label "Gentoo" --loader '\efi\boot\bootx64.efi' -u initrd='\efi\boot\initramfs.img'
  • EFI uses \ (backslash) as path separators.
  • The system tested on required the kernel arguments to be passed as Unicode text (-u option). YMMV.


Now build the kernel and copy the image to the EFI partition as EFI/Boot/bootx64.efi. The following example shows the EFI partition mounted to /mnt/EFI):

root #cd /usr/src/linux
root #make -jN
root #make install modules_install
root #mkdir -p /mnt/EFI/EFI/Boot
root #cp /boot/vmlinuz-3.7.9-gentoo /mnt/EFI/EFI/Boot/bootx64.efi

Adding additional kernels

In order to modify UEFI boot entries, the system needs to be booted in EFI mode. This means that the EFI stub image or some EFI capable live media must have been booted as described above.

Optionally additional kernels can be made known to the UEFI firmware. This is especially useful when wanting to test more kernels or to dual-boot with another operating system. These will be shown in the boot selection prompt, normally after a keyboard hotkey is pressed at the right time during system initialization. If the hotkey combination is unknown, search for official documentation from the computer manufacture. This information is usually not difficult to find.

Ensure that CONFIG_EFI_VARS have been enabled in the kernel, install sys-boot/efibootmgr and make them known to the UEFI firmware.

KERNEL Enable EFI sysfs controls
Firmware Drivers  --->
    <*> EFI Variable Support via sysfs
root #cp /boot/vmlinuz-3.6.11-gentoo /mnt/EFI/EFI/Boot/vmlinuz.efi
root #efibootmgr --create --part 1 --label "Gentoo" --loader '\efi\boot\vmlinuz.efi'
EFI uses \ (backslash) as path separators.

See also

External resources