LPIC-1: Loading Linux
In October 2018, LPI updated LPIC-1 to version 5.0 and Linux Essentials to version 1.6. In this blog series we will review the major changes introduced by these updates. Today, we start with an overview of ways to load the Linux kernel.
Objective 101.2 used to cover the traditional BIOS. The new version adds a UEFI, a newer type or computer firmware. In addition, objective 104.1 now includes GPT in addition to MBR partition tables. Although firmware (BIOS vs. UEFI) and partition tables (MBR vs. GPT) are technically different concepts, they are closely related when it comes to starting the Linux kernel.
When a computer starts, it has to load an operating system. What sounds trivial involves several components. After the firmware set up the hardware, the bootloader loads the operating system kernel from the hard disk which is then run to start the actual operating system. The exact location of the bootloader and the mechanism to locate and start it differ depending on the firmware and partition table type. For the rest of this post, we assume that the GRUB 2 bootloader is used.
Traditionally, hard disks contain a master boot record partition table (MBR). The MBR reserves some space which contains the bootloader. The BIOS can find this space because it resides at a fixed position on the disk. However, this space is too small for most bootloaders, which is why only an initial part of the bootloader is stored in the MBR. GRUB, for example, stores its so-called
boot.img here, which just knows enough to load the rest of the bootloader from another position.
A traditional MBR leaves some space between the end of the MBR and the start of the first partition. On an MBR disk, GRUB uses this space to store its
core.img. This code is finally able to access the
/boot/ partition, where GRUB loads additional modules, the Linux kernel and the initramfs image.
GUID partition tables, GPT for short, have a different structure which supports more and larger partitions. However, it no longer contains a partition gap, so GRUB cannot use this space to store its
core.img. Instead, it expects a small partition with the type BIOS boot partition (EF02). This partition does not contain a file system; it is directly used by
grub-install to store
core.img. When booting the system using legacy BIOS and GPT, GRUB is loaded from the MBR, loads
core.img from the BIOS boot partition and then reads the remaining components from the partition containing
UEFI is a type of firmware which can load and execute extensions. The Linux kernel can be compiled to be such an extension, just like the GRUB bootloader. The extensions are stored in the EFI system partition, ESP. This partition is identified by the partition type EFI System (0xEF00) and typically contains a FAT file system. It is explicitly mentioned in objective 102.1.
In Linux, the this partition is usually mounted to
/boot/efi/. This partition can contain EFI binaries for multiple operating systems or bootloaders.
grub-install can create a directory for GRUB on the ESP. The directory
/boot/efi/EFI/linux/ could, for example, contain the file
grubx64.efi. If secure boot is used, some additional files are required. These files are executed by the firmware to start GRUB.
UEFI offers an interactive shell which supports navigating through the EFI partition’s file system and executing EFI binaries. To ease the startup, UEFI can store settings of one or more operating systems which can be started directly without using the EFI shell. These settings can be modified from Linux using the command
efibootmgr, which is covered in LPIC-2. If you want to learn all the details, Adam Williamson’s blog on EFI Partitions is a great read.
The installation of a bootloader depends on on the firmware used. For a legacy BIOS, either an MBR partition table or a GPT which contains a GRUB partition is required. In both cases, the
boot.img part of GRUB is installed at a fixed position on the hard disk.
core.img is either loaded from the partition gap after the MBR or from the GRUB partition on a GPT disk. Wikipedia illustrates this quite nicely. UEFI instead starts the GRUB EFI binary, along with additional extensions required to support secure boot, from the ESP. In any case, GRUB is now able to access the
/boot/ partition to load additional GRUB modules, the Linux kernel and initramfs.
As all of these concepts are relevant for LPIC-1, you should try to manually configure all these three scenarios by using
grub-install. Refer to your distribution’s documentation for the exact steps, packages you need to install and how to generate a GRUB configuration file. Consider using a virtual machine to have some hard disks for your experiments.
Once the Linux kernel and the initramfs are started, an init system such as systemd takes over. Next week we will review some advanced concepts of systemd which were added to the new version of LPIC-1.