21

Nov

What’s The Deal With UEFI?

It seems like there are two camps, the small group of people who care about UEFI and everyone else who doesn’t really notice or care as long as their computer works. So let’s talk about what UEFI is, how it came to be, what it’s suitable for, and why you should (or shouldn’t) care.

What is UEFI?

UEFI stands for Unified Extensible Firmware Interface, a standard held by an organization known as the United EFI Forum. Intel came out with EFI (Extensible Firmware Interface) and later made the spec public as UEFI. As a spec, implementation details change between vendors and manufacturers, but the goal is to present an OS bootloader’s standard and understandable structure. This makes it much easier to write an OS as you no longer need to worry about all the messy business of actually starting the chipset.

Several IBVs (Independent Bios Vendors) offer their implementations of UEFI that OEMs who produce motherboards can license and use in their products. Some examples would be AMI, Phoenix, and InSyde. You’ve likely seen their logo or just the text of their name briefly flash on the screen before your OS of choice properly boots.

Let’s talk about how UEFI boots. Generally, there are a few different phases. We generally say since there are many implementations and many of them do things out of spec. There are three general phases: Security (SEC), Pre-EFI Initialization (PEI), and Drive Execution Environment (DXE). Each is a mini operating system. Because Intel is the one who started EFI and later turned it into UEFI, much of the design is built around how Intel processors boot up. Other platforms like ARM might not do much in the SEC or PEI phase.

What’s The Deal With UEFI?

The boot process for X86 processors is a bit strange. They start in real mode (though most processors these days are technically unreal), with a 20-bit address space (1MB of addressable memory) for backward compatibility reasons. As the processor continues to boot, it switches to protected mode and then finally to long mode. In a multi-core system, all the processors race to get a semaphore or read EAX, and one is designated the BSP (bootstrap processor). The losers all halt until the BSP starts them via an IPI (inter-processor interrupt). Ordinarily, there is an onboard SPI flash chip with firmware mapped into the end of the physical 32-bit region of memory. The Intel Management Engine (ME) or AMD Platform Security Processor (PSP) does most of the SEC phase, such as flushing the cache and starting the processors.

Once the processors are started, PEI has officially begun. On Intel systems, there is no system RAM in most of PEI. This is because memory needs to be trained and links initialized before the processor can use them. The ever relentless push for more and more speed from RAM means that the RAM needs to be tested, calibrated, and configured on every boot as different RAM sticks have other parameters. Many systems cache these parameters for faster boot times, but they often need to be invalidated and retrained as the RAM sticks age. The PSP handles memory training and loading UEFI on some AMD systems before the main x86 processor is pulled out of reset. For Intel systems, they use a trick called XIP (execute in place) which turns the various caches into temporary RAM. There is only a small stack, a tiny amount of heap space, and no static variables for PEI. Many Intel server platforms rely on the Board Management Controller (BMC) to train memory, as training large amounts of memory takes a very long time.

After initializing RAM and transferring the contents of the temporary cache, we move to DXE. The DXE phase provides two types of services: boot and runtime. Runtime services are meant to be consumed by an OS, services such as non-volatile variables. Boot services are destroyed once ExitBootServices is called (typically by the OS loader), but they are services like keyboard input and graphical drivers. BDS (boot device selection) runs in DXE and is how the system determines what drive to boot (hard drive, USB, etc.).

This has been a very dense and x86 specific overview. Many architectures such as ARM eschew UEFI for something more like coreboot, linuxboot, or LK, where it boots a small Linux kernel that then kexec’s into a much larger kernel. However, many ARM platforms can also leverage UEFI. Only time will tell which way the industry moves.

How It Came To Be

In 2005, UEFI entirely replaced EFI (Extensible Firmware Interface), the standard Intel had put forth a few years prior. EFI borrowed many things from Windows of that period, PECOFF image formats, and UEFI, in turn, borrowed practices from EFI. Before EFI, there was good old BIOS (Basic Input Output System). The name originated from CP/M systems of 1975. In that period, the BIOS was a way for the system to boot and provide a somewhat uniform interface for applications by providing BIOS interrupt calls. The calls allowed a program to access the input and outputs such as the serial ports, the RTC, and the PCI bus. Phoenix and others reverse-engineered the proprietary interface that IBM created to manufacture IBM compatible machines, which eventually led to something close to a standard.

Is It Better Than BIOS?

Yes and no, depending on your perspective. Many OS vendors like UEFI because they generally make their lives easier as the services provided make it easy to give a homogenous experience booting. The Linux community, generally speaking, is agnostic at best and antagonistic at worst towards UEFI. The BIOS interface is pushing 45 years as of the time of writing and is considered legacy in every sense. Another point in UEFI’s corner is that it facilitates selecting different boot devices and updating the firmware on your machine. UEFI uses GUID Partition Table (GPT) over Master Boot Record (MBR) — considerd a plus as MBR is somewhat inflexible. Many platforms shipped today are based on the open-source EDK2 project from TianoCore, an implementation of UEFI that supports X86, ARM, and RISCV.

The biggest complaint with UEFI is that it is a closed black box with unimaginable access to your computer and stays resident after the computer boots. BIOS is appealing since the interface is well-known and generally is non-resident. UEFI can be updated easier but also has a much more vital need for updates. A UEFI update can brick your system entirely. It will not boot, and due to the fuses being blown on the unit, it is almost physically impossible to fix it, even for the manufacturer. Significant amounts of testing go into these updates, but most are hesitant to push many updates because of the amount of work required.

Why You Should or Shouldn’t Care

At the end of the day, you care if you can use your computer for the things that are important to you. Whether that’s playing a game, writing an email, or making a new computer, it doesn’t matter as long as the computer does what you want. And booting is just one oft-forgotten step in making that happen. If you care about knowing every single piece of code your machine runs, you need to buckle in for a long ride. There are companies such as Librem going to long lengths to make sure that tricky problems like memory init are running in non-proprietary blobs. You can still tweak UEFI, [Hales] being a great example of tweaking the BIOS of an old school laptop. Open-source tools for inspecting and understanding what’s going on under the hood are getting better.

Ultimately it is up to you whether you care about the boot process of your device.