How UEFI Boot Services Impact Memory Management

Unified Extensible Firmware Interface (UEFI) memory management is fundamentally shaped by the lifecycle of its services, which are split between transient Boot Services and persistent Runtime Services. Because Boot Services exist solely to initialize the platform, load drivers, and prepare the operating system loader, they are completely terminated at the end of the pre-boot phase. This transient design forces UEFI to implement a dual-tier memory classification system, strictly controls how memory is allocated and mapped, and mandates a coordinated handoff that allows the operating system kernel to reclaim boot-time memory while preserving runtime firmware components.

The Transient Boundary: ExitBootServices()

In UEFI architecture, the transition from firmware control to operating system control hinges on a single API call: ExitBootServices(). Prior to this call, the platform firmware controls all hardware, interrupts, and memory spaces via Boot Services.

Once the operating system loader calls ExitBootServices(), the Boot Services table and all associated APIs are invalidated. Timers, event handlers, and allocation functions cease to function. Consequently, any memory allocation made during the boot phase must anticipate this hard boundary. Memory management cannot treat all allocations equally; it must differentiate between data needed only to boot the machine and data required indefinitely by the OS.

UEFI Memory Classification and Allocation Types

To manage the transient lifecycle, UEFI defines specific memory types within its memory map. When a UEFI application or driver requests memory using AllocatePages() or AllocatePool(), it must specify the memory type, determining its fate after ExitBootServices():

  • Boot Services Memory (EfiBootServicesCode and EfiBootServicesData): Allocated for drivers, applications, and temporary buffers needed exclusively during the boot phase. Once ExitBootServices() succeeds, the operating system is free to reclaim and overwrite these memory regions as standard system RAM.
  • Runtime Services Memory (EfiRuntimeServicesCode and EfiRuntimeServicesData): Allocated for firmware components that must persist throughout the OS lifecycle, such as NVRAM variable access and system reset handlers. The OS must preserve these regions and map them into its own virtual address space.
  • Conventional Memory (EfiConventionalMemory): Unallocated RAM available for use by both the firmware and, later, the operating system.
  • ACPI and Reserved Memory (EfiACPIReclaimMemory, EfiACPIMemoryNVS, EfiReservedMemoryType): Tables and platform-specific data that must be handled under specific OS preservation rules.

If a developer mistakenly allocates boot-time data as runtime memory, that RAM is permanently leaked and cannot be recovered by the OS. Conversely, if runtime components depend on memory marked as boot-services memory, the operating system will overwrite that memory, triggering kernel panics or hardware instability when runtime firmware functions are invoked.

Memory Map Synchronization Challenges

The transient nature of Boot Services creates a synchronization challenge during the OS handoff. The OS loader must obtain the platform's current memory layout using GetMemoryMap() before calling ExitBootServices().

However, calling GetMemoryMap() often requires allocating a buffer to store the map itself. If that buffer allocation alters the memory layout, the memory map key changes, causing ExitBootServices() to reject the termination call. As a result, the memory subsystem requires loaders to execute a precise loop: allocate memory for the map, fetch the map, and immediately invoke ExitBootServices() using the returned key without performing any intermediate allocations.

Operating System Memory Reclamation and Virtual Remapping

Once ExitBootServices() executes successfully, the operating system initiates two primary memory management actions directly influenced by UEFI's transient design:

  1. Reclamation: The OS parses the memory map provided by UEFI, identifies all ranges labeled EfiBootServicesCode and EfiBootServicesData, and adds them to its free memory pool alongside EfiConventionalMemory. This design ensures that large UEFI footprints (such as complex option ROMs, graphical setup interfaces, and diagnostic utilities) leave no permanent memory overhead in the running OS.
  2. Virtual Address Remapping: Because Boot Services no longer exist, the OS only remaps regions marked for Runtime Services. Through the SetVirtualAddressMap() runtime call, the OS assigns new virtual addresses to persistent firmware components, completely discarding the transient physical-to-virtual mappings used during the boot phase.