BLFS does not have the essential packages to support Secure Boot. To set up the boot process with GRUB for UEFI installed 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.
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:
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/sdxWelcome to fdisk (util-linux 2.38.1). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Command (m for help):
tPartition number (1-9, default 9):
1Partition type or alias (type L to list all):
uefiChanged type of partition 'Linux filesystem' to 'EFI System'. Command (m for help):
wThe partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.
Still as the root
user, create a
mount point for the EFI partition on the USB flash drive and mount
it:
mkdir -pv /mnt/rescue && mount -v -t vfat /dev/sdx1 /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 a emergency boot disk on x86-64 UEFI platform. It will boot the system and show the GRUB shell. Then you can type commands to boot your operating systems on the hard drive. To learn how to select the boot device, read the manual of your motherboard or laptop.
Enable the following options in the kernel configuration and recompile the kernel if necessary:
Processor type and features --->
[*] EFI runtime service support [CONFIG_EFI]
[*] EFI stub support [CONFIG_EFI_STUB]
Enable the block layer --->
Partition Types --->
[*] Advanced partition selection [CONFIG_PARTITION_ADVANCED]
[*] EFI GUID Partition support [CONFIG_EFI_PARTITION]
Device Drivers --->
Firmware Drivers --->
[*] Mark VGA/VBE/EFI FB as generic system framebuffer [CONFIG_SYSFB_SIMPLEFB]
EFI (Extensible Firmware Interface) Support --->
< > EFI Variable Support via sysfs [CONFIG_EFI_VARS]
[*] Export efi runtime maps to sysfs [CONFIG_EFI_RUNTIME_MAP]
Graphics support --->
<*> Direct Rendering Manager [CONFIG_DRM]
<*> Simple framebuffer driver [CONFIG_SIMPLEDRM]
Frame buffer Devices --->
<*> Support for frame buffer devices ---> [CONFIG_FB]
Console display driver support --->
[*] Framebuffer Console support [CONFIG_FRAMEBUFFER_CONSOLE]
File systems --->
Pseudo filesystems --->
<*/M> EFI Variable filesystem [CONFIG_EFIVAR_FS]
The meaning of the configure options:
CONFIG_EFI_STUB
Although the EFI stub is designed to boot a kernel directly from the UEFI firmware (without a bootloader like GRUB), GRUB needs the kernel to be loaded to support the EFI handover protocol enabled by this option.
CONFIG_EFI_VARS
Don't use this deprecated option because of a 1024-byte
variable size limit. Its function is replaced by CONFIG_EFIVAR_FS
.
CONFIG_SYSFB_SIMPLEFB
, CONFIG_DRM
, CONFIG_SIMPLEDRM
, CONFIG_FB
, and CONFIG_FRAMEBUFFER_CONSOLE
The combination of these options allows the kernel to print debug messages (along with Tux logos) at the early stage of the boot process with UEFI. To ensure them functional at the early stage, they shouldn't be built as a kernel module unless an initramfs will be used.
On EFI based system, 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 Linux distribution or Windows is pre-installed,
it's likely that the ESP is already 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 a first time
install an UEFI booted OS on the system, the ESP may not exist. In
that case, 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.
Some (old) UEFI implementations may demand 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):
mkdir -pv /boot/efi && mount -v -t vfat /dev/sda1 /boot/efi
Add an entry for the ESP in /etc/fstab
, so it will be mounted automatically
during system boot:
cat >> /etc/fstab << EOF
/dev/sda1 /boot/efi vfat defaults 0 1
EOF
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 into the EFI variables. The use of the hardcoded path
should be avoided as much as possible. However, in some cases we
have to use the hardcoded path:
The system is not booted with EFI yet, causing EFI variables inaccessible.
The EFI firmware is 64-bit but the LFS system is 32-bit, causing 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 is stored in NVRAM or EEPROM on the local machine.
You are unable or unwilling to install efibootmgr for manipulating boot entries in EFI variables.
In these cases, follow this section to install GRUB EFI application into the hardcoded path and make a minimal boot configuration. Otherwise it's better to skip this section and read the remaining sections to set up the boot configuration in a normal way.
To install GRUB with the EFI application installed into the
hardcoded path EFI/BOOT/BOOTX64.EFI
,
first ensure the boot partition is mounted at /boot
and the ESP mounted at /boot/efi
. Then as the root
user, run the command:
The 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
The command would install 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 into /boot/grub
directory and will be loaded by BOOTX64.EFI
during system boot.
The EFI firmware usually prefers the EFI applications with the path recorded in boot entries 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 figure out how.
If you've followed this section and set up a minimal boot configuration, now skip until “Creating the GRUB Configuration File”.
The installation of GRUB on a UEFI platform requires that the EFI
Variable file system, efivarfs
, to
be 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
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.
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 minimal boot configuration created as above, then mount
efivarfs
and continue.
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
loaded by the firmware, it will load
GRUB modules in 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 efibootmgr | cut -f 1 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.
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)
if loadfont /boot/grub/fonts/unicode.pf2; then
set gfxmode=auto
insmod all_video
terminal_output gfxterm
fi
menuentry "GNU/Linux, Linux 5.19.2-lfs-11.2" {
linux /boot/vmlinuz-5.19.2-lfs-11.2 root=/dev/sda2 ro
}
menuentry "Firmware Setup" {
fwsetup
}
EOF
(hd0,2)
, sda2
, and 5.19.2-lfs-11.2
should be replaced to match your
configuration.
From GRUB's perspective, the files are relative to the partition
are 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 can be used
to enter the configuration interface provided by the firmware
(sometimes called “BIOS configuration”).
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.