CRUX : Home

Home :: Documentation :: Download :: Development :: Community :: Wiki :: Ports :: Bugs :: Links :: About

Back to wiki start page

Categories: Install

How to boot CRUX via UEFI

Authors: Thomas Penteker, Matt Housh


Overview

UEFI (Unified Extensible Firmware Interface) is a replacement for the BIOS (Basic Input/Output System) used by most IBM-compatible PCs. Much more detail can be found on Wikipedia's UEFI Page or at the Unified Extensible Firmware Inteface Forum.

This document details how to boot CRUX using UEFI.

Installation Support

CRUX 3.2 and later support native UEFI installation. More detail about boot loaders can be found in the later "Boot Loaders" section of this page.

Disk Label/EFI System Partition

While the UEFI specification supports both MBR (msdos) and GPT disk labels, GPT is the preferred choice. Some manufacturers' (HP's, for example) UEFI implementations will not boot a UEFI system from an MBR-partitioned drive. If dual-booting with Windows it's important to note that Windows also requires a GPT disk label to boot in UEFI mode.

Creating a GPT disk label can be done easily with either parted or gdisk (also known as gptfdisk). gdisk automatically converts MBR disk labels to GPT when run. To create a GPT disk label in parted use the mklabel command before defining partitions:

(parted) mklabel gpt

In addition to the usual partitions created during an install, an ESP (EFI System Partition) is required. It should be formatted with a FAT12, FAT16, or FAT32 filesystem. It doesn't need to be very large, just large enough to comfortably house your kernel/initrd images and whatever UEFI executables and helper files are needed. Some common sizes are 100MiB, 128Mib, 200Mib, or 256MiB.

Here's an example GPT partition layout with partition sizes displayed in sectors:

Model: ATA OCZ-VERTEX2 (scsi)
Disk /dev/sda: 234441648s
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start     End         Size        File system     Name     Flags
 1      2048s     264191s     262144s     fat16           primary  boot
 2      264192s   4458495s    4194304s    linux-swap(v1)  primary
 3      4458496s  234440703s  229982208s  ext4            primary

Here's the same layout with sizes displayed in MiB:

Model: ATA OCZ-VERTEX2 (scsi)
Disk /dev/sda: 114473MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start    End        Size       File system     Name     Flags
 1      1.00MiB  129MiB     128MiB     fat16           primary  boot
 2      129MiB   2177MiB    2048MiB    linux-swap(v1)  primary
 3      2177MiB  114473MiB  112296MiB  ext4            primary

On this example system the ESP is 128MiB in size. It was formatted using dosfstools' mkfs.fat program with no special arguments. While the ESP in this example is the first partition on the drive, that is not a hard requirement of the UEFI specification. Microsoft does recommend it be the first partition for Windows installations so keep that in mind if dual-booting.

Kernel Configuration

There are several UEFI-related options that need to be enabled in the kernel for full support. They are:

-*- Enable the block layer  --->
   Partition Types  --->
      [*]   EFI GUID Partition support
Processor type and features  --->
   [*] EFI runtime service support
This option is required if EFI stub support is desired in lieu of one of the more traditional boot loaders OR if syslinux is used. See the EFI stub notes in the "Boot Loaders" section below.
Processor type and features  --->
   [*] EFI runtime service support
      [*]   EFI stub support
NOTE: This option can be builtin (<*>) or module (<M>). If you build it as a module, be sure to load the 'efivarfs' module before attempting to edit UEFI boot entries.
File systems  --->
   Pseudo filesystems  --->
      <*> EFI Variable filesystem
Device Drivers  --->
   Graphics support  --->
      <*> Support for frame buffer devices  --->
         [*]   EFI-based Framebuffer Support
      Console display driver support  --->
         <*> Framebuffer Console support
         [*]   Map the console to the primary display device

Please note that some of these options can technically be compiled as modules but it is NOT recommended due to the extra requirements that adds such as an initrd or initramfs to load the GPT partition support and EFI frame buffer early.

Boot Loaders

EFI stub is technically not a boot loader. Instead it's a kernel option added in Linux 3.3 that allows a kernel image to be loaded directly, bypassing a traditional UEFI boot loader. This option requires the EFI stub support mentioned above in the kernel configuration section. If the kernel is compiled with EFI stub support it can be used directly with efibootmgr or the system's UEFI setup utility (if available), see the "EFI Boot Manager" section below for details. In addition another kernel configuration option is required, "Built-in kernel command line (CMDLINE)":
Processor type and features  --->
   [*] Built-in kernel command line
   (root=/dev/sda3 ro quiet) Built-in kernel command string
