UEFI基础知识学习2

发布时间:2026/6/26 3:34:36

UEFI基础知识学习2 一、 UEFI Driver Binding 模型1、简要描述UEFI Driver Binding 是 UEFI Driver 管理设备的标准模型。UEFI Driver 加载后通过安装EFI_DRIVER_BINDING_PROTOCOL到Driver Image Handle上向系统声明自己可以识别、启动和停止某类设备Controller。2、核心函数EFI_DRIVER_BINDING_PROTOCOL包含三个核心函数Support、Start和Stop。typedefstruct_EFI_DRIVER_BINDING_PROTOCOL{EFI_DRIVER_BINDING_SUPPORTED Supported;//判断该Driver是否支持某个 Controller。EFI_DRIVER_BINDING_START Start;//启动 Controller打开 Protocol安装 Protocol。EFI_DRIVER_BINDING_STOP Stop;//停止 Controller关闭 Protocol卸载 Protocol。UINT32 Version;//驱动优先级版本高的优先尝试EFI_HANDLE ImageHandle;//当前Driver镜像的HandleEFI_HANDLE DriverBindingHandle;//安装Driver Binding Protocol的Handle}EFI_DRIVER_BINDING_PROTOCOL;3、运作流程DXE Dispatcher 加载 Driver Image | v DriverEntryPoint 执行 //UEFI DXE Driver被加载后最先执行的入口函数 | v 安装 EFI_DRIVER_BINDING_PROTOCOL | v 系统调用 ConnectController() //触发 Driver Binding 流程的 Boot Services 接口 | v 遍历可用 Driver Binding Protocol | v 调用 Supported() | v 如果支持调用 Start() | v Driver 打开底层 Protocol初始化设备 | v Driver 安装新的 Protocol | v 需要断开时调用 DisconnectController() | v 触发 Stop()4、ControllerHandle、DriverBindingHandle 和 ChildHandleHandle说明DriverBindingHandle驱动自身的HandleControllerHandle被驱动管理的设备对象ChildHandleBus Driver枚举出的子设备对象例如USB Bus Driver | |DriverBindingHandle v USB Controller | |ControllerHandle v USB Device 1: U盘 -- ChildHandle USB Device 2: 键盘 -- ChildHandle USB Device 3: 鼠标 -- ChildHandle5、Driver 类型类型作用是否创建ChildHandleDevice Driver直接驱动某个设备通常不会创建Bus Driver枚举总线上的子设备通常会创建Hybrid Driver同时具备设备驱动和总线驱动能力执行总线时会创建6、OpenProtocol在Driver Binding模型中OpenProtocol()起到获取接口、记录驱动和设备之间的管理关系的作用。三个重要的Attributes参数EFI_OPEN_PROTOCOL_BY_DRIVER //获取接口不表示接管设备。 EFI_OPEN_PROTOCOL_GET_PROTOCOL //表示这个 Driver 正式接管这个 Controller。 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER //Bus Driver 创建 Child Handle 时使用。ChildHandle创建流程Bus Driver 在 Start() 里枚举到子设备 创建 ChildHandle 安装 Device Path Protocol 安装描述这个子设备的 Protocol 用 OpenProtocol BY_CHILD_CONTROLLER 建立父子关系7、常见案例——USB U盘出现fs0:1DXE Dispatcher 加载 USB Bus Driver 2USB Bus Driver 安装 Driver Binding Protocol 3ConnectController() 尝试连接 USB Controller 4调用 USB Bus Driver 的 Supported() 5Supported() 判断 Controller 支持 USB 6调用 Start() 7Start() 初始化 USB Controller 8枚举 USB 设备 9为 U 盘创建 ChildHandle 10安装相关 USB Protocol 11后续 Mass Storage Driver 连接这个 ChildHandle 12安装 Block IO Protocol 13文件系统 Driver 发现 Block IO Protocol 14安装 Simple File System Protocol 15Shell 看到 fs0:8、常见源码位置MdePkg/Include/Protocol/DriverBinding.h MdeModulePkg/Bus/Pci/PciBusDxe/ MdeModulePkg/Bus/Usb/UsbBusDxe/ MdeModulePkg/Universal/Disk/9、QA1Driver Binding 是什么UEFI Driver Binding 是 UEFI 驱动管理设备的标准模型用来判断、启动和停止某个设备 Controller。2Supported / Start / Stop 分别做什么Supported()判断驱动是否支持这个设备。Start()真正启动设备打开底层 Protocol初始化设备并安装新的 Protocol。Stop()停止设备关闭 Protocol卸载 Protocol释放资源。3Device Driver 和 Bus Driver 有什么区别Device Driver直接驱动某个具体设备。Bus Driver管理一条总线并枚举出子设备也就是ChildHandle。4OpenProtocol BY_DRIVER是什么意思表示这个 Driver 要以驱动身份打开某个 Protocol并正式接管这个 Controller。二、Event 与 Timer 机制1、简要描述Event 是 UEFI 中的事件通知机制Timer 是一种可以按时间触发的 Event。它们用于异步通知、定时任务、等待用户输入、阶段退出回调等场景。2、Event1Event 常见用途在DXE阶段常用等待某个事件发生如键盘输入或某个 Protocol 被安装。定时触发回调。在某个阶段发生时收到通知如ExitBootServices时通知驱动清理资源。VirtualAddressChange 时通知 Runtime Driver 转换地址。Protocol 安装后触发 notify。2Event接口类型详细作用创建 EventCreateEvent()CreateEventEx()创建一个 Event等待事件、通知事件或 Timer 事件触发 EventSignalEvent()主动触发一个 Event让它变成“已发生”状态等待 EventWaitForEvent()等待一个或多个 Event 发生常用于等待键盘输入等检查 EventCheckEvent()检查某个 Event 是否已经发生不阻塞等待关闭 EventCloseEvent()关闭 Event释放相关资源设置 TimerSetTimer()给 Event 设置定时触发方式实例1自己创建、触发、等待、释放 Event。gBS-CreateEvent(Type,NotifyTpl,NotifyFunction,NotifyContext,Event);gBS-SignalEvent(Event);gBS-WaitForEvent(1,Event,Index);gBS-CloseEvent(Event);2等待键盘输入gBS-WaitForEvent(1,gST-ConIn-WaitForKey,Index);3Event类型EVT_NOTIFY_SIGNAL //Event 被 Signal 时执行回调函数。 EVT_NOTIFY_WAIT //当有人等待或检查这个 Event 时执行回调函数。 EVT_TIMER //表示这个 Event 可以被 Timer 触发和 SetTimer() 配合使用。4NotifyFunctionEvent 发生后系统调用 NotifyFunctionContext 用来告诉回调函数该处理什么对象。VOID EFIAPINotifyFunction(IN EFI_EVENT Event,IN VOID*Context//创建 Event 时传进去的上下文数据。);3、TimerTimer 不是单独一套机制而是挂在 Event 上的定时触发能力。1TPLTPL 是 Task Priority Level表示事件回调执行时的任务优先级。常见 TPLTPL说明TPL_APPLICATION普通应用级别TPL_CALLBACK普通回调常用TPL_NOTIFY较高优先级通知回调TPL_HIGH_LEVEL最高级别通常不应随意使用2Timer类型类型作用TimerCancel取消定时器TimerPeriodic周期性触发TimerRelative延迟一次触发注意UEFI Timer 的时间单位是100nsgBS-SetTimer(Event, TimerPeriodic, 10000000);的意思是大约每 1 秒触发一次。3通用流程CreateEvent 创建带 EVT_TIMER 的 Event | SetTimer 设置定时方式 | 时间到 | Event 被触发 | 执行 NotifyFunction | CloseEvent 关闭 Event4、源码位置MdeModulePkg/Core/Dxe/Event/ MdePkg/Include/Uefi/UefiSpec.h MdePkg/Include/Guid/EventGroup.h三、Variable Services 与 NVRAM 存储1、简要描述UEFI Variable 是BIOS/UEFI 提供的一套键值存储机制。数据通常保存在NVRAM中掉电后依然存在。Variable Services 属于 Runtime Services所以部分变量在 OS runtime 阶段仍可访问。2、Variable 的组成要素含义VariableName变量名Unicode 字符串VendorGUID变量命名空间避免不同厂商变量重名Data变量数据Attributes变量属性决定变量能在哪些阶段访问、是否掉电保存等3、Variable Services常用接口主要都在Runtime Services中gRT-GetVariable()//读取变量gRT-SetVariable()//创建、修改或删除变量gRT-GetNextVariableName()//枚举变量gRT-QueryVariableInfo()//查询变量存储空间信息4、NVRAM非易失性存储区域Non-Volatile RAM保存于SPI Flash的某个变量存储区域中。典型实现中Variable Runtime DXE 负责变量服务逻辑Fault Tolerant Write 负责可靠写 FlashVariable Store 负责组织变量数据结构。厂商 BIOS 可能会在此基础上加入权限、锁定、安全启动、恢复机制等。5、Variable Attributes属性说明EFI_VARIABLE_NON_VOLATILE掉电保留EFI_VARIABLE_BOOTSERVICE_ACCESSBoot Services 阶段可访问EFI_VARIABLE_RUNTIME_ACCESSOS Runtime 阶段可访问EFI_VARIABLE_HARDWARE_ERROR_RECORD硬件错误记录EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS基于时间的认证写入EFI_VARIABLE_APPEND_WRITE追加写入6、GetVariable和SetVariableGetVariable读取流程DataSize 0Data NULL | v 第一次调用 GetVariable() | v 返回 EFI_BUFFER_TOO_SMALL | v UEFI 把真正需要的大小写回 DataSize | v AllocatePool(DataSize) 分配缓冲区 | v 第二次调用 GetVariable() | v 变量数据被读取到 Data 中 | v 使用变量数据 | v FreePool(Data) 释放缓冲区SetVariable会修改 NVRAM以下变量不能随意修改BootOrder Boot#### Setup PK / KEK / db / dbx Secure Boot 相关变量7、GetNextVariableNameGetNextVariableName用于枚举所有变量。gRT-GetNextVariableName()|VariableNameVendorGuid//返回值|gRT-GetVariable()//读取变量的数据和属性8、源码位置MdeModulePkg/Universal/Variable/RuntimeDxe/ MdeModulePkg/Universal/FaultTolerantWriteDxe/ MdePkg/Include/Uefi/UefiSpec.h MdePkg/Include/Guid/GlobalVariable.h四、 Boot Option 与启动项管理1、简要描述Boot Option 是 UEFI 用 Variable 保存和管理启动项的机制。2、关键变量变量作用BootOrder启动项顺序UINT16数组Boot####具体启动项####是四位十六进制编号BootCurrent本次启动所使用的启动项BootNext下一次启动优先生效的启动项只生效一次3、Boot####Boot####的数据通常是EFI_LOAD_OPTION格式UINT32 Attributes //启动项属性是否启用 UINT16 FilePathListLength //Device Path 长度 CHAR16 Description[] //启动项显示名称 FilePathList[] //启动设备/启动文件路径 UINT8 OptionalData[] //可选参数4、BDS 阶段如何使用 Boot OptionBDS 阶段下的流程读取 BootNext | 如果 BootNext 存在优先尝试它并清除 BootNext | 否则读取 BootOrder | 按照顺序读取 Boot#### | 检查启动项是否启用 | 解析 Device Path //EFI_DEVICE_PATH_PROTOCOL | 加载对应 EFI Image | StartImage 启动 | 如果失败尝试下一个启动项5、启动项解析步骤读取 BootOrder 遍历每个 UINT16 编号 拼接 Boot0001 变量名 读取 Boot#### 解析 Attributes 解析 FilePathListLength 解析 Description 解析 Device Path 输出启动项信息6、推荐源码位置MdePkg/Include/Uefi/UefiSpec.h MdePkg/Include/Guid/GlobalVariable.h MdePkg/Include/Protocol/DevicePath.h MdePkg/Library/UefiDevicePathLib/ MdeModulePkg/Universal/BdsDxe/ MdeModulePkg/Library/UefiBootManagerLib/7、QA1Boot Option 是什么Boot Option 是 UEFI 用来描述和管理启动项的机制通常保存在 NVRAM Variable 中。2BootOrder 是什么BootOrder 是启动顺序列表里面保存的是一组 Boot#### 编号。3Boot#### 是什么Boot#### 是具体启动项比如 Windows Boot Manager、USB 启动项、PXE 启动项等。4BootNext 是什么BootNext 是下一次启动临时使用的启动项只生效一次。5Boot#### 里面保存什么保存 EFI_LOAD_OPTION包括启动项属性、显示名称、Device Path 和可选参数。6Boot Option 和 Variable Services 有什么关系Boot Option 本质上就是一组 UEFI Variables。五、Boot Services 与 Runtime Services 区别与应用1、简要内容Boot Services启动阶段用的服务ExitBootServices 后失效。Runtime Services运行时服务进入 OS 后仍可用。2、Boot ServicesBoot Services 是 UEFI 在启动阶段提供的大量服务。作用内存分配 Protocol 管理 Handle 管理 Event / Timer 加载和启动 Image Device Path 操作 驱动连接 等待输入常见接口gBS-AllocatePool() gBS-FreePool() gBS-LocateProtocol() gBS-OpenProtocol() gBS-InstallProtocolInterface() gBS-CreateEvent() gBS-SetTimer() gBS-LoadImage() gBS-StartImage() gBS-ConnectController() gBS-ExitBootServices() //Boot Services 只在 ExitBootServices 之前有效OS Loader 调用 ExitBootServices() 后系统控制权交给 OSBoot Services 就不能再使用了。3、Runtime ServicesRuntime Services 是 UEFI 在 OS 阶段仍然可能保留的服务。作用时间服务 变量服务 系统复位 Capsule Update 虚拟地址转换常见接口gRT-GetTime() gRT-SetTime() gRT-GetVariable() gRT-SetVariable() gRT-GetNextVariableName() gRT-ResetSystem() gRT-UpdateCapsule() gRT-SetVirtualAddressMap() gRT-ConvertPointer() ## Runtime Services 在 ExitBootServices 后仍可能可用。4、生命周期区别对比项Boot ServicesRuntime Services有效期ExitBootServices()前ExitBootServices()后仍可用主要使用者UEFI Driver、UEFI App、BootloaderOS runtime典型功能Protocol、Event、Memory、ImageVariable、Time、Reset内存要求Boot Service Code/DataRuntime Code/Data 必须保留使用场景场景服务枚举 ProtocolBoot Services安装 ProtocolBoot Services分配 Boot 阶段内存Boot Services加载 EFI 文件Boot Services启动 EFI ImageBoot ServicesEvent / TimerBoot Services读写 UEFI VariableRuntime Services获取系统时间Runtime Services重启/关机Runtime ServicesCapsule UpdateRuntime Services5、源码位置MdePkg/Include/Uefi/UefiSpec.h MdeModulePkg/Core/Dxe/ MdeModulePkg/Core/RuntimeDxe/ MdeModulePkg/Universal/Variable/RuntimeDxe/6、QA1Boot Services和Runtime Services的区别是什么ExitBootServices()后 Boot Services 失效Runtime Services 仍可用。2Protocol 相关接口属于哪类属于 Boot Services。3Variable Services 属于哪类属于 Runtime Services.4LoadImage / StartImage 属于哪类属于 Boot Services。

相关新闻