Originally written: 3/11/2011; last update: 7/16/2017
This Web page is provided free of charge and with no annoying outside ads; however, I did take time to prepare it, and Web hosting does cost money. If you find this Web page useful, please consider making a small donation to help keep this site up and running. Thanks!
|Donate $1.00||Donate $2.50||Donate $5.00||Donate $10.00||Donate another value|
This page is part of my Managing EFI Boot Loaders for Linux document. If a Web search has brought you to this page, you may want to start at the beginning.
In late 2011, Linux kernel developers began work on a new way to boot Linux on EFI-based systems. This approach turns the Linux kernel into an EFI application. Once loaded, the kernel takes over the computer, effectively bypassing the need for a boot loader in the strictest sense. This approach has its own unique advantages and disadvantages, as detailed on this page. (If you're interested in the technical details, you can read about them in the Linux Kernel Mailing List thread on this topic.)
The Linux kernel's EFI stub loader has a number of unique features. Some are positive, some are negative, and some can be either:
As a practical matter, this approach works well for most recent distributions. The EFI stub loader works best in conjunction with the rEFInd or gummiboot/systemd-boot boot manager, which can specify the extra options that the Linux kernel requires when booted in this way, thus eliminating the awkwardness of having to type options every time you boot. In fact, as described on the rEFInd page, the combination of rEFInd and the EFI stub loader can enable you to upgrade your kernel in a drag-and-drop fashion, without having to edit any configuration files!
Installing the EFI stub loader entails configuring your 3.3.0 or later kernel and compiling it (or obtaining a suitably pre-configured kernel) and then installing the kernel on your ESP (or on some other EFI-accessible partition) in the usual way for an EFI boot loader. If you need help compiling your own kernel, consult a Web page on the topic, such as How to: Compile Linux Kernel 2.6 or Compiling the Linux Kernel. If you've never done it before, be aware that the worst part of the task is sifting through the thousands of kernel options to decide what you need. A generic kernel configuration file can be handy; it will set the options that will work on most computers, similar to what distribution providers use. You should pay attention to one, or possibly two, kernel configuration options:
Both of these features are highlighted (via GIMP trickery) in the below make xconfig screen shot:
With the kernel compiled, you should install its modules in the usual way (by typing make modules_install) and prepare an initial RAM disk in the usual way (using mkinitrd or mkinitramfs, typically—details vary from one distribution to another). Instead of (or in addition to) copying your kernel file and initial RAM disk to the Linux /boot directory, though, you should copy these files to your ESP. For instance, you might use the EFI/linux subdirectory on the ESP to hold these files.
The kernel's stub loader requires no configuration per se, although building options into it may be desirable in some cases. When compiled without them, you must know how to pass it options that you would normally pass it on an options line in a boot loader. You must also pass it the name of the initial RAM disk, if you use one. The resulting command, typed at an EFI shell, might look like this:
fs0:> bzImage.efi root=/dev/sda4 ro initrd=\EFI\linux\initrd.img
This is a very minimal example. It assumes that you've called the kernel file bzImage.efi, that your root Linux filesystem is on /dev/sda4, and that the initial RAM disk is stored in the ESP's EFI/linux/initrd.img file. The ro option tells Linux to mount the root filesystem read-only. (This is standard; initialization scripts later re-mount the filesystem read/write.) Note that the root= option identifies the Linux root filesystem using Linux-style forward slashes (/) to separate directory elements, and relative to the Linux root (/) filesystem; but the initrd= specification uses EFI-style backslashes (\) and identifies the initial RAM disk relative to the ESP's root. This is extremely important; an incorrect initrd= specification causes the kernel to hang. With early versions of the EFI stub loader (3.3.0 through at least 3.4.0), there were no error messages. With more recent versions (as of 3.6.0, and perhaps 3.5.x kernels), the kernel displays an error message when it can't read its initrd file.
EFI implementations include their own boot managers, but they're usually quite primitive. Nonetheless, if yours enables you to choose a boot loader, or if you're satisfied with always booting just one kernel, you can set it up with the efibootmgr program in Linux. You can do this with a command like the following:
# efibootmgr -c -d /dev/sda -p 1 -L "Arch Linux" -l '\EFI\arch\vmlinuz-arch.efi' -u root=/dev/sda3 ro initrd=EFI/arch/initramfs-arch.img
This command tells the EFI to boot the \EFI\arch\vmlinuz-arch.efi file using the arguments specified following the -u option. The -d and -p options are theoretically unnecessary if you use /dev/sda1 as your ESP; I've included them in this example in case your ESP is elsewhere and you need to change them. If your EFI implementation supports a decent boot menu, you can use multiple commands like this to create alternative boot options—say, to boot different kernels, multiple distributions, or using alternate options.
If you're using a separate EFI boot manager program, such as rEFInd or gummiboot, you can look into configuring it to pass the necessary options to the kernel. As already noted, this isn't possible with rEFIt. My fork of rEFIt, rEFInd, supports two ways of passing options to the EFI stub loader: You can write boot loader stanza definitions in the main refind.conf file; or you can rely on semi-automated discovery that reads options for all kernels in a directory from a file called refind_linux.conf. Either approach can make the combination of this kernel support and rEFInd a flexible and relatively easy-to-maintain combination in a multi-boot environment; however, you may need to do at least a little manual maintenance. gummiboot/systemd-boot requires a separate configuration file for each of its main-menu options. Few or no distributions support it with maintenance scripts, so you'll have to maintain it manually.
It's theoretically possible to launch a Linux kernel compiled with EFI stub support from GRUB Legacy or GRUB 2 using their chainloader option rather than their kernel or linux options. (I've not tried this, though.) Using chainloader might provide advantages if you're having problems with hardware initialization when launching in the usual way; however, I can make no promises about that.
EFI drivers for ext2fs/ext3fs, ext4fs, ReiserFS, and others are available, which makes it possible to load a Linux kernel with EFI stub support from a Linux filesystem. This could simplify configuration in some environments, since you won't need to copy the kernel to the ESP, although you might need to rename it or create a link to the kernel with an extension of .efi. This page describes using EFI drivers, with an emphasis on configuring rEFInd to load them.
Because the kernel's EFI stub loader is not currently supported by most distributions, you're on your own when it comes to maintenance. In the future, it's possible that distributions will use efibootmgr or other tools to help maintain installations that use this approach, or support it by maintaining the configuration files for GRUB, rEFInd, or gummiboot/systemd-boot. Because rEFInd requires little or no maintenance when you add new kernels, the maintenance needs for the combination of the EFI stub loader and rEFInd are quite low.
Go on to "Using rEFIt"
Return to "Managing EFI Boot Loaders for Linux" main page
If you have problems with or comments about this web page, please e-mail me at firstname.lastname@example.org. Thanks.
Return to my main Web page.