Blog>>Software development>>Beyond the legacy: embracing UEFI platform firmware

Beyond the legacy: embracing UEFI platform firmware

In this article, let’s discuss the evolution of platform firmware from the legacy 16-bit BIOS to the modern Unified Extensible Firmware Interface (UEFI). We examine how BIOS laid the groundwork for hardware initialization and boot processes and how its limitations led to the development of UEFI.

A brief overview of the legacy of 16-bit BIOS

BIOS stands for basic input/output system (BIOS). It is a platform firmware used to perform hardware initialization during boot time, orchestrating the platform boot-up process, and preparing the platform for OS management. It was originally invented by Gary Kildall (an American computer scientist) in the 1970s.

The earliest BIOS implementations were hardcoded into the computer's ROM (read-only memory). They provided basic functionalities such as power-on self-test (POST), which checked the system's hardware for errors during boot-up and handled input/output operations for peripherals like keyboards and monitors.

In the 1980s, legacy BIOS began to take shape as a more standardized interface, particularly with the introduction of IBM's personal computer (PC) in 1981. As PCs gained popularity in homes and offices throughout the 1980s and 1990s, legacy BIOS changed to keep up with hardware advancements. It supported the transition from floppy disks to hard drives, recognized and set up expansion cards, and offered system configuration options through a simple text interface, among other things.

However, as platforms evolved into what they are today, the limitations of legacy BIOS started to surface. BIOS runs in a 16-bit environment called real mode, which means that it can only address about 1MB of memory (with some exceptions). This seriously reduces the acceptable complexity of the BIOS and bootloaders. Additionally, BIOS can only work with master boot record (MBR) partitions which cannot be larger than ~2.2TB. Finally, it does not provide any advanced functionalities such as security or a GUI framework.

Unified Extensible Firmware Interface (UEFI): A successor to legacy BIOS

The advent of the Intel Itanium architecture required a different approach to booting platforms, as IA-64 did not start in real mode and could not utilize the existing BIOS code. To address this challenge, Intel started the Intel Boot Initiative (IBI) in 1998, which was later renamed to Extensible Firmware Interface (EFI). EFI presented the overall market with an opportunity to change the boot interface for other existing CPU architectures. Out of various solutions offered at that time by companies and organizations, EFI prevailed and was adopted.

The emergence of x86-64 and the industry’s need for a publicly-owned boot specification resulted in the formation of the UEFI Forum organization in 2005. In parallel, Intel has contributed EFI to the open-source community, which is now known as Unified EFI (UEFI). The following base components have been made public:

  • EFI specification - detailed description of the boot interface,
  • "Foundation Code" - Intel's preferred way of implementing EFI, which later evolved into EDK and EDKII - the baseline code for UEFI platform firmware.

Fast-forward to today, and UEFI supports various CPU architectures (x86-64, Arm, RISC-V, …) and is shipped in the majority of contemporary PC and server platforms. Also, all major operating systems are compatible with the UEFI boot environment.

The development of UEFI specifications and EDKII reference implementation

In essence, UEFI is a specification that standardizes:

  • the execution environment for device drivers and applications (e.g. bootloaders),
  • the boot manager, its behavior and control mechanisms,
  • the communication interface between platform firmware and the OS,
  • the storage partitioning format (GPT).

Simply put, it describes the mechanisms that allow for the loading and execution of next-stage bootloaders up to the functional operating system. Along with the Platform Initialization (PI) and Advanced Configuration and Power Interface (ACPI) specifications, the industry can develop a fully-fledged platform firmware.

EDKII is an open-source firmware framework compatible with PI and UEFI specifications. It is developed, tested, and maintained by TianoCore, an organization associated with major system manufacturers and operating system vendors. Widespread adoption of EDKII in contemporary PC, server, and IoT platforms guarantees that the available code is uniform, reliable, and secure.

UEFI platform boot phases

The boot process of a modern computer system is a complex sequence of events orchestrated by the UEFI firmware. Understanding the stages through which UEFI guides the system from power-on to the operating system (OS) loading is crucial for grasping the foundational aspects of system initialization and operation. 

Fig.1: UEFI platform boot phases [BP]
A diagram showing UEFI boot phases

