Using GRUB to Set Up the Boot Process with UEFI

#### Beyond Linux® From Scratch (systemd Edition) - Version 13.0

### Chapter 5. File Systems and Disk Management

- Prev

  GRUB-2.14 for EFI

- Next

  Text Editors

- Up
- Home

# Using GRUB to Set Up the Boot Process with UEFI

## Turn Off Secure Boot

BLFS does not have the essential packages to support Secure Boot. To set up the boot process with GRUB and UEFI in BLFS, Secure Boot must be turned off from the configuration interface of the firmware. Read the documentation provided by the manufacturer of your system to find out how.

## Kernel Configuration for UEFI support

Enable the following options in the kernel configuration and recompile the kernel if necessary:

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

    -*- Enable the block layer --->                                          [BLOCK]
      Partition Types --->
        [ /*] Advanced partition selection                      [PARTITION_ADVANCED]
        [*]     EFI GUID Partition support                           [EFI_PARTITION]

    File systems --->
      DOS/FAT/EXFAT/NT Filesystems --->
        <*/M> VFAT (Windows-95) fs support                                 [VFAT_FS]
      Pseudo filesystems --->
        <*/M> EFI Variable filesystem                                    [EFIVAR_FS]
      -*- Native language support --->                                         [NLS]
        <*/M> Codepage 437 (United States, Canada)                [NLS_CODEPAGE_437]
        <*/M> NLS ISO 8859-1  (Latin 1; Western European Languages)  [NLS_ISO8859_1]

The meaning of the configuration options:

`CONFIG_PARTITION_ADVANCED`

  If it's not enabled, `CONFIG_EFI_PARTITION` will be enabled automatically. But when it's enabled, you must set `CONFIG_EFI_PARTITION` to enabled as well.

## Create an Emergency Boot Disk

Ensure that an emergency boot disk is ready to “rescue” the system in case the system becomes un-bootable. To make an emergency boot disk with GRUB for an EFI based system, find a spare USB flash drive and create a `vfat` file system on it. Install dosfstools-4.2 first, then as the `root` user:

### Warning

The following command will erase all directories and files in the partition. Make sure your USB flash drive contains no data which will be needed, and change `sdx1` to the device node corresponding to the first partition of the USB flash drive. Be careful not to overwrite your hard drive with a typo!

    mkfs.vfat /dev/sdx1

Still as the `root` user, use the fdisk utility to set the first partition of the USB flash drive to be an “EFI system” partition (change `sdx` to the device node corresponding to your USB flash drive):

    fdisk /dev/sdx

    Welcome to fdisk (util-linux 2.39.1).
    Changes will remain in memory only, until you decide to write them.
    Be careful before using the write command.

    Command (m for help): t
    Partition number (1-9, default 9): 1
    Partition type or alias (type L to list all): uefi
    Changed type of partition 'Linux filesystem' to 'EFI System'.

    Command (m for help): w
    The partition table has been altered.
    Syncing disks.

Still as the `root` user, create a mount point for the EFI partition on the USB flash drive and mount it:

    mount --mkdir -v -t vfat /dev/sdx1 -o codepage=437,iocharset=iso8859-1 /mnt/rescue

Install GRUB for EFI on the partition:

    grub-install --target=x86_64-efi --removable \
                 --efi-directory=/mnt/rescue --boot-directory=/mnt/rescue

Unmount the partition:

    umount /mnt/rescue

Now the USB flash drive can be used as an emergency boot disk on any x86-64 UEFI platform. To learn how to select this flash drive as the boot device, read the manual of your motherboard or laptop. It will boot the system and show the GRUB shell. Then you can type commands to boot your operating system from the hard drive.

## Find or Create the EFI System Partition

On EFI based systems, the bootloaders are installed in a special FAT32 partition called an EFI System Partition (ESP). If your system supports EFI, and a recent version of some Linux distribution or Windows is pre-installed, it's likely that the ESP has already been created. As the `root` user, list all the partitions on your hard drive (replace `sda` with the device corresponding to the appropriate hard drive):

    fdisk -l /dev/sda

The “Type” column of the ESP should be `EFI System`.

If the system or the hard drive is new, or it's the first installation of a UEFI-booted OS on the system, the ESP may not exist. In that case, install dosfstools-4.2 first. Then create a new partition, make a `vfat` file system on it, and set the partition type to “EFI system.” See the instructions for the emergency boot device above as a reference.

### Warning

Some (old) UEFI implementations may require the ESP to be the first partition on the disk.

Now, as the `root` user, create the mount point for the ESP, and mount it (replace `sda1` with the device node corresponding to the ESP):

    mount --mkdir -v -t vfat /dev/sda1 -o codepage=437,iocharset=iso8859-1 /boot/efi

If you want to mount the ESP automatically during system boot, as the `root` user, add an entry for the ESP into `/etc/fstab`:

    cat >> /etc/fstab << EOF
    /dev/sda1 /boot/efi vfat codepage=437,iocharset=iso8859-1 0 1
    EOF

## Minimal Boot Configuration with GRUB and EFI

On UEFI based systems, GRUB works by installing an EFI application (a special kind of executable) into the ESP. The EFI firmware will search boot loaders in EFI applications from boot entries recorded in EFI variables, and additionally a hardcoded path `EFI/BOOT/BOOTX64.EFI`. Normally, a boot loader should be installed into a custom path and the path should be recorded in the EFI variables. The use of the hardcoded path should be avoided if possible. However, in some cases we have to use the hardcoded path:

- The system is not booted with EFI yet, making EFI variables inaccessible.

- The EFI firmware is 64-bit but the LFS system is 32-bit, making EFI variables inaccessible because the kernel cannot invoke EFI runtime services with a different virtual address length.

- LFS is built for a Live USB, so we cannot rely on EFI variables, which are stored in NVRAM or EEPROM on the local machine.

- You are unable or unwilling to install the efibootmgr for manipulating boot entries in EFI variables.

In these cases, follow these instructions to install the GRUB EFI application into the hardcoded path and make a minimal boot configuration. Otherwise it's better to skip ahead and set up the boot configuration normally.

To install GRUB with the EFI application in the hardcoded path `EFI/BOOT/BOOTX64.EFI`, first ensure the boot partition is mounted at `/boot` and the ESP is mounted at `/boot/efi`. Then, as the `root` user, run the command:

### Note

This command will overwrite `/boot/efi/EFI/BOOT/BOOTX64.EFI`. It may break a bootloader already installed there. Back it up if you are not sure.

    grub-install --target=x86_64-efi --removable

This command will install the GRUB EFI application into the hardcoded path `/boot/efi/EFI/BOOT/BOOTX64.EFI`, so the EFI firmware can find and load it. The remaining GRUB files are installed in the `/boot/grub` directory and will be loaded by `BOOTX64.EFI` during system boot.

### Note

The EFI firmware usually prefers the EFI applications with a path stored in EFI variables to the EFI application at the hardcoded path. So you may need to invoke the boot selection menu or firmware setting interface to select the newly installed GRUB manually on the next boot. Read the manual of your motherboard or laptop to learn how.

If you've followed the instructions in this section and set up a minimal boot configuration, now skip ahead to the section Creating the GRUB Configuration File.

## Mount the EFI Variable File System

The installation of GRUB on a UEFI platform requires that the EFI Variable file system, `efivarfs`, is mounted. As the `root` user, mount it if it's not already mounted:

    mountpoint /sys/firmware/efi/efivars || mount -v -t efivarfs efivarfs /sys/firmware/efi/efivars

### Note

If the system is booted with UEFI and systemd, `efivarfs` will be mounted automatically. However, in the LFS chroot environment it still needs to be mounted manually.

### Warning

If the system is not booted with UEFI, the directory `/sys/firmware/efi` will be missing. In this case you should boot the system in UEFI mode with the emergency boot disk or using a minimal boot configuration created as above, then mount `efivarfs` and continue.

## Setting Up the Configuration

On UEFI based systems, GRUB works by installing an EFI application (a special kind of executable) into `/boot/efi/EFI/[id]/grubx64.efi`, where `/boot/efi` is the mount point of the ESP, and `[id]` is replaced with an identifier specified in the grub-install command line. GRUB will create an entry in the EFI variables containing the path `EFI/[id]/grubx64.efi` so the EFI firmware can find `grubx64.efi` and load it.

`grubx64.efi` is very lightweight (136 KB with GRUB-2.06) so it will not use much space in the ESP. A typical ESP size is 100 MB (for Windows boot manager, which uses about 50 MB in the ESP). Once `grubx64.efi` has been loaded by the firmware, it will load GRUB modules from the boot partition. The default location is `/boot/grub`.

As the `root` user, install the GRUB files into `/boot/efi/EFI/LFS/grubx64.efi` and `/boot/grub`. Then set up the boot entry in the EFI variables:

    grub-install --bootloader-id=LFS --recheck

If the installation is successful, the output should be:

    Installing for x86_64-efi platform.
    Installation finished. No error reported.

Issue the efibootmgr | cut -f 1 command to recheck the EFI boot configuration. An example of the output is:

    BootCurrent: 0000
    Timeout: 1 seconds
    BootOrder: 0005,0000,0002,0001,0003,0004
    Boot0000* ARCH
    Boot0001* UEFI:CD/DVD Drive
    Boot0002* Windows Boot Manager
    Boot0003* UEFI:Removable Device
    Boot0004* UEFI:Network Device
    Boot0005* LFS

Note that `0005` is the first in the `BootOrder`, and `Boot0005` is `LFS`. This means that on the next boot, the version of GRUB installed by LFS will be used to boot the system.

## Creating the GRUB Configuration File

Generate `/boot/grub/grub.cfg` to configure the boot menu of GRUB:

    cat > /boot/grub/grub.cfg << EOF
    # Begin /boot/grub/grub.cfg
    set default=0
    set timeout=5

    insmod part_gpt
    insmod ext2
    set root=(hd0,2)

    insmod efi_gop
    insmod efi_uga
    if loadfont /boot/grub/fonts/unicode.pf2; then
      terminal_output gfxterm
    fi

    menuentry "GNU/Linux, Linux 6.16.1-lfs-12.4" {
      linux   /boot/vmlinuz-6.16.1-lfs-12.4 root=/dev/sda2 ro
    }

    menuentry "Firmware Setup" {
      fwsetup
    }
    EOF

Refer to the LFS book for the basic knowledge about the `grub.cfg` file. `(hd0,2)`, `sda2`, and `6.16.1-lfs-12.4` must match your configuration.

The insmod efi_gop and insmod efi_uga directives load two modules for EFI-based video support. On most systems the `efi_gop` module is enough. The `efi_uga` module is only useful for legacy systems, but it's harmless to load it anyway. The video support is needed for the terminal_output gfxterm directive to really work.

The terminal_output gfxterm directive changes the display resolution of the GRUB menu to match your display device. It will break the rendering if the `unicode.pf2` font data file is not loaded, so it's guarded by a if directive.

### Note

From GRUB's perspective, the files are relative to the partitions used. If you used a separate /boot partition, remove /boot from the above paths (to kernel and to `unicode.pf2`). You will also need to change the "set root" line to point to the boot partition.

The `Firmware Setup` entry (fwsetup) can be used to enter the configuration interface provided by the system firmware (sometimes called “BIOS configuration”).

## Dual-booting with Windows

Add a menu entry for Windows into `grub.cfg`:

    cat >> /boot/grub/grub.cfg << EOF
    # Begin Windows addition

    menuentry "Windows 11" {
      insmod fat
      insmod chain
      set root=(hd0,1)
      chainloader /EFI/Microsoft/Boot/bootmgfw.efi
    }
    EOF

`(hd0,1)` should be replaced with the GRUB designated name for the ESP. The `chainloader` directive can be used to tell GRUB to run another EFI executable, in this case the Windows Boot Manager. You may put more usable tools in EFI executable format (for example, an EFI shell) into the ESP and create GRUB entries for them, as well.

- Prev

  GRUB-2.14 for EFI

- Next

  Text Editors

- Up
- Home