UEFI Driver Services
为UEFI驱动程序提供的UEFI引导服务和UEFI运行时服务一般可分为三个方面:
- 驱动通常使用
- 很少使用的服务
- 不应该使用的服务
UEFI驱动程序通常使用的服务
下表列出了UEFI驱动程序通常使用的UEFI服务。接下来,讨论将简要描述每种服务,它们为什么被普遍使用,或它们有用的特殊情况。代码示例显示了UEFI驱动程序通常如何使用服务,并如何按服务类型进行分组。
Service | Type | Service Type | Description |
---|---|---|---|
AllocatePool() | Boot | Memory Allocation | Allocates a memory buffer of a particular type. |
AllocatePool() | Boot | Memory Allocation | Allocates a memory buffer of a particular type. |
FreePool() | Boot | Memory Allocation | Frees a previously allocated memory buffer… |
AllocatePages() | Boot | Memory Allocation | Allocates one memory buffer of a particular type with a 4KB aligned start address and a 4KB aligned length… |
FreePages() | Boot | Memory Allocation | Frees a memory buffer previously allocated with AllocatePages(). |
CopyMem() | Boot | Miscellaneous | Copies a buffer from one location to another. |
SetMem() | Boot | Miscellaneous | Initializes the contents of a buffer with a specified value. |
InstallMultipleProtocolInterfa() | Boot | Protocol Handler | Installs one or more protocol interfaces onto a handle. Replaces the InstallProtocolInterface() service… |
UninstallMultipleProtocolInter() | Boot | Protocol Handler | Uninstalls one or more protocol interfaces from a handle. Replaces the UninstallProtocolInterface() service… |
LocateHandleBuffer() | Boot | Protocol Handler | 从符合搜索条件的句柄数据库中检索句柄的列表。返回的缓冲区将被自动分配。. |
LocateProtocol() | Boot | Protocol Handler | 在支持请求协议的句柄数据库中的第一个句柄。 |
OpenProtocol() | Boot | Protocol Handler | 向使用协议接口的代理的列表中添加元素. |
OpenProtocolInformation() | Boot | Protocol Handler | 检索当前正在使用协议接口的代理的列表。 |
CloseProtocol() | Boot | Protocol Handler | 从使用协议接口的代理列表中删除元素。 |
RaiseTPL() | Boot | Task Priority | 提高了任务的优先级级别。 |
RestoreTPL() | Boot | Task Priority | 恢复/降低任务的优先级级别。。 |
CreateEvent() | Boot | Event | 创建一个通用的事件结构。 |
CreateEventEx() | Boot | Event | 创建事件结构作为事件组的一部分 |
CloseEvent() | Boot | Event | 关闭并释放一个事件结构。 |
SignalEvent() | Boot | Event | 触发一个事件。 |
CheckEvent() | Boot | Event | 检查事件是否处于已触发状态。 |
SetTimer() | Boot | Time-related | 设置要在特定时间发出信号的事件。 |
Stall() | Boot | Time-related | 等待指定数量的微秒。 |
InstallMultipleProtocolInterfaces() and UninstallMultipleProtocolInterfaces()
这些服务用于执行以下操作:
- 在句柄数据库中创建新的句柄
- 从句柄数据库中删除一个句柄
- 向句柄数据库中的现有句柄添加协议
- 从句柄数据库中的现有句柄中删除协议
-如果在将协议添加到句柄时产生了任何错误,那么在返回错误之前添加的任何协议都会被安装多协议接口()自动删除。这意味着句柄数据库中的句柄的状态与调用之前的状态相同。
LocateHandleBuffer()
此服务从句柄数据库中检索符合搜索条件的句柄列表。以下是搜索选项:
- 检索所有句柄:检索句柄数据库中的所有句柄。
- 检索ByProtocol:检索句柄数据库中支持指定协议的所有句柄。
- 检索ByRegisterNotify:检索使用RegisterProtocolNotify()为注册通知配置特定协议的句柄,对于UEFI驱动程序,强烈建议使用此搜索选项
OpenProtocol()
使用OpenProtocol(),以防止在驱动程序使用协议时协议被删除。
如果一个层需要跳过一个层以到达一个较低级别的服务,那么使用EFI_OPEN_PROTOCOL_GET_PROTOCOL是安全的,因为如果删除了较低级别的协议,则将通过这些层通知驱动程序。
在EDK II中,最好的例子是FAT驱动程序。FAT驱动程序使用磁盘I/O协议的服务来访问大容量存储设备的内容。
但是,磁盘I/O协议并没有刷新服务。只有块I/O协议具有刷新服务。磁盘I/O驱动程序会打开块I/O协议EFI_OPEN_PROTOCOL_BY_DRIVER,因此FAT驱动程序也不允许打开块I/O协议EFI_OPEN_PROTOCOL_BY_DRIVER。相反,FAT驱动程序必须使用EFI_OPEN_PROTOCOL_GET_PROTOCOL。此方法是安全的,因为当磁盘I/O协议响应于删除块I/O协议时,当删除块I/O协议时,就会间接通知FAT驱动程序。
事件服务
启动服务中事件相关函数有6个,函数名大部分以Event结尾。提供给事件生产者的函数有CreateEvent/CreateEventEx、SignalEvent及CloseEvent。提供给事件使用者的有WaitForEvent和CheckEvent。
WaitForEvent 是阻塞操作,直到Event数组内任一事件被触发,或任一事件导致错误出现,WaitForEvent才返回,如果所有事件都没被触发,则从头开始重新检查。
事件类型
还有两种特殊的事件,它们用在操作系统系统加载器从启动期向运行时期转换的过程
- EVT_SIGNAL_EXIT_BOOT_SERVICES: 此类事件是一种特殊的EVT_NOTIFY_SIGNAL,实际上它是EVT_NOTIFY_SIGNAL和0x0000001的组合。当ExitBootServices()执行时,事件被触发。EVT_SIGNAL_EXIT_BOOT_SERVICES不能和其它类型混合使用。它的Notification函数和子函数不能使用启动服务中的内存分配服务;在Notification函数执行前所有的定时器都已失效,因而在Notification函数中也不能使用定时器服务。
2)EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE:它是EVT_RUNTIME_CONTEXT、EVT_RUNTIME、EVT_NOTIFY_SIGNAL和0x0000002的组合。它不能和这4种类型之外的类型组合使用。当SetVirtualAddressMap()被调用时触发此类事件
UEFI驱动程序很少使用的服务
Service | Type | Service Type | Description |
---|---|---|---|
ConnectController() | Boot | Protocol Handler | 使用一组优先级规则来查找要管理控制器的最佳驱动程序集. |
DisconnectController() | Boot | Protocol Handler | 通知一组驱动程序以停止管理控制器。. |
ReinstallProtocolInterface() | Boot | Protocol Handler | 在设备句柄上重新安装一个协议接口。 |
LocateDevicePath() | Boot | Protocol Handler | 定位支持特定协议并具有最近匹配的设备路径的设备句柄 |
LoadImage() | Boot | Image | 仅供能够加载、启动和可能卸载存储在总线子设备上其他位置的其他图像中的UEFI驱动程序使用。 |
StartImage() | Boot | Image | 仅供能够加载、启动和可能卸载存储在总线子设备上其他位置的其他图像中的UEFI驱动程序使用。. |
GetVariable() | Runtime | Variable | 返回一个变量的值. |
SetVariable() | Runtime | Variable | 设置一个变量的值. |
QueryVariableInfo() | Runtime | Variable | 返回有关EFI变量的信息。… |
GetTime() | Runtime | Time-related | 返回当前的时间和日期,以及平台的计时功能。. |
CalculateCrc32() | Boot | Miscellaneous | 维护UEFI系统表、UEFI引导服务表和UEFI运行时服务表的校验和。 |
ConvertPointer() | Runtime | Miscellaneous | 有时会被UEFI运行时驱动程序使用。UEFI引导服务驱动程序永远不应该使用此服务。 |
InstallConfigurationTable() | Boot | Miscellaneous | 从UEFI系统表中添加、更新或删除一个配置表。 |
WaitForEvent() | Boot | Event | 直到发出事件被唤醒才停止执行。 |
GetNextMonotonicCount() | Boot | Special | 提供了一个64位的单调计数器,并保证会增加。 |
UEFI驱动程序不使用的服务
下表列出了UEFI驱动程序不应该使用的UEFI服务。这些服务可能被UEFI驱动程序以外的组件使用,或者这些服务可能已经被较新的服务所取代,
Service | Type | Service Type | Description |
---|---|---|---|
InstallProtocolInterface() | Boot | Protocol Handler | 已替换为InstallMultipleProtocolInterfaces(). |
UninstallProtocolInterface() | Boot | Protocol Handler | 替换为UninstallMultipleProtocolInterfaces() |
HandleProtocol() | Boot | Protocol Handler | 查询一个句柄,以确定它是否支持指定的协议,替换为OpenProtocol()。 |
LocateHandle() | Boot | Protocol Handler | 定位支持特定协议并具有最近匹配的设备路径的设备句柄 |
ProtocolsPerHandle() | Boot | Protocol Handler | 检索安装在句柄上的协议的列表。返回的缓冲区将被自动分配。此服务已被替换为:UEFI驱动程序绑定协议中的启动函数。 |
RegisterProtocolNotify() | Boot | Protocol Handler | 注册要在为指定协议安装接口时发出信号的事件。此服务已被替换为:UEFI驱动程序绑定协议中支持的()函数。. |
UnloadImage() | Boot | Image | 用于卸载先前加载的UEFI驱动程序。. |
GetNextVariableName() | Runtime | Variable | 用于历通过UEFI变量服务维护的UEFI变量列表。通常不需要使用这项服务。. |
SetWatchDogTimer() | Boot | Timerelated | 返回有关EFI变量的信息。… |
SetTime() | Runtime | Time-related | 设置当前的本地时间和日期信息。UEFI驱动程序不应使用此服务;UEFI驱动程序不应修改系统时间或唤醒计时器。. |
GetWakeupTime() | Runtime | Time-related | 返回当前的唤醒闹钟设置。UEFI驱动程序不应该使用此服务;从UEFI启动管理器管理来计时。。 |
SetWakeupTime() | Runtime | Time-related | 设置系统唤醒闹钟的时间。UEFI驱动程序不应该使用此服务;监视器计时器从UEFI引导管理器进行管理 |
GetMemoryMap() | Boot | Memory Allocation | 返回当前引导服务的内存映射和内存映射键 |
ExitBootServices() | Boot | Special | 该服务将平台的控制从UEFI一致性固件传递到操作系统。UEFI驱动程序必须永远不能使用此服务。 |
SetVirtualAddressMap() | Runtime | Special | 对于希望使用虚拟地址调用UEFI运行时服务的操作系统,只有UEFI操作系统加载器或操作系统内核才会使用此服务。UEFI驱动程序必须永远不能使用此服务。 |
QueryCapsuleCapabilities() | Runtime | Special | Test to see if a capsule or capsules can be updated via UpdateCapsule(). |
UpdateCapsule() | Runtime | Special | 允许操作系统将信息传递给固件。. |
ResetSystem() | Runtime | Special | 重置并设置在引导服务期间使用的看门狗计时器。UEFI驱动程序不应该使用此服务;从UEFI启动管理器管理来计时. |
Exit() | Boot | Special | UEFI驱动程序不应该使用此服务。此服务通常由应用程序使用。. |
GetNextHighMonotonicCount() | Runtime | Special | 提供了一个64位的单调计数器,并保证会增加。 |