> 文章列表 > UEFI Driver Services

UEFI Driver Services

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才返回,如果所有事件都没被触发,则从头开始重新检查。

事件类型

UEFI Driver Services
还有两种特殊的事件,它们用在操作系统系统加载器从启动期向运行时期转换的过程

  1. 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位的单调计数器,并保证会增加。