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.
Enable the following options in the kernel configuration and recompile the kernel if necessary:
Processor type and features ---> [*] EFI runtime service support [EFI] -*- Enable the block layer ---> [BLOCK] Partition Types ---> [ /*] Advanced partition selection [PARTITION_ADVANCED] [*] EFI GUID Partition support [EFI_PARTITION] Device Drivers ---> Firmware Drivers ---> [*] Mark VGA/VBE/EFI FB as generic system framebuffer [SYSFB_SIMPLEFB] Graphics support ---> <*> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) ---> ... [DRM] [*] Enable legacy fbdev support for your modesetting driver ... [DRM_FBDEV_EMULATION] <*> Simple framebuffer driver [DRM_SIMPLEDRM] Frame buffer Devices ---> <*> Support for frame buffer devices ---> [FB] Console display driver support ---> -*- Framebuffer Console support [FRAMEBUFFER_CONSOLE] 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.
CONFIG_SYSFB_SIMPLEFB
,
CONFIG_DRM
,
CONFIG_DRM_FBDEV_EMULATION
,
CONFIG_DRM_SIMPLEDRM
,
CONFIG_FB
, and
CONFIG_FRAMEBUFFER_CONSOLE
The combination of these options provides the Linux console support on top of the UEFI framebuffer. To allow the kernel to print debug messages at an early boot stage, they shouldn't be built as kernel modules unless an initramfs will be used.
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.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):
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. 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. It will boot the system and show the GRUB shell. Then you can type commands to boot your operating system from the hard drive. To learn how to select the boot device, read the manual of your motherboard or laptop.
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.
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
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:
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.
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 “Creating the GRUB Configuration File”.
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
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 using a 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
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.
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 all_video
if loadfont /boot/grub/fonts/unicode.pf2; then
terminal_output gfxterm
fi
menuentry "GNU/Linux, Linux 6.4.10-lfs-12.0" {
linux /boot/vmlinuz-6.4.10-lfs-12.0 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.4.10-lfs-12.0
must match your
configuration.
The insmod all_video directive loads various modules for video support. It's needed to initialize the EFI framebuffer for the kernel to print messages correctly before the kernel GPU driver initialization.
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.
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 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, as well.