UEFI运行时驱动与Windows内核驱动通信的可行方案咨询
问题描述
需要在UEFI运行时驱动中设置UINT类型标志,供Windows内核驱动读取,但使用gRT->SetVariable接口遇到障碍:
ExitBootServices后调用该接口会导致VMware虚拟机触发三重故障(日志记录vcpu-0 Triple fault),进而触发VMware断言错误并崩溃;- 若仅设置
EFI_VARIABLE_RUNTIME_ACCESS属性,接口返回"invalid parameter"错误(符合UEFI规范要求:运行时可访问的变量必须同时具备EFI_VARIABLE_BOOTSERVICE_ACCESS权限); - 仅在
ExitBootServices之前的启动阶段能正常设置该变量。
相关调用代码:
Status = gRT->SetVariable( VariableName, &MyGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(flagValue), &flagValue );
可行替代方案
1. 复用ACPI表自定义区域
在UEFI启动阶段(ExitBootServices前)修改ACPI表中预留的自定义字段写入标志值。Windows内核驱动通过AcpiGetTable系列API读取对应ACPI表,解析自定义字段获取数据。需注意更新ACPI表校验和,避免系统ACPI校验失败;优先选择不影响系统功能的预留区域或自定义小型ACPI设备节点。
2. 使用CMOS RAM存储
利用x86平台CMOS RAM(通过0x70/0x71端口访问)中未被系统占用的寄存器存储标志值。UEFI驱动可通过端口IO直接写入(运行时环境需确保IO权限),Windows内核驱动通过READ_PORT_UCHAR/WRITE_PORT_UCHAR访问对应端口读取。需提前确认目标寄存器未被BIOS/UEFI或Windows占用,避免冲突。
3. 自定义SMI机制传递
在UEFI启动阶段配置SMRAM共享区域,UEFI运行时驱动通过触发SMI将标志值写入该区域;Windows内核驱动通过IoRequestSmi或自定义接口触发SMI,由SMI handler从共享区域读取数据返回。需确保SMI handler逻辑正确,同时注意Windows平台对自定义SMI的安全限制。
4. 利用PCI配置空间预留寄存器
选择未使用的PCI设备(或虚拟PCI设备),在其配置空间预留寄存器存储标志值。UEFI运行时驱动通过EFI_PCI_IO_PROTOCOL写入,Windows内核驱动通过ZwReadPciConfigSpace或WDF的WdfPciExpressReadConfig读取。需确认目标设备及寄存器未被系统或其他驱动占用,虚拟设备需在UEFI阶段完成初始化。
5. 内存保留区域预存
在ExitBootServices前分配一块标记为EFI_MEMORY_RESERVED的内存区域存入标志值,UEFI运行时驱动在运行阶段更新该区域内容(需确保内存未被系统回收)。Windows内核驱动通过MmMapIoSpace映射该保留内存读取数据。需通过GetMemoryMap确认内存区域的安全性,避免被系统分配占用。
内容的提问来源于stack exchange,提问作者OneAndOnly

