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