Published on 02 November 2024 by Jing Huang.
In order to boot the Linux kernel, one traditionally needs a bootloader like Grub or chainloader like rEFInd. However, these are ugly (text-only ones look alright, but graphic ones with low resolution images really don’t look good), slow and no longer necessary.
Modern PC comes with UEFI support, which enables us to directly load kernel images from the EFI partition without the need for any bootloader or chainloaders.
You should enable native EFI support and EFI stub support for the kernel.
|Processor type and features --->|[*] EFI runtime service support|[*] EFI stub support|[ ] EFI mixed-mode support
You are also recommended to embed the root partition information into the kernel.
|Processor type and features --->|[*] Built-in kernel command line|(root=/dev/nvme0n1p3)
Rebuild the kernel and install the kernel modules.
|make -j && make modules_install
An initramfs regeneration might be necessary. For example if you embedded the root partition information into the kernel, or if you use BTRFS subvolumes.
Create an EFI system partition if you don’t have one. This ESP should then be mounted at /efi. Then
make the below directory structure:
|/efi|└── EFI|└── Gentoo|├── initramfs.img5 |└── bzImage.efi
The bzImage.efi should be copied from /usr/src/linux/arch/x86/boot/bzImage. The
initramfs.img is optional, copied from the initramfs only when needed.
There can be more than one subdirectories containing stub images for more than one system inside the
EFI directory.
The tool we use to create and manage the boot entries requires the EFI variables filesystem to be accessible (i.e., properly mounted).
Run the following command to check if it is mounted properly:
|mount | grep efivars
If it is mounted as ro, remount it with rw so that we can create and modify EFI boot
entries.
First execute efibootmgr without any options to list the existing boot entries. Remove unnecessary or
obsolete ones with:
|efibootmgr -b 2 -B # select the `Bootx002' entry and remove it
Then create an entry for our system.
|efibootmgr -c -d /dev/nvme0n1 -p 2 -L "Linux EFI Stub" -l '\EFI\gentoo\bzImage.efi' -u 'root=/dev/nvme0n1p3' # without initramfs|efibootmgr -c -d /dev/nvme0n1 -p 2 -L "Linux EFI Stub" -l '\EFI\gentoo\bzImage.efi' -u 'initrd=\EFI\gentoo\initramfs.img' # with initramfs
After checking if the system can successfully boot, you can unmerge efibootmgr. Just copy new kernel
images and initramfs to the same position on the EFI partition.
If you encountered the common VFS: Cannot open root device or unknown block
error, don’t panic.
root=/dev/<block> using -u option of
efibootmgr or the kernel built-in command line. An initramfs generated by for instance dracut might
also contain one.UUID, you need
an initramfs.rootwait option if an initramfs is not used and the root filesystem is on an MTD device
(such as an NVME drive) to make the kernel wait for asynchronous initialization of the device.