一、系统表介绍
对UEFI应用程序和驱动程序开发人员来讲,系统表是最重要的数据结构之一,它是用户空间通往内核空间的通道。有了它,UEFI应用程序和驱动才可以访问UEFI内核、硬件资源和输入/输出设备。
(1)在应用程序和驱动中如何访问系统表
计算机系统进入DXE阶段后系统表被初始化,因而系统表只能用于DXE阶段以及以后的应用程序和驱动中。系统表是UEFI内核的一个全局结构体,其指针作为程序映像(Image)入口函数的参数传递到用户空间。程序映像(包括UEFI应用程序、DXE驱动程序以及UEFI驱动程序)的入口函数有统一的格式,函数原型如下:
EFI_STATUS
EFIAPI
*EFI_IMAGE_ENTRY_POINT(
IN EFI_HANDLE ImageHandle, //程序映像Image的句柄
IN EFI_SYSTEM_TABLE *SystemTable //系统表指针
);
(2)系统表指针从内核传递到用户空间的过程
通常,程序映像的入口函数是_ModuleEntryPoint,当应用程序被加载到内存形成Image后,_ModuleEntryPoint函数地址被赋值给Image对象的EntryPoint,然后Image ->EntryPoint(ImageHandle, SystemTable)会被执行,最终会从Image的入口函数_ModuleEntryPoint执行到模块的入口函数(模块的入口函数是通过.inf文件中的ENTRY_POINT指定的那个函数)。
传递给映像的最重要的参数就是系统表(system table),这是进入一个UEFI映像的入口。系统表包含了指向各种控制设备的指针,指向引导服务表的指针和指向运行服务的指针,指向系统配置表(如ACPI、SMBIOS,SAL系统表)的指针。
EFI System Table的数据结构为:
typedef struct {
EFI_TABLE_HEADER Hdr; //EFI System Table的表头
CHAR16 *FirmwareVendor; //指向一个以null结尾地字符串,标识系统固件的供应商
UINT32 FirmwareRevision; //特定于固件供应商,用于表示固件平台的版本
EFI_HANDLE ConsoleInHandle; //控制输入控制设备的句柄
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; //指向与ConsoleInHandle相关联的EFI_SIMPLE_TEXT_INPUT_PROTOCOL接口的指针。
EFI_HANDLE ConsoleOutHandle;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
EFI_HANDLE StandardErrorHandle; //指向标准错误控制台的指针
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *StdErr;
EFI_RUNTIME_SERVICES *RuntimeServices; //指向运行时服务的指针
EFI_BOOT_SERVICES *BootServices; //指向引导服务的指针
UINTN NumberOfTableEntries; //缓冲区系统配置表的数量
EFI_CONFIGURATION_TABLE *ConfigurationTable; //指向系统配置表的指针
} EFI_SYSTEM_TABLE;
1、在用户空间使用系统表
在模块的入口函数中,系统表的地址可以通过模块入口函数的参数得到
2、在用户空间使用gST访问系统表
在其它函数中可以使用gST变量访问系统表。EDK2为例方便开发者,提供了UefiBootServicesTableLib,在UefiLib中定义了全局变量gST(指向System Table)、gBS(指向SystemTable->BootServices)和gImageHandle(指向ImageHandle)。
二、启动服务表
EFI启动服务表,表中的每一项是一个函数指针,这个函数用于提供一项服务。当操作系统加载器彻底取得对计算机系统的控制权之后,启动服务也就完成了它的使命,启动服务占用的系统资源也需要转交给操作系统加载器。此时需要调用gBS->ExitBootServices,其作用是结束启动服务、释放启动服务占用的资源以及使用启动服务分配得到的启动期资源,将控制权交给操作系统加载器。
extern EFI_BOOT_SERVICES *gBS;
gBS是一个指向启动服务的指针,EFI_BOOT_SERVICES是一个提供一组启动服务的数据结构,其提供的服务有:
Event、Timer、Task Priority Services服务
内存分配服务
Protocol处理服务
Image服务
typedef struct {
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 开启和关闭Protocol服务
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 32位CRS服务(循环冗余校验服务)
EFI_CALCULATE_CRC32 CalculateCrc32;
// Miscellaneous Services 杂项服务
EFI_COPY_MEM CopyMem;
EFI_SET_MEM SetMem;
EFI_CREATE_EVENT_EX CreateEventEx;
} EFI_BOOT_SERVICES;
三、运行时服务
从进入DXE阶段运行时服务被初始化、直到操作系统结束,运行时服务都一直存在并向上层(操作系统、操作系统加载器、UEFI应用程序或UEFI驱动)提供服务。
EFI运行服务表
extern EFI_RUNTIME_SERVICES *gRT;
gRT是指向运行服务表的指针,EFI_RUNTIME_SERVICES是一个提供一组运行时服务的数据结构,所提供的服务有:
运行时规则和限制
Variable服务
时间服务
虚拟内存服务
杂项服务
/// EFI Runtime Services Table.
typedef struct {
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 UEFI2.0 胶囊服务
EFI_UPDATE_CAPSULE UpdateCapsule;
EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities;
// Miscellaneous UEFI 2.0 Service UEFI2.0 杂项服务
EFI_QUERY_VARIABLE_INFO QueryVariableInfo;
} EFI_RUNTIME_SERVICES;