How UEFI Drivers Register Protocols in DXE
This article explains how UEFI drivers publish and register protocols during the Driver Execution Environment (DXE) phase. In UEFI architecture, protocols act as standardized interfaces enabling inter-module communication. Drivers register these interfaces by attaching them to handles via DXE Core Boot Services, allowing other drivers, system applications, and the firmware core to discover, bind, and execute protocol-defined functionality.
The Role of Protocols and Handles
In the DXE environment, communication is fundamentally modular. A
protocol is a C structure containing function pointers and data
structures, uniquely identified by a 128-bit Globally Unique Identifier
(EFI_GUID). Protocols do not exist in isolation; they are
attached to an EFI_HANDLE. A handle is an opaque pointer
maintained by the DXE Core that serves as a container for one or more
protocols representing a device, a controller, or an abstract system
service.
Core Registration APIs
To register a protocol, a DXE driver uses the UEFI Boot Services
table (EFI_BOOT_SERVICES, commonly accessible via the
global pointer gBS). The two primary functions used for
registration are:
gBS->InstallProtocolInterface(): Installs a single protocol interface onto an existing handle or creates a new handle if the handle pointer is initialized toNULL.gBS->InstallMultipleProtocolInterfaces(): A variable-argument function that can install multiple protocols onto a single handle atomically. This is generally preferred for modern drivers because it reduces overhead and avoids race conditions.
The Registration Process
Protocol Definition: The driver defines the protocol structure containing pointers to its internal functions and defines the unique
EFI_GUIDcorresponding to that protocol.Handle Allocation and Binding: Within the driver's entry point (e.g.,
UefiMainorInitializeDriver), the driver prepares the interface instance. If the protocol represents a new service or virtual device, the driver initializes anEFI_HANDLEvariable toNULL. If the driver is augmenting an existing hardware device, it uses the device's existing handle.Invoking Boot Services: The driver calls
InstallMultipleProtocolInterfaces(), passing:- The address of the target
EFI_HANDLE. - The protocol's
EFI_GUID. - The pointer to the protocol's interface structure.
- A terminating
NULLparameter.
- The address of the target
EFI_STATUS Status;
EFI_HANDLE DriverHandle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&DriverHandle,
&gMyCustomProtocolGuid,
&mMyCustomProtocolInstance,
NULL
);- Handle Database Update: Upon receiving the call,
the DXE Core creates a handle entry (if
NULLwas passed) and links the protocol GUID and interface pointer to that handle in the global DXE handle database.
Notification and Consumption by Other Modules
Once a protocol is registered, the DXE Core signals any protocol
notification events registered via
gBS->RegisterProtocolNotify(). This mechanism allows
dependent drivers to stay dormant until their prerequisite protocols are
installed.
Other DXE modules can then locate and consume the registered protocol using one of several methods:
gBS->LocateProtocol(): Finds the first available instance of a protocol in the system.gBS->OpenProtocol(): Opens a protocol on a specific handle with defined attributes, ensuring proper tracking of driver-to-device bindings.gBS->LocateHandleBuffer(): Retrieves all handles that support a specific protocol GUID, enabling drivers to iterate over multiple instances of an interface across the platform.