EFISTUB
The Linux kernel supports EFISTUB booting which allows EFI firmware to load the kernel as an EFI executable. The option is enabled by default on Arch Linux kernels, or if compiling the kernel one can activate it by setting CONFIG_EFI_STUB=y
in the Kernel configuration. See The EFI Boot Stub for more information.
With EFISTUB a kernel can be booted directly by a UEFI motherboard or indirectly using a boot loader. Using a boot loader is recommended if you have multiple kernel/initramfs pairs and your motherboard's UEFI boot menu is not easy to use.
Preparing for EFISTUB
First, you must create an EFI system partition and choose how it is mounted. See EFI system partition#Mount the partition for all available ESP mounting options.
Booting EFISTUB
esp/EFI/arch/initramfs-linux.img
, the corresponding UEFI formatted line should be initrd=\EFI\arch\initramfs-linux.img
. In the following examples we will assume that everything is under esp/
.Using UEFI directly
UEFI is designed to remove the need for an intermediate bootloader such as GRUB. If your motherboard has a good UEFI implementation, it is possible to embed the kernel parameters within a UEFI boot entry and for the motherboard to boot Arch directly. You can use efibootmgr or UEFI Shell v2 to modify your motherboard's boot entries.
efibootmgr
To create a boot entry with efibootmgr that will load the kernel:
# efibootmgr --create --disk /dev/sdX --part Y --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=block_device_identifier rw initrd=\initramfs-linux.img'
or create a boot entry with efibootmgr and hibernation on swap partition:
# efibootmgr --create --disk /dev/sdX --part Y --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=block_device_identifier resume=block_device_identifier rw initrd=\initramfs-linux.img'
Where and are the drive and partition number where the ESP is located. Change the and parameters to reflect your Linux root and swap partitions.
If omitted, then the first partition on /dev/sda
is used as the ESP.
Note that the -u
/ argument in quotes is just the list of kernel parameters, so you may need to add additional parameters (e.g. for suspend to disk or microcode).
After adding the boot entry, you can verify the entry was added properly with:
# efibootmgr --unicode
To set the boot order:
# efibootmgr --bootorder XXXX,XXXX --unicode
Where XXXX is the number that appears in the output of efibootmgr command against each entry.
bcfg
Some UEFI implementations make it difficult to modify the NVRAM successfully using efibootmgr. If efibootmgr cannot successfully create an entry, you can use the bcfg command in UEFI Shell v2 (i.e., from the Arch Linux live iso).
First, find out the device number where your ESP resides with:
Shell> map
In this example, is used as the device number. To list the contents of the ESP:
Shell> ls FS1:
To view the current boot entries:
Shell> bcfg boot dump
To add an entry for your kernel, use:
Shell> bcfg boot add N FS1:\vmlinuz-linux "Arch Linux"
Where is the location where the entry will be added in the boot menu. 0 is the first menu item. Menu items already existing will be shifted in the menu without being discarded.
Add the necessary kernel options by creating a file on your ESP:
Shell> edit FS1:\options.txt
In the file, add the boot line. For example:
root=/dev/sda2 ro initrd=\initramfs-linux.img
Press to save and then to exit.
Add these options to your previous entry:
Shell> bcfg boot -opt N FS1:\options.txt
Repeat this process for any additional entries.
To remove a previously added item do:
Shell> bcfg boot rm N
kesboot
You can also simplify and automate the work with EFISTUB using a script from the package. It also contains a pacman hook that can add and remove EFI variables during actions with packages.
First, install the package, and then configure the file:
/etc/kesboot.conf
CMDLINES=('linux' 'acpi=on' 'linux-zen' 'iommu=off')
INSTALL_HOOK
and REMOVE_HOOK
), then it will overwrite the CMDLINES
array every time it runs (preserving the contents of all records).Then, execute
# kesboot -u
The package also contains a program for the initial configuration of the EFI boot. After mounting the ESP directory, run
# /usr/lib/setup-efi-boot
Using UEFI Shell
If you do not want to create a permanent boot entry it is possible to launch the kernel from UEFI Shell since it is a normal UEFI application:
> FS0: > \vmlinuz-linux root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rw initrd=\initramfs-linux.img
In this case, the kernel parameters are passed as normal parameters to the launched EFISTUB kernel file.
To avoid needing to remember all of your kernel parameters every time, you can save the executable command to a shell script such as on your UEFI System Partition, then run it with:
> FS0: > archlinux
Using a startup.nsh script
Some UEFI implementations do not retain EFI variables between cold boots (e.g. VirtualBox before version 6.1) and anything set through the UEFI firmware interface is lost on poweroff.
The UEFI Shell Specification 2.0 establishes that a script called at the root of the ESP partition will always be interpreted and can contain arbitrary instructions; among those you can set a bootloading line. Make sure you mount the ESP partition on and create a script that contains a kernel bootloading line. For example:
vmlinuz-linux rw root=/dev/sdX [rootfs=myfs] [rootflags=myrootflags] \ [kernel.flag=foo] [mymodule.flag=bar] \ [initrd=\intel-ucode.img] initrd=\initramfs-linux.img
This method will work with almost all UEFI firmware versions you may encounter in real hardware, you can use it as last resort. The script must be a single long line. Sections in brackets are optional and given only as a guide. Shell style linebreaks are for visual clarification only. FAT filesystems use the backslash as path separator and in this case, the backslash declares the initramfs is located in the root of the ESP partition. Only Intel microcode is loaded in the booting parameters line; AMD microcode is read from disk later during the boot process; this is done automatically by the kernel.
Troubleshooting
Boot entries are randomly removed
Some motherboards may remove boot entries due to lack of free space in the NVRAM instead of giving an error at creation. To prevent this from occurring, reduce the amount of boot entries being added by efibootmgr by minimizing your entry creation process, as well as reducing the amount of automatic drive boot entries by the Compatibility Support Module (CSM) by disabling it from your UEFI settings. See .
EFISTUB does not work on some Dell systems
Several generation Dell firmwares are wrongly passing the arguments to the bootloader, thus making EFISTUB parse a null command line which normally means unbootable system (see the complete linux-efi thread).
A workaround has been found since Linux 5.10 to correct this behavior (see this commit ). For Linux < 5.10, you can use an efi-packer like arch-efiboot, or a different bootloader.
Changes to boot entries are not applied
Some motherboards, such as Haswell-era Asus boards (as encountered on the french forum), will not notice changes to boot entries unless the system is booted with another pre-existing boot entry before booting the updated EFISTUB entry.