4 - EFI System Table
本章节主要介绍的是 UEFI Image 的 Entry point(在 UEFI 固件执行的时候,都是直接调用入口函数并且执行从而调用其他的 driver)。
UEFI Image 主要是有三类:UEFI boot service driver、UEFI runtime driver 以及 UEFI application.三种 UEFI image 的 entry point 没有什么区别。
4.1 UEFI Image Entry Point
- 传递给映像的最重要的参数是指向系统表的指针。这个指针是EFI_IMAGE_ENTRY_POINT(见下面的定义),是UEFI映像的主要Entry Point。系统表包含指向活动控制台设备的指针、指向引导服务表的指针、指向运行时服务表的指针,以及指向系统配置表(如ACPI、SMBIOS和SAL系统表)列表的指针。
EFI_IMAGE_ENTRY_POINT :这是UEFI映像的主要入口点。这个入口点对于UEFI应用程序和UEFI驱动程序是相同的。
typedef
EFI_STATUS
(EFIAPI *EFI_IMAGE_ENTRY_POINT) (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
参数:
- ImageHandle:image 的 Hanle,是由固件分配的
- SystemTable:指向 system table 的指针
这个函数是一个EFl图像的入口点。EFI映像通过EFI引导服务EFI_BOOT_SERVICES.LoadImage()加载并重新定位到系统内存中。。EFI映像是通过EFI引导服务EFI_BOOT_SERVICES.StartImage()调用的。系统表包含标准输出和输入句柄,以及指向EFI_BOOT_SERVICES和EFI_RUNTIME_SERVICES表的指针。服务表包含固件中的入口点,用于访问核心EFI系统功能。
系统表中的句柄用于获得对控制台的基本访问。此外,系统表中还包含了指向其他标准表的指针,如果相关指针被初始化为非零值,则加载映像可以使用这些指针。这些表的例子有ACPI、SMBIOS、SAL系统表等。
ImageHandle 可以看作是一个 driver 的标识符,每个 driver 的 handle 是唯一的,我们可以通过 EFI_INSTALL_PROTOCOL_INTERFACE 在 handle 上安装多个该 driver 需要调用的 protocol .
4.2 EFI Table Header
EFI_TABLE_HEADER数据类型是位于所有标准EFI表类型之前的数据结构。它包括每个表类型的唯一签名,table 的修订版,可以在向EFI表类型添加扩展时更新,以及一个32位的CRC,以便EFI表类型的使用者可以验证EFI表的内容,确认 table 是否被修改。
typedef struct {
///
/// A 64-bit signature that identifies the type of table that follows.
/// Unique signatures have been generated for the EFI System Table,
/// the EFI Boot Services Table, and the EFI Runtime Services Table.
///
UINT64 Signature;
///
/// The revision of the EFI Specification to which this table
/// conforms. The upper 16 bits of this field contain the major
/// revision value, and the lower 16 bits contain the minor revision
/// value. The minor revision values are limited to the range of 00..99.
///
UINT32 Revision;
///
/// The size, in bytes, of the entire table including the EFI_TABLE_HEADER.
///
UINT32 HeaderSize;
///
/// The 32-bit CRC for the entire table. This value is computed by
/// setting this field to 0, and computing the 32-bit CRC for HeaderSize bytes.
///
UINT32 CRC32;
///
/// Reserved field that must be set to 0.
///
UINT32 Reserved;
} EFI_TABLE_HEADER;
4.3 EFI System Table
UEFI使用EFI系统表,其中包含指向运行时和启动服务表的指针。
ExitBootServices()调用之前 EFI系统表的所有字段都有效。在操作系统通过调用ExitBootServices()控制平台之后,只有Hdr, FirmwareVendor, FirmwareRevision, RuntimeServices, NumberOfTableEntries和ConfigurationTable字段有效。
typedef struct {
///
/// The table header for the EFI System Table.
///
EFI_TABLE_HEADER Hdr;
///
/// A pointer to a null terminated string that identifies the vendor
/// that produces the system firmware for the platform.
///
CHAR16 *FirmwareVendor;
///
/// A firmware vendor specific value that identifies the revision
/// of the system firmware for the platform.
///
UINT32 FirmwareRevision;
///
/// The handle for the active console input device. This handle must support
/// EFI_SIMPLE_TEXT_INPUT_PROTOCOL and EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
///
EFI_HANDLE ConsoleInHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL interface that is
/// associated with ConsoleInHandle.
///
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
///
/// The handle for the active console output device.
///
EFI_HANDLE ConsoleOutHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
/// that is associated with ConsoleOutHandle.
///
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
///
/// The handle for the active standard error console device.
/// This handle must support the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
///
EFI_HANDLE StandardErrorHandle;
///
/// A pointer to the EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL interface
/// that is associated with StandardErrorHandle.
///
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
///
/// A pointer to the EFI Runtime Services Table.
///
EFI_RUNTIME_SERVICES *RuntimeServices;
///
/// A pointer to the EFI Boot Services Table.
///
EFI_BOOT_SERVICES *BootServices;
///
/// The number of system configuration tables in the buffer ConfigurationTable.
///
UINTN NumberOfTableEntries;
///
/// A pointer to the system configuration tables.
/// The number of entries in the table is NumberOfTableEntries.
///
EFI_CONFIGURATION_TABLE *ConfigurationTable;
} EFI_SYSTEM_TABLE;
4.4 EFI Boot Services Table
UEFI使用EFI引导服务表,其中包含表头和指向所有引导服务的指针。这个表的定义如下面的代码片段所示。除了表头之外,EFI引导服务表中的所有元素都是函数指针的原型,指向第7节中定义的函数。在操作系统通过调用EFI_BOOT_SERVICES.ExitBootServices()控制平台之后,该表中的函数指针将失效。
///
/// EFI Boot Services Table.
///
typedef struct {
///
/// The table header for the EFI Boot Services Table.
///
EFI_TABLE_HEADER Hdr;
//
// Task Priority Services
//
EFI_RAISE_TPL RaiseTPL;
EFI_RESTORE_TPL RestoreTPL;
//
// Memory Services
//
EFI_ALLOCATE_PAGES AllocatePages;
EFI_FREE_PAGES FreePages;
EFI_GET_MEMORY_MAP GetMemoryMap;
EFI_ALLOCATE_POOL AllocatePool;
EFI_FREE_POOL FreePool;
//
// Event & Timer Services
//
EFI_CREATE_EVENT CreateEvent;
EFI_SET_TIMER SetTimer;
EFI_WAIT_FOR_EVENT WaitForEvent;
EFI_SIGNAL_EVENT SignalEvent;
EFI_CLOSE_EVENT CloseEvent;
EFI_CHECK_EVENT CheckEvent;
//
// Protocol Handler Services
//
EFI_INSTALL_PROTOCOL_INTERFACE InstallProtocolInterface;
EFI_REINSTALL_PROTOCOL_INTERFACE ReinstallProtocolInterface;
EFI_UNINSTALL_PROTOCOL_INTERFACE UninstallProtocolInterface;
EFI_HANDLE_PROTOCOL HandleProtocol;
VOID *Reserved;
EFI_REGISTER_PROTOCOL_NOTIFY RegisterProtocolNotify;
EFI_LOCATE_HANDLE LocateHandle;
EFI_LOCATE_DEVICE_PATH LocateDevicePath;
EFI_INSTALL_CONFIGURATION_TABLE InstallConfigurationTable;
//
// Image Services
//
EFI_IMAGE_LOAD LoadImage;
EFI_IMAGE_START StartImage;
EFI_EXIT Exit;
EFI_IMAGE_UNLOAD UnloadImage;
EFI_EXIT_BOOT_SERVICES ExitBootServices;
//
// Miscellaneous Services
//
EFI_GET_NEXT_MONOTONIC_COUNT GetNextMonotonicCount;
EFI_STALL Stall;
EFI_SET_WATCHDOG_TIMER SetWatchdogTimer;
//
// DriverSupport Services
//
EFI_CONNECT_CONTROLLER ConnectController;
EFI_DISCONNECT_CONTROLLER DisconnectController;
//
// Open and Close Protocol Services
//
EFI_OPEN_PROTOCOL OpenProtocol;
EFI_CLOSE_PROTOCOL CloseProtocol;
EFI_OPEN_PROTOCOL_INFORMATION OpenProtocolInformation;
//
// Library Services
//
EFI_PROTOCOLS_PER_HANDLE ProtocolsPerHandle;
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer;
EFI_LOCATE_PROTOCOL LocateProtocol;
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces;
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces;
//
// 32-bit CRC Services
//
EFI_CALCULATE_CRC32 CalculateCrc32;
//
// Miscellaneous Services
//
EFI_COPY_MEM CopyMem;
EFI_SET_MEM SetMem;
EFI_CREATE_EVENT_EX CreateEventEx;
} EFI_BOOT_SERVICES;
4.5 EFI Runtime Services Table
UEFI使用EFI运行时服务表,它包含一个表头和指向所有运行时服务的指针。这个表的定义如下面的代码片段所示。除了表头之外,EFI Runtime Services Tables中的所有元素都是函数指针的原型,指向第8节中定义的函数。与EFI启动服务表不同,这个表和它包含的函数指针在UEFI操作系统加载程序和操作系统通过调用EFI_BOOT_SERVICES.ExitBootServices()控制平台后有效。如果操作系统调用SetVirtualAddressMap(),则该表中的函数指针将固定到指向新的虚拟映射入口点。
///
/// EFI Runtime Services Table.
///
typedef struct {
///
/// The table header for the EFI Runtime Services Table.
///
EFI_TABLE_HEADER Hdr;
//
// Time Services
//
EFI_GET_TIME GetTime;
EFI_SET_TIME SetTime;
EFI_GET_WAKEUP_TIME GetWakeupTime;
EFI_SET_WAKEUP_TIME SetWakeupTime;
//
// Virtual Memory Services
//
EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;
EFI_CONVERT_POINTER ConvertPointer;
//
// Variable Services
//
EFI_GET_VARIABLE GetVariable;
EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;
EFI_SET_VARIABLE SetVariable;
//
// Miscellaneous Services
//
EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount;
EFI_RESET_SYSTEM ResetSystem;
//
// UEFI 2.0 Capsule Services
//
EFI_UPDATE_CAPSULE UpdateCapsule;
EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities;
//
// Miscellaneous UEFI 2.0 Service
//
EFI_QUERY_VARIABLE_INFO QueryVariableInfo;
} EFI_RUNTIME_SERVICES;
4.6 EFI Configuration Table & Properties Table
EFI配置表是EFI系统表中的ConfigurationTable字段。该表包含一组GUID/指针对。该表的每个元素都由下面的EFI_CONFIGURATION_TABLE结构描述。配置表类型的数量预计会随着时间的推移而增加。这就是为什么使用GUID来标识配置表类型的原因。EFI配置表每种表类型最多只能包含一个实例。
///
/// Contains a set of GUID/pointer pairs comprised of the ConfigurationTable field in the
/// EFI System Table.
///
typedef struct {
///
/// The 128-bit GUID value that uniquely identifies the system configuration table.
///
EFI_GUID VendorGuid;
///
/// A pointer to the table associated with VendorGuid.
///
VOID *VendorTable;
} EFI_CONFIGURATION_TABLE;