UEFI Depex in DXE Driver Dispatching

The Dependency Expression (Depex) language in the Unified Extensible Firmware Interface (UEFI) is a specialized grammar that dictates the precise execution order of Driver Execution Environment (DXE) drivers. Because UEFI firmware is inherently modular and distributed across independent binaries within Firmware Volumes (FVs), drivers frequently depend on protocols produced by other drivers before they can function. The Depex language provides the DXE Dispatcher with the conditional logic required to evaluate whether a driver’s functional prerequisites have been met in the protocol database, preventing premature execution, dependency deadlocks, and system initialization failures.

The Role and Purpose of Depex

During the DXE phase, the platform discovers hardware and initializes core system services. DXE drivers are typically self-contained PE32/PE32+ images that expose interfaces called protocols. Many drivers require access to specific protocols produced by underlying silicon or bus drivers; for instance, a generic storage driver cannot initialize without an underlying controller protocol.

The Depex grammar solves this ordering problem. Instead of relying on hardcoded, platform-specific initialization sequences, driver developers embed a Depex section directly into the driver’s Firmware File System (FFS) file. This decouples individual drivers from static build orders and allows dynamic, modular dispatch based purely on protocol availability.

Architecture and Syntax

A Depex expression is compiled from source code into a compact, stack-based bytecode format interpreted by the DXE Dispatcher. The grammar functions similarly to Reverse Polish Notation (RPN) and consists of:

  • GUIDs: 128-bit identifiers representing the specific protocols required by the driver.
  • Logical Operators: Instructions such as AND, OR, and NOT used to construct complex conditional requirements.
  • Terminal Statements: Operators such as END, which marks the conclusion of the expression, and boolean constants like TRUE or FALSE. A driver with a TRUE expression signals that it has no protocol prerequisites and can execute immediately upon discovery.

How the DXE Dispatcher Evaluates Depex

The DXE Dispatcher operates as a state machine that systematically moves through Firmware Volumes in iterative passes:

  1. Discovery: The dispatcher discovers driver binaries and parses their embedded EFI_SECTION_DXE_DEPEX metadata.
  2. Stack-Based Evaluation: For each driver waiting in the queue, the dispatcher processes the compiled Depex bytecode against the global UEFI Protocol Database. It pushes boolean results onto an internal stack—evaluating TRUE if a referenced protocol GUID is registered and FALSE if it is absent.
  3. Execution (Dispatch): If the final evaluation of the expression yields TRUE, the dispatcher loads the driver's image into memory, invokes its entry point, and marks the driver as dispatched.
  4. Dispatcher Loop: As newly executed drivers register their own protocols, the dispatcher triggers another pass through the un-dispatched queue. This re-evaluates previously unsatisfied Depex expressions until no further drivers can be dispatched.

Interaction with the A Priori File

While Depex handles dynamic ordering, firmware designers occasionally need foundational architectural protocols initialized before standard dependency resolution begins. The DXE Dispatcher supports an optional A Priori list—a special file within a Firmware Volume that specifies an explicit, pre-Depex execution list. Drivers enumerated in the A Priori list bypass their normal Depex evaluation and run first, ensuring the core infrastructure required to register initial protocols and run the dispatcher itself is firmly established.

System Impact

Through the Depex language, the UEFI framework achieves deterministic hardware initialization while maintaining strict driver isolation. It eliminates race conditions during boot, minimizes memory overhead by ensuring drivers load only when ready, and allows hardware vendors to produce portable, independent drivers that integrate reliably across diverse platform architectures.