UEFI notes
Structures
Services
typedef struct { Hdr; // 0x00 RaiseTPL; // 0x18 RestoreTPL; // 0x20 AllocatePages; // 0x28 FreePages; // 0x30 GetMemoryMap; // 0x38 AllocatePool; // 0x40 FreePool; // 0x48 CreateEvent; // 0x50 SetTimer; // 0x58 WaitForEvent; // 0x60 SignalEvent; // 0x68 CloseEvent; // 0x70 CheckEvent; // 0x78 InstallProtocolInterface; // 0x80 ReinstallProtocolInterface; // 0x88 UninstallProtocolInterface; // 0x90 HandleProtocol; // 0x98 Reserved; // 0xa0 RegisterProtocolNotify; // 0xa8 LocateHandle; // 0xb0 LocateDevicePath; // 0xb8 InstallConfigurationTable; // 0xc0 LoadImage; // 0xc8 StartImage; // 0xd0 Exit; // 0xd8 UnloadImage; // 0xe0 ExitBootServices; // 0xe8 GetNextMonotonicCount; // 0xf0 Stall; // 0xf8 SetWatchdogTimer; // 0x100 ConnectController; // 0x108 DisconnectController; // 0x110 OpenProtocol; // 0x118 CloseProtocol; // 0x120 OpenProtocolInformation; // 0x128 ProtocolsPerHandle; // 0x130 LocateHandleBuffer; // 0x138 LocateProtocol; // 0x140 InstallMultipleProtocolInterfaces; // 0x148 UninstallMultipleProtocolInterfaces; // 0x150 CalculateCrc32; // 0x158 CopyMem; // 0x160 SetMem; // 0x168 CreateEventEx; // 0x170 } EFI_BOOT_SERVICES;
typedef struct { EFI_TABLE_HEADER Hdr; // 0x00 CHAR16 *FirmwareVendor; // 0x18 UINT32 FirmwareRevision; // 0x20 EFI_HANDLE ConsoleInHandle; // 0x28 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; // 0x30 EFI_HANDLE ConsoleOutHandle; // 0x38 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut; // 0x40 EFI_HANDLE StandardErrorHandle; // 0x48 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr; // 0x50 EFI_RUNTIME_SERVICES *RuntimeServices; // 0x58 EFI_BOOT_SERVICES *BootServices; // 0x60 UINTN NumberOfTableEntries; // 0x68 EFI_CONFIGURATION_TABLE *ConfigurationTable; // 0x70 } EFI_SYSTEM_TABLE;
NVRAM
typedef struct NVAR_ENTRY_HEADER_ { uint32_t Signature; // 0x00 'NVAR' = 0x5241564e uint16_t Size; // 0x04 Size of the entry including header, MSB first uint8_t Next[3](3); // 0x06 Offset to the next entry in a list, or empty if latest in the list, MSB first uint8_t Attributes; // 0x09 Attributes } NVAR_ENTRY_HEADER; #define NVRAM_NVAR_ENTRY_RUNTIME 0x01 #define NVRAM_NVAR_ENTRY_ASCII_NAME 0x02 #define NVRAM_NVAR_ENTRY_GUID 0x04 #define NVRAM_NVAR_ENTRY_DATA_ONLY 0x08 #define NVRAM_NVAR_ENTRY_EXT_HEADER 0x10 #define NVRAM_NVAR_ENTRY_HW_ERROR_RECORD 0x20 #define NVRAM_NVAR_ENTRY_AUTH_WRITE 0x40 #define NVRAM_NVAR_ENTRY_VALID 0x80 #define NVRAM_NVAR_ENTRY_EXT_CHECKSUM 0x01 #define NVRAM_NVAR_ENTRY_EXT_AUTH_WRITE 0x10 #define NVRAM_NVAR_ENTRY_EXT_TIME_BASED 0x20 #define NVRAM_NVAR_ENTRY_EXT_UNKNOWN_MASK 0xCE
Calling conventions
- Calling convention is Microsoft x64: RCX, RDX, R8, R9
- DXE Driver Entry point: ImageHandle, *SystemTable
Firmware file system
FV
Firmware volumes are typical flash page aligned and contain an unspecified number of firmware files (FFS) that are 8-byte aligned and concatenated together. Empty spsace is 0xFF and there is usually nothing to indicate where it begins.
- Firmware Volume Header ("
_FVH
")
typedef struct { UINT8 ZeroVector[16](16); // 0x00 EFI_GUID FileSystemGuid; // 0x10 UINT64 FvLength; // 0x20 (64-bit) UINT32 Signature; // 0x28 ('_FVH') EFI_FVB_ATTRIBUTES Attributes; // 0x2C (uint32_t) UINT16 HeaderLength; // 0x30 (should be 0x48) UINT16 Checksum; // 0x32 UINT8 Reserved[3](3); // 0x34 UINT8 Revision; // 0x37 (should be 2) EFI_FV_BLOCK_MAP_ENTRY FvBlockMap[2](2); // 0x38 (unused) } EFI_FIRMWARE_VOLUME_HEADER; // 0x48 bytes
FFS
Files in a firmware volume must start on an 8-byte alignment and each consist of multiple 4-byte aligned sections. The header sum is over the first 0x17 bytes of the header with both the header_sum and file_sum set to zero, and does include the state field. The length does not include the alignment padding.
// File header typedef struct EFI_GUID Name; // 0x00 UINT8 Header_sum; // 0x10 UINT8 File_sum; // 0x11 -- 0xAA for not sumed UINT8 Type; // 0x12 UINT8 Attributes; // 0x13 UINT8 Size[3](3); // 0x14 -- LSB first UINT8 State; // 0x17 -- 0xF8 == good } EFI_FFS_FILE_HEADER; // 0x18 bytes total // Large file header for FFSv3 typedef struct { EFI_GUID Name; // 0x00 UINT8 Header_sum; // 0x10 UINT8 File_sum; // 0x11 -- 0xAA for not sumed UINT8 Type; // 0x12 UINT8 Attributes; // 0x13 UINT8 Size[3](3); // 0x14 -- 0xFFFFFF UINT8 State; // 0x17 -- 0xF8 == good UINT64 ExtendedSize; // 0x18 } EFI_FFS_FILE_HEADER2; // 0x20 total bytes
Sections
Each FFS consists of a concatenation of sections. The typical DXE driver has a UI section with its name, a PE32 section with the code, a DEPEX section with its dependencies and a VERSION section with 1.0 in UCS16. The length does not include the alignment padding.
typedef struct { UINT8 Size[3](3); // 0x00 - LSB UINT8 Type; // 0x03 } EFI_COMMON_SECTION_HEADER; // 0x04 total bytes // Large file common section header only valid in FFSv3 typedef struct { UINT8 Size[3](3); // 0x00 -- 0xFFFFFF UINT8 Type; // 0x03 UINT32 ExtendedSize; // 0x04 } EFI_COMMON_SECTION_HEADER2; // 0x08 total bytes
Glossary
- See also Phoenix acronoym list
- PEI: Pre-EFI Initialization (what runs before DXE)
- DXE: Device Execution Environment (what runs before OS)
- Smm: System Management Mode
- Ppm: Process Power Management