Memory Allocation Pools in UEFI Boot Services

This article examines the role and architecture of memory allocation pools in Unified Extensible Firmware Interface (UEFI) Boot Services. It outlines how UEFI firmware manages dynamic memory during the pre-boot phase, the fundamental distinctions between pool-based and page-based memory allocations, and how developers utilize boot service primitives to optimize resource usage before transferring system control to the operating system.

In the UEFI environment, the firmware execution environment relies on Boot Services to manage system resources before the operating system kernel is loaded. Memory management is one of the most critical responsibilities of Boot Services, categorized broadly into page allocation and pool allocation. While page allocation manages physical memory in standard 4 KiB granular blocks, memory allocation pools provide a finer-grained, dynamic allocation mechanism designed for arbitrary buffer sizes.

The primary function of memory allocation pools is to prevent internal memory fragmentation and minimize resource waste. UEFI drivers, firmware components, and pre-boot applications frequently require small chunks of memory to store transient data structures, configuration strings, handles, and device paths. Allocating an entire 4 KiB page for an object requiring only a few dozen bytes would rapidly deplete available physical memory. Pool allocation bridges this gap by carving out small, variable-sized chunks from broader underlying pages.

UEFI Boot Services exposes pool functionality primarily through two API functions: AllocatePool() and FreePool(). When an application calls AllocatePool(), it specifies the desired memory type (such as EfiBootServicesData, EfiBootServicesCode, EfiRuntimeServicesData, or EfiRuntimeServicesCode) and the requested size in bytes. The memory type determines the lifetime and preservation of the memory block:

  • Boot Services Memory: Reclaimed by the operating system after the boot loader calls ExitBootServices(). Most transient pool allocations utilize EfiBootServicesData.
  • Runtime Services Memory: Preserved in memory maps and remains accessible even after the operating system assumes control of the hardware.

Behind the scenes, the firmware’s memory manager services pool requests by maintaining internal free lists for common buffer sizes. When a pool allocation request occurs, the manager matches the request with an available slot in an existing page or allocates a new 4 KiB page from the system map to populate new pool slots. Each allocated pool chunk typically contains an implementation-defined header that records the allocation size and memory type, allowing FreePool() to release the buffer back to the memory pool without requiring the caller to supply the original size.

Memory allocation pools are essential for the scalability, speed, and reliability of the UEFI pre-boot phase. By delivering a mechanism analogous to traditional heap allocation in standard programming environments, pools enable modular firmware drivers and boot loaders to allocate and free arbitrary memory buffers efficiently until the operating system initializes its own virtual memory subsystem.