[According to my own standards, this post about “UEFI booting” was only like 70% “ready” — I had it pending in “draft” state for many months, because I was lacking the time to finish it… I now decided to release it in its current state, simply because I believe it will still be very useful to many people interested in the topic…]
Before we actually dive deep into how UEFI booting works, a short and simple introduction is due.
Introduction
What is UEFI, anyway?
UEFI could be called the successor of the old BIOS concept. It is a unified version and successor of “EFI”, which was an architecture for a platform firmware used to boot operating systems (in the following abbreviated as “OS”), and the corresponding interface to interact with the firmware and the operating system.
The advantages of UEFI over the traditional BIOS are, among others, the following:
- Boot disks with large partitions (over 2 TB), using GUID partitioning (GPT),
- network capabilities already in pre-OS phase, and
- modular design.
Boot Mechanism
So, how does booting with UEFI work?
When you enter your UEFI, you will find a user interface that shows all devices that have been detected, and that support booting. Usually that includes all your hard drives.
You can freely define a desired boot order (regardless of hardware paths, i.e. the way your drives are connected, be it via an SATA port, be it via an NVME slot), i. e. the primary OS that should be booted, if that fails the next OS that should be tried, etc. That’s called your “boot configuration”, and it resides in your motherboard’s NVRAM. (a concept that’s basically the successor of what used to be called “CMOS” in the old days of the BIOS). More specifically, we speak about “UEFI Variables“, which allow the OS and the firmware to interact.
When UEFI’s Firmware Boot Manager wants to boot an OS, it first needs to load something called the OS “Boot Manager.” Common OS boot managers are:
- BOOTMGFW.EFI used to load Windows, or
- SHIMX64.EFI used to load Linux
The OS boot manager is located on the “EFI system partition” (ESP). This is a small partition (usually only a few 100 M) at the start of your hard drive, formatted with basically a FAT filesystem. FAT is a very simple filesystem, so that the code to parse it and load files from it can be reasonably small and fit into a boot firmware.
A typical disk layout for a Windows installation may look as follows:
The first partition is the ESP, then comes the Windows boot and system drive (with a drive letter of C:), and then comes the recovery partition.
Apart from boot loaders, the ESP can contain kernel images or (device) drivers, e. g. to support hardware that must be initialized prior to the start of the OS, or to give access to a complex filesystem that holds the actual OS to be booted.
Depending on which OS you want to boot, the OS boot manager then loads
- in the case of Linux: the OS kernel, and the kernel in turn loads the OS, or
- in the case of Windows: the Windows Boot Loader (
\Windows\system32\winload.efi
)
Boot Configuration Details
Now that we got a good overview of the mechanism as a whole, let’s dive into the details. Let’s look at the boot configuration of my machine. To do so, invoke the below command (I did it under Ubuntu 23.04, but it should work the same under any reasonably current Linux distro where the tool is installed):
# efibootmgr -v
BootCurrent: 0003 Timeout: 1 seconds BootOrder: 0000,0002,0003 Boot0000* Windows Boot Manager HD(1,GPT,a39d5736-7aaf-4be0-b6b6-0852ba2f7803,0x800,0x32000)/File(\EFI\MICROSOFT\BOOT\BOOTMGFW.EFI)WINDOWS………x…B.C.D.O.B.J.E.C.T.=.{.9.d.e.a.8.6.2.c.-.5.c.d.d.-.4.e.7.0.-.a.c.c.1.-.f.3.2.b.3.4.4.d.4.7.9.5.}…R……………. Boot0002* ubuntu HD(1,GPT,280ea55d-c182-5242-bb52-a2b40812190c,0x800,0x219800)/File(\EFI\UBUNTU\SHIMX64.EFI)..BO Boot0003* ubuntu HD(1,GPT,91b56f9f-3526-404b-b681-1c684551ec4f,0x800,0xd87be)/File(\EFI\UBUNTU\SHIMX64.EFI)..BO
So, what does the above tell us? First, we see that “(Boot)0003
” is the boot entry used to start the currently running system. Secondly, the order in which boot is tried is 0000
, 0002
, and then 0003
. So by default, Windows (by the “Windows Boot Manager”) will be booted. Then we see the three boot entries. The star/asterisk (*
) after the boot entry shows that all these entries are “active.”
What about the remaining info in the above command output? Immediately after the boot entry, we see the names that are also displayed on screen by the Firmware Boot Manager (“Windows Boot Manager” and two times “ubuntu”). We then see references to the ESPs used to boot these OS.
HD
obviously means “hard drive”, then we see a 1
which refers to the first partition on the respective drive, then we see GPT
which refers to the partitioning table format, and then we see a UUID. To find the respective partitions, we can use the below command:
# blkid --match-token TYPE=vfat
/dev/nvme0n1p1: LABEL="UBUNTU_TEMP" UUID="EC76-8E7F" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="280ea55d-c182-5242-bb52-a2b40812190c"
/dev/nvme1n1p1: SEC_TYPE="msdos" LABEL_FATBOOT="UBUNTU_MAIN" LABEL="UBUNTU_MAIN" UUID="8140-E4C0" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI" PARTUUID="91b56f9f-3526-404b-b681-1c684551ec4f"
/dev/sda1: UUID="40AD-1127" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="a39d5736-7aaf-4be0-b6b6-0852ba2f7803"
The PARTUUID
values in the above output match the UUIDs in the boot configuration as shown by efibootmgr
. So, the ESPs are located by searching for the partitions’ UUIDs. That means that you can replug your drives to different ports, or even copy partitions to different drives, and the UEFI boot mechanism will still find them. That’s a nice and very stable design.
UEFI User Interface
Now, let’s enter the UEFI and look at some of the details there. My PC’s motherboard is an MSI, and to enter the UEFI I need to press “F2” after the beep when powering on the PC (from “off” state, not when suspended to RAM, i.e. “sleeping”!) or restarting it.
# lspci
[...]
21:00.0 Non-Volatile memory controller: Sandisk Corp WD Blue SN570 NVMe SSD 1TB
2b:00.0 Non-Volatile memory controller: Sandisk Corp WD Blue SN570 NVMe SSD 1TB