The string section between parentheses should be populated with the proper command line boot string. Without this specified the system will most likely NOT boot! The above string is correct for the example system used here.
NOTE: GRUB2 does NOT require kernel/initrd/initramfs images to be located in the ESP!
Install grub2-efi from the opt collection. Once installed, grub2-efi can be configured like so:
If the ESP has not been mounted yet, do so:
# mkdir /boot/efi
# mount /dev/sdXY /boot/efi
NOTE: Replace /dev/sdXY with your ESP device.
Install GRUB2 into the ESP:
# grub-install /boot/efi
The grub-install utility will install the UEFI executable into the ESP and add a grub entry to the UEFI boot order using efibootmgr. It will NOT automatically create a config file for you (it used to do this in the past).
NOTE: This means you can skip the 'EFI Boot Manager' section below.
Once the UEFI executable and boot entry are created, a configuration file is required. One can be automatically generated using the grub-mkconfig utility like so:
# grub-mkconfig -o /boot/grub/grub.cfg
If preferred, a grub.cfg file can be constructed manually but that's beyond the scope of this document. See the GNU GRUB Manual for more information.
NOTE: EFI stub support (see "EFI stub support (CONFIG_EFI_STUB)" in the "Kernel Configuration" section above) is required for syslinux to boot a kernel properly! Without it, attempting to boot a kernel will cause the screen to blank and the system to reboot.
NOTE: Syslinux requires kernel/initrd/initramfs images to be located in the ESP!
Install syslinux from the opt collection. Once installed, syslinux can be configured like so:
If the ESP has not been mounted yet, do so:
# mkdir /boot/efi
# mount /dev/sdXY /boot/efi
NOTE: Replace /dev/sdXY with your ESP device.
Install syslinux into the ESP:
# mkdir /boot/efi/EFI
# cp -a /usr/share/syslinux/efi64 /boot/efi/EFI/syslinux
Create a UEFI boot entry, for example:
# efibootmgr -c -d /dev/sda -l "\EFI\syslinux\syslinux.efi" -L "syslinux" -p 1
See the "EFI Boot Manager" section below for more details on efibootmgr usage.
Once the UEFI executable is installed and a boot entry created, a configuration file is required. Create a syslinux.cfg file with your preferred text editor in the same directory as syslinux.efi, in this case /boot/efi/EFI/syslinux/syslinux.cfg. An example configuration might look like this:
DEFAULT crux
TIMEOUT 30
UI menu.c32

LABEL crux
    MENU LABEL CRUX 3.7
    LINUX ../../vmlinuz-5.15.79
    APPEND root=/dev/sda3 ro quiet
In this example the kernel is located at /boot/efi/vmlinuz-5.15.79 which is up two filesystem levels relative to the location of syslinux.efi (/boot/efi/EFI/syslinux/syslinux.efi), thus using the path ../../vmlinuz-5.15.79.
This is just a simple example. See the upstream Syslinux documentation for more details on the configuration file format and options.

EFI Boot Manager

Once the preferred UEFI boot loader (or EFI stub support) is installed and configured, the system's UEFI needs to know how to launch it. There are 2 main methods for configuring the system UEFI's boot options:
Some hardware manufacturers include a boot option editor/manager in their UEFI setup utility (UEFI equivalent to the BIOS setup on a BIOS system). These are sometimes referred to as "UEFI boot managers" but should not be confused with the "efibootmgr" software discussed below. These vary by manufacturer of the hardware or UEFI implementation so check the motherboard manual or documentation for more information specific to the system in use. An example from a SuperMicro server looks like this:
SuperMicro/Aptio UEFI setup utility image
If the system in use does not ship with a UEFI boot option manager in the setup utility or for some reason an alternative is needed/desired, use efibootmgr. It's a command-line utility that displays, creates, alters, and deletes UEFI boot options.
efibootmgr also relies on the aforementioned EFI variable filesystem support (CONFIG_EFIVAR_FS) kernel configuration option to work properly. Use the following command to mount it manually:
# mount -t efivarfs none /sys/firmware/efi/efivars
A line like the following can be used in /etc/fstab to mount it automatically:
none /sys/firmware/efi/efivars efivarfs defaults 0 0
Without any arguments efibootmgr displays the current configuration. From the example system used here, it looks like this:
# efibootmgr
BootCurrent: 0000
Timeout: 3 seconds
BootOrder: 0007
Boot0007  UEFI: Built-in EFI Shell
NOTE: Some systems have an EFI shell application, some do not. It is not used in this document.
To create a new UEFI boot option for one of the traditional boot loaders mentioned earlier, use efibootmgr's -c option. Please note that efibootmgr assumes various default values if their options (notably -d, -l, -L, and -p) are not specified! When in doubt, specify them explicitly. On the example system used here this creates a new entry for GNU GRUB2 using the grub2 UEFI executable:
# efibootmgr -c -l "\efi\grub\grubx64.efi" -L "GNU GRUB2"
BootCurrent: 0000
Timeout: 3 seconds
BootOrder: 0000,0007
Boot0007  UEFI: Built-in EFI Shell 
Boot0000* GNU GRUB2
As shown in the output above, efibootmgr created a new UEFI boot entry with id 0000 and label "GNU GRUB2". More detail can be seen using efibootmgr's -v option if desired. Note that efibootmgr also set BootOrder to 0000,0007 which means that the new entry was automatically placed first in the boot order. Also note that efibootmgr's -d and -p options were not specified because the defaults (/dev/sda for -d and 1 for -p) were valid for the example system. The path specified with the -l option is relative to the root of the ESP's filesystem rather than the main Linux root filesystem and backslashes are used instead of forward slashes.
Another example, this time using efibootmgr to add a boot entry for a kernel loaded directly via EFI stub support:
# efibootmgr -c -d /dev/sdb -l "\efi\linux\vmlinuz-3.11.6.efi" -L "Linux 3.11.6 EFI Stub" -p 2
BootCurrent: 0000
Timeout: 3 seconds
BootOrder: 0000,0007
Boot0007  UEFI: Built-in EFI Shell 
Boot0000* Linux 3.11.6 EFI Stub
In the above example the -d and -p options were explicitly specified. This example created a UEFI boot entry with id 0000 and label Linux 3.11.6 EFI Stub. The compiled kernel image was copied (by the user, not efibootmgr) to the ESP's filesystem as "vmlinuz-3.11.6.efi" in a "/efi/linux" folder structure. The ESP in this case is the second partition of the second disk (/dev/sdb2).