Tag Archives: linux

A deep-dive into UEFI Booting

[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:

UEFI /EFI System Partition as seen under Windows

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

Grub and root on partitionable RAID1 array

To make a long story short — don’t do it, it won’t work. 🙂

And now the long version of the whole story. The following applies to Debian 4.0 aka “Etch,” but it’s not specific to Debian, since the principles of the whole procedure is the same on all Linux distributions.

For the first time I wanted to use a partitionable RAID1 array, because I wanted to spare myself the trouble of creating multiple partitions on both drives which would then be combined to individual RAID1 arrays. Instead I would have to create a single partitionable RAID1 array and partition it afterwards.

Continue reading Grub and root on partitionable RAID1 array

A somewhat nightmarish Debian upgrade…

You might remember that I while ago I wrote a post about upgrading my office test-server from Debian Sarge to the almost-ready Etch, and that everything went as smoothly as I’m used to Debian distro-upgrades.

Well, on 2007-04-10 I upgraded my personal production server (that also hosts this blog) to the finally-released Debian 4.0, code-named “Etch.” I sticked pretty closely to the release notes, which always is a good idea even if you’re an experienced user.

At first, all seemed to go well. I performed the pre-upgrade step to pull in the new libc6, and afterwards performed the dist-upgrade that pulled in the remaining packages to be upgraded or to be newly installed in order to satisfy dependencies.

Continue reading A somewhat nightmarish Debian upgrade…

Debian distro upgrade to Etch

A few days ago I upgraded my personal Debian server in the office from Sarge to Etch, considering that it’s only approximately two weeks until Etch will be officially released, and I wanted to be prepared for what’s to come when I upgrade other (important!) boxes to Etch.

As always I was amazed about how smoothly the upgrade went. I used

apt-get dist-upgrade

to upgrade the box. APT downloaded about 300 packages, if I remember correctly. In the configuration phase that occurred afterwards, it asked me the usual couple of questions about some of the packages in case the existing configuration files didn’t contain all the necessary settings, or in case I had changed config files for which a new version is available in Etch.

Continue reading Debian distro upgrade to Etch