Typically, platform boot consists of the following steps:

  • SEC (Security) Phase
    This is the first stage within the UEFI Platform Initialization (PI). It oversees the management of all platform restart events, establishes a temporary memory store, and acts as the foundational trust anchor in the system. This includes all the CPU startup code from the moment the system boots up. Its job is to prepare the system enough to find, check, install, and start the PEI phase.
  • PEI (Pre-EFI Initialization) Phase
    This sets up the entire platform and loads and initiates the DXE phase. In this phase, critical hardware initialization tasks are undertaken, including configuring the CPU, memory, and other crucial system elements.
  • DXE (Driver Execution Environment) Phase
    DXE Core takes over and loads extra drivers called DXE drivers. These drivers help the UEFI firmware handle different hardware devices and services. The DXE phase is all about finding, setting up, and getting hardware devices like storage controllers, network adapters, and input devices ready to use.
  • BDS (Boot Device Selection) Phase
    This phase initializes console devices and any remaining necessary devices. Subsequently, the chosen boot entry is loaded and executed in preparation for the transient system load (TSL) phase.
  • TSL (Transient System Load) Phase
    During this stage, the UEFI firmware passes control to the operating system loader (for example, Windows Boot Manager or Linux boot loader). The OS loader then loads the operating system kernel and any required system files into memory, initializing the operating system environment for further startup procedures.
  • RT (Runtime) PhaseThis is the point where the system transitions to control the UEFI-compatible operating system.

UEFI Protocols as an enabler for extensibility

At the heart of UEFI lies a concept that enables adaptable and extensible development: UEFI Protocols. These act as fundamental elements that enable communication and interaction between different UEFI firmware components, applications, drivers, and the operating system. Through standardized interfaces and behaviors, UEFI protocols ensure interoperability and compatibility across a spectrum of hardware platforms and software environments.

The definition of each protocol comprises of:

  • A globally unique ID (GUID) - a unique identifier assigned to each UEFI protocol to differentiate it from others
  • An interface structure - data structure (C style) definition containing the functions and data fields produced by this protocol interface.
  • Services - functions that realize specific actions. 

The figure below shows the basic concept of the UEFI protocol use case. The UEFI driver registers protocol-specific functions. Once the UEFI protocols are correctly registered and recognized, other components may obtain the interface of the required protocol and call its functions.

Fig.2: Construction of a UEFI protocol
Construction of a UEFI protocol

The best way to grasp the concept of the UEFI protocol is by examining specific examples. For instance, consider a UEFI driver operating during the DXE phase. The key point is that this driver must offer the necessary interfaces to assist the UEFI firmware in managing the hardware. UEFI also needs to confirm that this driver is compatible with the selected hardware. This kind of scenario would be managed using the UEFI Driver Binding Protocol, which facilitates the connection between UEFI drivers and the hardware devices they control. This protocol defines rules and procedures for installing, configuring, and managing UEFI drivers within the system. It allows the UEFI firmware to manage the startup and functioning of hardware devices by associating drivers with compatible devices during boot time.

UEFI Driver Binding Protocol GUID: 

#define EFI_DRIVER_BINDING_PROTOCOL_GUID \
          {0x18A031AB,0xB443,0x4D1A,\
          {0xA5,0xC0,0x0C,0x09,0x26,0x1E,0x9F,0x71}}

UEFI Driver Binding Protocol Structure:

typedef struct _EFI_DRIVER_BINDING_PROTOCOL {
    EFI_DRIVER_BINDING_PROTOCOL_SUPPORTED    Supported;
    EFI_DRIVER_BINDING_PROTOCOL_START        Start;
    EFI_DRIVER_BINDING_PROTOCOL_STOP         Stop;
    UINT32                                   Version;
    EFI__HANDLE                              ImageHandle;
    EFI_HANDLE                               DriverBindingHandle;
} EFI_DRIVER_BINDING_PROTOCOL;

UEFI Driver Binding Protocol Services: 

  • Supported() - determines whether a driver is compatible with a specific device or not. 
  • Start() - initializes a driver for a specific device,
  • Stop() - terminates the driver's operation on a device.

UEFI firmware utilizes the UEFI Driver Binding Protocol to manage the initialization and operation of drivers for hardware devices during the system boot process by calling the appropriate protocol services.

