EsrtDxe is a UEFI DXE driver that manages the EFI System Resource Table (ESRT),
the mechanism by which UEFI firmware reports updatable firmware components to
the operating system. The OS uses the ESRT to discover which firmware devices
support capsule-based updates and their current version/status.
This driver is part of MdeModulePkg/Universal/EsrtDxe in the EDK2 source tree.
| Field | Value |
|---|---|
| Module | EsrtDxe.efi |
| Size | 0x27e0 bytes (10,208 bytes) |
| Architecture | X64 |
| Base Address | 0x0 (relocatable) |
| MD5 | bfbebf10d01756d5fbd879ba69cf4e57 |
| Source | Lenovo HR650X BIOS (HR6N0XMLK build) |
| Compiler | VS2015, DEBUG build |
| EDK2 Path | MdeModulePkg/Universal/EsrtDxe/EsrtDxe.inf |
| Address | Name | Size | Description |
|---|---|---|---|
| 0x2C0 | InternalCopyMem | 0x42 | Internal memcpy (forward/backward) |
| 0x370 | InternalZeroMem | 0x20 | Internal memset(0) |
| 0x390 | _ModuleEntryPoint | 0x13 | UEFI driver entry point |
| 0x3A4 | EsrtDxeEntryInit | 0x142 | Init globals (gST, gBS, gRT, gDS, HOB list) |
| 0x4E8 | EsrtDxeRegisterCallbacks | 0xE5 | Register events, init locks, install protocols |
| 0x5D0 | EsrtDxeUpdateEntry | 0xA3 | Update ESRT entry (NonFMP -> FMP) |
| 0x674 | EsrtDxeDeleteEntry | 0x95 | Delete ESRT entry (FMP -> NonFMP) |
| 0x70C | EsrtDxeRemoveEntry | 0x4B | Remove entry from NonFMP only |
| 0x758 | EsrtDxeAddEntry | 0x78 | Add entry to NonFMP (if not exists) |
| 0x7D0 | EsrtDxeCollectFmpEntries | 0x492 | Enumerate FMP protocols, collect descriptors |
| 0xC64 | EsrtDxeLockVariables | 0x8D | Lock ESRT variables via Variable Lock protocol |
| 0xCF4 | EsrtDxeNotifyInstallEsrtTable | 0x1E5 | Build combined ESRT table, install config table |
| 0xEDC | EsrtDxeFindAndCopyEntry | 0x108 | Find entry by GUID in repository |
| 0xFE4 | EsrtDxeAppendNonFmpEntry | 0x19D | Append entry to NonFMP repository |
| 0x1184 | EsrtDxeDeleteNonFmpEntry | 0x12C | Delete entry from NonFMP, shift remaining |
| 0x12B0 | EsrtDxeUpdateRepositoryEntry | 0x14E | Update/append entry in repository by GUID |
| 0x1400 | EsrtDxeCopyCollectedEntry | 0x58 | Copy FMP descriptor to collected format |
| 0x1458 | GetDebugOutputProtocol | 0x7F | Locate debug protocol via CMOS check |
| 0x14D8 | DebugPrint | 0x88 | Debug print via CMOS-controlled debug level |
| 0x1560 | DebugAssert | 0x3E | Debug assert via debug protocol |
| 0x15A0 | CopyMem | 0x9E | Bounds-checking memory copy |
| 0x1640 | CompareGuid | 0x67 | 64-bit unaligned GUID comparison |
| 0x16A8 | AllocatePool | 0x2E | gBS->AllocatePool wrapper |
| 0x16D8 | AllocateZeroPool | 0x27 | Allocate + zero memory |
| 0x1700 | FreePool | 0x44 | gBS->FreePool wrapper |
| 0x1744 | EfiGetSystemConfigurationTable | 0xC4 | Look up config table by GUID |
| 0x1808 | EfiInitializeLock | 0x45 | Initialize EFI_LOCK |
| 0x1850 | EfiAcquireLock | 0x76 | Raise TPL, acquire lock |
| 0x18C8 | EfiReleaseLock | 0x5F | Restore TPL, release lock |
| 0x1928 | GetEfiVariable | 0x11A | Read UEFI variable (auto-alloc) |
| 0x1A44 | HobLibConstructor | 0x82 | Initialize HOB list |
| 0x1AC8 | ReadUnaligned64 | 0x2F | Unaligned QWORD read |
| 0x1AF8 | ZeroMem | 0x6E | Bounds-checking memory zero |
| Address | GUID | Purpose |
|---|---|---|
| 0x2400 | CD3D0A05-9E24-437C-A891-1EE053DB7638 |
gEfiEventReadyToBootGuid |
| 0x2410 | 86C77A67-0B97-4633-A187-49104D0685C7 |
gEfiEventVirtualAddressChangeGuid |
| 0x2420 | A340C064-723C-4A9C-A4DD-D5B47A26FBB0 |
ESRT Table protocol GUID (config table) |
| 0x2430 | 7739F24C-93D7-11D4-9A3A-0090273FC14D |
gEfiHobListGuid |
| 0x2440 | B122A263-3661-4F68-9929-78F8B0D62180 |
ESRT Management protocol GUID |
| 0x2450 | 05AD34BA-6F02-4214-952E-4DA0398E2BB9 |
gEfiDxeServicesTableGuid |
| 0x2460 | 999BD818-7DF7-4A9A-A502-9B75033E6A0F |
ESRT variable vendor GUID |
| Variable Name | Type | Description |
|---|---|---|
EsrtFmp |
EFI_SYSTEM_RESOURCE_ENTRY[] |
FMP-sourced ESRT entries |
EsrtNonFmp |
EFI_SYSTEM_RESOURCE_ENTRY[] |
Non-FMP (legacy) ESRT entries |
Both variables use: EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS (attributes = 3).
Boot:
EsrtDxeEntryInit -> Initialize gST, gBS, gRT, gDS, HOB list
EsrtDxeRegisterCallbacks ->
- Create ReadyToBoot event -> EsrtDxeNotifyInstallEsrtTable
- Create VirtualAddrChange event -> EsrtDxeLockVariables
- Install ESRT Management protocol interface
At Runtime (other drivers call these):
EsrtDxeAddEntry(Entry) -> Appends to EsrtNonFmp
EsrtDxeUpdateEntry(Guid) -> Updates EsrtNonFmp (falls back to EsrtFmp)
EsrtDxeDeleteEntry(Guid) -> Deletes from EsrtFmp (fallback EsrtNonFmp)
EsrtDxeRemoveEntry(Guid) -> Deletes from EsrtNonFmp only
EsrtDxeCollectFmpEntries() -> Enumerates FMP protocols, writes EsrtFmp
On ReadyToBoot:
EsrtDxeCollectFmpEntries()
EsrtDxeNotifyInstallEsrtTable() ->
- Read EsrtNonFmp + EsrtFmp variables
- Validate alignment (must be 40-byte aligned)
- Build combined ESRT table (header + entries)
- Install via gBS->InstallConfigurationTable(gEfiEsrtTableProtocolGuid)
On VirtualAddressChange:
EsrtDxeLockVariables() ->
- Use Variable Lock protocol to prevent further writes
+0x00 EFI_GUID FwClass (16 bytes) +0x10 UINT32 FwType (0=Unknown, 1=System, 2=Device) +0x14 UINT32 FwVersion +0x18 UINT32 LowestSupportedFwVersion +0x1C UINT32 CapsuleFlags +0x20 UINT32 LastAttemptVersion +0x24 UINT32 LastAttemptStatus Total: 40 bytes (0x28)
The driver uses two TPL-based locks:
mFmpLock (at unk_24F0, 24 bytes): Protects EsrtFmp variable accessmNonFmpLock (at unk_2508, 24 bytes): Protects EsrtNonFmp variable accessBoth locks operate at TPL_NOTIFY (TPL = 8) and prevent concurrent access
between the FMP enumeration callback and normal ESRT variable operations.
Size == (Size / 40) * 40