UEFI Secure Boot implementation insights

UEFI Secure Boot is a security feature based on public-key cryptography that safeguards the computer's boot process from malicious threats. It ensures that the only software allowed to run at boot time is signed by a recognized, trusted Certificate Authority (CA).

How UEFI Secure Boot works

When Secure Boot is enabled, the UEFI firmware verifies the signature of each component of the boot software, such as UEFI drivers or the boot loaders, against a database of trusted signatures. If the signature is considered valid, the system will continue to boot. Otherwise, the boot process is stopped to prevent potential security threats.

Secure Boot does not extend to boot loaders and OS images executed at the runtime stage. Mechanisms based on the same principle as Secure Boot, such as Machine Owner Key, are outside the scope of this blog post.

Benefits of Secure Boot

  • Enhanced Security
    Secure Boot greatly diminishes the risk of malware infections during the boot process, safeguarding the system's integrity from the initial power-on.
  • Integrity Verification
    Secure Boot helps preserve the overall integrity of the operating system and essential boot components by allowing only trusted software to run.
  • Compliance and TrustFor organizations with stringent security policies, Secure Boot meets compliance requirements and fosters a reliable computing environment.

Reasons users disable Secure Boot

Despite its security benefits, many users opt to disable Secure Boot for several reasons:

  1. Compatibility Issues
    Secure Boot is not compatible with all operating systems and hardware drivers, particularly older or less common systems like certain Linux distributions or older versions of Windows. Users may disable Secure Boot to allow these systems to boot.
  2. Default Public Keys
    Systems are shipped with a set of default public keys. Their private key counterparts are managed by Microsoft, which is not always acceptable; e.g. for the Linux community. Furthermore, replacing default keys is cumbersome to many system users.
  3. Custom Hardware and Software
    Enthusiasts and professionals who build custom PCs or use specialized hardware might face Secure Boot issues if their components lack the necessary signatures. Disabling Secure Boot can simplify the setup and use of such systems.
  4. Ease of Use
    Troubleshooting Secure Boot can be cumbersome. If an unsigned driver or application is crucial for their work, users might find it more convenient to disable Secure Boot rather than seek signed versions of their software.
  5. Dual Booting
    Users running multiple operating systems on a single machine (e.g. Windows and Linux) may encounter difficulties with Secure Boot, as not all boot loaders support it out of the box. Disabling Secure Boot can facilitate a smoother dual-boot experience.

The future of UEFI

UEFI has revolutionized the computer boot process, offering significant improvements over traditional BIOS systems. It has helped the industry develop a secure, maintainable, and extensible platform firmware in a timely manner, reusing existing common code as much as possible.

However, a brief look at history may spark a discussion about the future of UEFI. BIOS emerged in 1981, and 20 years later, due to its limitations, UEFI began taking over the market. After another 20 years, UEFI has dropped backward compatibility with legacy BIOS (CSM) on Intel platforms. Today, 20 years have passed since UEFI appeared, and there is still room for improvement, especially in the realm of emerging firmware issues compromising the security and integrity of the systems.

There are at least two different trends for EDKII improvement:

  • Rewriting EDKII in a more secure low-level programming language, like Rust, to avoid introducing the most common bugs, such as memory leaks or buffer overflows.
  • The abandonment of UEFi in favor of boot loaders based on the Linux kernel (LinuxBoot) provides an even more common code base with better coverage.

It is hard to tell which trend will become the mainstream, but it sure is exciting to see what the future will bring.

Kacperski  Kamil

Kamil Kacperski

Engineering Manager

Kamil Kacperski is an engineering manager and author on CodiLime's blog. Check out the author's articles on the blogRead about author >
Rabęda Maciej

Maciej Rabęda

Senior Software Engineer

Maciej is a senior software engineer at CodiLime with a decade-long journey in platform firmware and pre-OS networking. He has worked as a developer and architect for solutions related to system booting (legacy, UEFI), storage (iSCSI, NVMe/TCP), manageability (e.g. Redfish) and low-level performance...Read about author >

Read also

Get your project estimate

For businesses that need support in their software or network engineering projects, please fill in the form and we'll get back to you within one business day.