BIOS开发笔记 15 – WMI 在系统中的集成及应用(下)
一、前言
二、编写 MOF 和 ASL 文件
首先需要创建 MOF 文件,它用于告诉操作系统,我们的 ASL 代码包含了哪些实现。我们在 MOF 文件中定义 2 两个函数,分别是 ReadCmos 和 WriteCmos。
[WMI, Dynamic, Provider("WMIProv"), Locale("MS\0x409"), Guid("{2969FE46-B6AB-40F8-ADE0-C58DBB378674}"), Description("AY123 WMI Example")] class AY123 { [key, read] string InstanceName; [read] boolean Active; [WmiMethodId(1), Implemented, read, write, Description("Read CMOS method") ] void ReadCmos([in, Description("uint8 Index")] uint8 Index,[out, Description("string Data")] string Data); [WmiMethodId(2), Implemented, read, write, Description("Write CMOS method") ] void WriteCmos([in, Description("uint8 Index")] uint8 Index,[in, Description("uint8 Data")] uint8 Data,[out, Description("string status")] string status); };
这一段程序对于没学过面向对象语言的可能有点陌生,但把它当成一个规则就可以了,写的时候注意一下 GUID、函数名称以及输入输出参数即可。需要注意一下的是,标记为 out 的输出参数,在 ASL 中需要 return 相应的参数。
将上面程序保存为 Wmi.mof, 使用如下命令编译:
mofcomp -B:Wmi.bmf "Wmi.mof"
将生成 Wmi.bmf,可以使用 16 进制编辑器打开,导出为数组,可包含在 ASL 代码中的 WQxx method中。
接下来是 ASL 代码的实现:
DefinitionBlock ("", "SSDT", 2, "AY123", "CUSTOM", 0x00000001) { Scope(_SB) { Device (WMIA) { Name (_HID, "PNP0C14") Name (_UID, "AY123WMI") Method (_WDG, 0, NotSerialized) { Return (Buffer() { // GUID: 2969FE46-B6AB-40F8-ADE0-C58DBB378674,与MOF中的GUID保持一致 0x46, 0xFE, 0x69, 0x29, 0xAB, 0xB6, 0xF8, 0x40, 0xAD, 0xE0, 0xC5, 0x8D, 0xBB, 0x37, 0x86, 0x74, 65, 67, // 此 2 byte 为 ASCII 编码,65, 67 对应字符 A,C,则 Object ID (AC) => WMAC 1, // Instance Count 0x02, // Flags (ACPI WMI Method) // // This GUID for returning the MOF data // 0x21, 0x12, 0x90, 0x05, 0x66, 0xd5, 0xd1, 0x11, 0xb2, 0xf0, 0x00, 0xa0, 0xc9, 0x06, 0x29, 0x10, 66, 65, // Object ID (BA) => WQBA 1, // Instance Count 0x00, // Flags }) } Name (WQBA, Buffer() { 0x46, 0x4F, 0x4D, 0x42, 0x01, 0x00, 0x00, 0x00, 0x6F, 0x03, 0x00, 0x00, 0xAE, 0x0B, 0x00, 0x00, 0x44, 0x53, 0x00, 0x01, 0x1A, 0x7D, 0xDA, 0x54, 0xA8, 0xCE, 0x85, 0x00, 0x01, 0x06, 0x18, 0x42, 0x20, 0x34, 0x01, 0x89, 0xC0, 0xA2, 0x69, 0x24, 0xC2, 0x01, 0x0C, 0x46, 0x03, 0x88, 0xE4, 0x40, 0x88, 0x8F, 0xC2, 0x85, 0x90, 0x57, 0x01, 0x36, 0x05, 0x98, 0x04, 0x51, 0xFF, 0xFE, 0x10, 0x25, 0xC1, 0xA1, 0x84, 0x40, 0x48, 0xA2, 0x00, 0xF3, 0x02, 0x74, 0x0B, 0x30, 0x2C, 0xC0, 0xB6, 0x00, 0xD3, 0x02, 0x1C, 0x43, 0x52, 0x69, 0xE0, 0x94, 0xC0, 0x52, 0x20, 0x24, 0x54, 0x80, 0x72, 0x01, 0xBE, 0x05, 0x68, 0x47, 0x94, 0x64, 0x01, 0x96, 0x61, 0x44, 0xE0, 0x51, 0x30, 0x34, 0x0E, 0x8D, 0x1D, 0x86, 0x65, 0x82, 0x69, 0x10, 0x87, 0x51, 0x36, 0xB2, 0x08, 0x8C, 0xDB, 0xA9, 0x00, 0xB9, 0x02, 0x84, 0x09, 0x10, 0x8F, 0x2A, 0x8C, 0xE6, 0xA0, 0x08, 0x5C, 0x68, 0x8C, 0x0C, 0x08, 0x79, 0x14, 0x60, 0x7D, 0x24, 0x84, 0xC0, 0xEE, 0x05, 0x28, 0xC3, 0x94, 0x36, 0x08, 0x69, 0x14, 0x60, 0x11, 0x5A, 0x28, 0x6D, 0x09, 0x50, 0x88, 0x21, 0x83, 0x18, 0x42, 0x39, 0x02, 0x83, 0x15, 0x87, 0x22, 0xA0, 0x13, 0x0C, 0x18, 0x27, 0x4A, 0x87, 0x02, 0xAC, 0x21, 0x09, 0x27, 0x60, 0x84, 0xCE, 0x04, 0x78, 0x83, 0x11, 0x6E, 0x8C, 0xA8, 0xED, 0x0F, 0x82, 0x0C, 0xEA, 0x58, 0x30, 0x62, 0x86, 0x4B, 0x86, 0xD5, 0xF9, 0xC4, 0x34, 0xC0, 0x93, 0x29, 0x5C, 0x80, 0x74, 0x0C, 0x0D, 0xEE, 0x90, 0x13, 0x1C, 0x44, 0xB3, 0x02, 0x8C, 0x8D, 0x47, 0x13, 0x28, 0x68, 0xA4, 0x14, 0xE4, 0x40, 0xCE, 0xEE, 0xC4, 0x0D, 0x7A, 0x8E, 0x2C, 0xD0, 0x51, 0x40, 0x12, 0x40, 0x14, 0x69, 0x14, 0xA8, 0xE1, 0x27, 0x78, 0x1C, 0x30, 0xF0, 0x19, 0x1C, 0xC6, 0x41, 0x04, 0x0E, 0x72, 0x1E, 0x71, 0xEB, 0x44, 0x27, 0x23, 0x66, 0x58, 0x09, 0x7E, 0x0D, 0x7C, 0x30, 0xC0, 0xBB, 0x06, 0xD4, 0x8D, 0xE0, 0x79, 0x80, 0xCD, 0x25, 0x1C, 0x66, 0xD4, 0x1E, 0x58, 0xB8, 0xFF, 0xFF, 0x09, 0x1C, 0x35, 0x03, 0xF4, 0x54, 0x1F, 0x05, 0xB0, 0xB3, 0x3D, 0x99, 0x33, 0x2B, 0x75, 0x76, 0x3A, 0x13, 0x1C, 0x5A, 0x82, 0xE3, 0xF1, 0x28, 0x3D, 0x9F, 0x9E, 0x21, 0x89, 0xFC, 0x41, 0xA0, 0x46, 0x66, 0x68, 0x8F, 0xF4, 0xB4, 0x4E, 0xD6, 0xC7, 0x83, 0xC3, 0x62, 0x62, 0x21, 0xA4, 0x00, 0x42, 0xE3, 0x01, 0xBF, 0xE2, 0x13, 0x80, 0x10, 0x8E, 0xDC, 0xF3, 0x35, 0x30, 0x8C, 0x01, 0xD9, 0xAF, 0x00, 0x84, 0xE0, 0xEF, 0x04, 0x47, 0xF4, 0xD0, 0x10, 0xE1, 0x61, 0x00, 0x47, 0x50, 0xE4, 0xC9, 0x00, 0x0D, 0xCC, 0x4F, 0x00, 0x31, 0x0F, 0xE5, 0x44, 0x02, 0x1F, 0x4A, 0x94, 0xF8, 0xC7, 0xE2, 0xE3, 0x84, 0x11, 0xCE, 0xF0, 0x29, 0xE2, 0xA9, 0xC2, 0x9A, 0x27, 0xA3, 0xF3, 0xC3, 0xE9, 0xBC, 0x08, 0x98, 0xA0, 0x8A, 0x15, 0x68, 0x90, 0x8E, 0xF3, 0x16, 0x90, 0x8D, 0x55, 0xFA, 0x88, 0x41, 0x03, 0x50, 0x49, 0xE9, 0x28, 0xE9, 0x0C, 0xDE, 0x0A, 0x0E, 0xE0, 0xDC, 0x1F, 0x29, 0x08, 0x98, 0x4E, 0x21, 0x86, 0xB6, 0x60, 0x0A, 0x89, 0xA2, 0xD1, 0x78, 0x3C, 0x64, 0x02, 0x23, 0x38, 0x83, 0x18, 0xD0, 0x19, 0x21, 0x64, 0xE4, 0x10, 0x80, 0x1A, 0xBA, 0x4F, 0x0B, 0x9E, 0x91, 0x6F, 0x0E, 0x09, 0x66, 0x82, 0xD0, 0xB9, 0xC1, 0x03, 0xF4, 0x19, 0x80, 0x9F, 0x4A, 0x7C, 0x29, 0x30, 0xB2, 0x05, 0x1E, 0x29, 0x40, 0x73, 0xE5, 0x30, 0x48, 0xA0, 0x37, 0x8C, 0x0B, 0xFC, 0xFF, 0x1F, 0x08, 0x4E, 0xCD, 0x09, 0x82, 0x0E, 0x83, 0xC3, 0x9D, 0x40, 0x02, 0x26, 0xEB, 0x5E, 0x00, 0x7D, 0x12, 0x18, 0x82, 0xFA, 0xAE, 0x05, 0xA0, 0x00, 0xF2, 0x61, 0xC0, 0x93, 0x7F, 0x1F, 0x60, 0x53, 0x08, 0x11, 0x26, 0x9A, 0xD1, 0xB9, 0xB4, 0xA1, 0xA3, 0xC4, 0x0C, 0x9D, 0x82, 0x78, 0xE8, 0x0E, 0x7A, 0xEE, 0x40, 0x0F, 0xDD, 0x53, 0x7B, 0x1D, 0x78, 0xED, 0x30, 0x81, 0x83, 0x0D, 0x9D, 0x9E, 0x39, 0xF0, 0xF3, 0x3D, 0xB4, 0x37, 0x04, 0xCF, 0xC2, 0x63, 0x07, 0xE7, 0x48, 0x70, 0xE3, 0xF0, 0xD8, 0xF9, 0x10, 0x3C, 0x76, 0x3E, 0x34, 0x1F, 0x41, 0xC0, 0x37, 0x26, 0xDC, 0xE4, 0xC1, 0x08, 0x8F, 0x11, 0xB1, 0x1E, 0x59, 0xB8, 0x1B, 0xD0, 0x71, 0xF1, 0x71, 0xFA, 0x2C, 0xF3, 0x42, 0x64, 0xEC, 0x13, 0x3D, 0x9C, 0xA2, 0x87, 0xA9, 0xC3, 0xC2, 0x41, 0xBD, 0x8E, 0x78, 0x6C, 0xFE, 0xFF, 0xC3, 0x7A, 0xE4, 0x1C, 0xD6, 0x68, 0xCF, 0x34, 0xFC, 0x1A, 0xE3, 0xE9, 0x1A, 0x23, 0xAC, 0x0F, 0x30, 0xE0, 0x00, 0xC4, 0x7B, 0x9F, 0x29, 0x99, 0x80, 0x01, 0xD9, 0x78, 0x9E, 0x06, 0xC0, 0x72, 0x04, 0x31, 0xCE, 0xEB, 0x40, 0xB0, 0x38, 0x47, 0x71, 0x74, 0x06, 0x0A, 0x12, 0x34, 0x9E, 0xE7, 0x60, 0x0C, 0x83, 0x47, 0x0A, 0xF4, 0x5C, 0x12, 0xE3, 0x84, 0x42, 0x3C, 0x50, 0xE0, 0x08, 0x6A, 0x7E, 0x2F, 0xE8, 0x5C, 0x82, 0x53, 0xB9, 0x66, 0x8D, 0xF8, 0x98, 0xF8, 0xBD, 0x04, 0xA3, 0x0D, 0x4C, 0xE7, 0x12, 0xAE, 0x0A, 0x46, 0xA9, 0x4F, 0x13, 0xA8, 0x9C, 0xA7, 0x09, 0x0A, 0xE2, 0x33, 0x80, 0xCF, 0x25, 0x80, 0xC5, 0x84, 0x33, 0x44, 0xAB, 0x10, 0xF0, 0xFF, 0xBF, 0x7E, 0xE0, 0x4E, 0x53, 0x1E, 0x21, 0xDC, 0x6B, 0x0A, 0xEE, 0xF4, 0x01, 0xC6, 0x09, 0xC2, 0x3A, 0x51, 0xF0, 0x7B, 0x0C, 0xB0, 0x95, 0x77, 0x55, 0x40, 0x09, 0xBA, 0x2A, 0x50, 0x10, 0x5F, 0x19, 0x1C, 0xF6, 0x1E, 0x83, 0x9E, 0x89, 0x6F, 0x63, 0xEC, 0x54, 0xE1, 0x5B, 0x12, 0x8B, 0x76, 0x91, 0x01, 0xC5, 0x3C, 0x3D, 0x77, 0x70, 0xDC, 0x59, 0x70, 0x83, 0x3F, 0x15, 0xEC, 0x4D, 0x06, 0xDE, 0xD0, 0x7C, 0x93, 0x01, 0x16, 0xFF, 0xFF, 0x9B, 0x0C, 0x30, 0x1C, 0x9B, 0x6F, 0x32, 0x80, 0x53, 0x85, 0x36, 0x7D, 0x6A, 0x34, 0x6A, 0xD5, 0xA0, 0x4C, 0x8D, 0x32, 0x0D, 0x6A, 0xF5, 0xA9, 0xD4, 0x98, 0xB1, 0x31, 0x59, 0xC6, 0x5A, 0x35, 0x6A, 0x87, 0x00, 0xA1, 0x32, 0x5E, 0x0E, 0x3A, 0x8C, 0x58, 0x13, 0x88, 0x80, 0x2C, 0x6E, 0xF9, 0x02, 0xB2, 0x54, 0x10, 0x01, 0x39, 0x94, 0x07, 0x20, 0x96, 0x10, 0x44, 0x40, 0x56, 0xBD, 0x3C, 0x01, 0x39, 0x02, 0x88, 0x80, 0x9C, 0xC7, 0x04, 0x10, 0x4B, 0x07, 0x22, 0x20, 0xFF, 0xFF, 0x01 }) Name (RBUF, Buffer () {0xff,0xff,0xff}) OperationRegion(CMOS, SystemIO, 0x70, 0x2) Field(CMOS,AnyAcc,NoLock,Preserve) { INDX, 8, DATA, 8, } // // Package Method data block // Arg0 has the instance being queried // Arg1 has the method id // Arg2 has the data passed Method (WMAC, 3, Serialized) { Store (Arg2, RBUF) CreateByteField (RBUF, 0, DAT0) // Return status CreateByteField (RBUF, 1, DAT1) // Return EC Register data CreateByteField (RBUF, 2, DAT2) if (LEqual(Arg1, 1)) { // ReadCmos Store (DAT0, INDX) Store (DATA, DAT2) } ElseIf (LEqual(Arg1, 2)) { // WriteCmos Store (DAT0, INDX) Store (DAT1, DATA) } Else{ } Return (ToHexString(RBUF)) } } } }
WQBA
该 Method 用于返回编译的 bmf 文件数据。
WMAC
WMAC 用于实现 MOF 中定义的 Method,通过 MOF 中的 WmiMethodId 来标识。如 WmiMethodId(1) 对应 ReadCmos,asl 中,WMAC 可使用 arg1 等于 1 的情况来处理。
GUID匹配
_WDG 方法中的 GUID 与 MOF 文件中的定义需保持一致,这种对应关系将 ACPI 实现与 WMI 类定义关联起来。
编译 ASL
本实验使用 QEMU 进行验证,可使用 iasl 工具直接编译 AML 文件加载。编译命令:
iasl.exe .\WMI.asl
启用 QEMU 时,利用 -acpitable 参数添加外部的 ACPI Table,如:
-acpitable file=/WMI.aml
三、Windows 测试
启动 QEMU 中的 Windows,管理员权限打开 powershell,输入如下命令可直接调用函数:
$instance = Get-WmiObject -NameSpace "rootwmi" -Class "AY123" $instance.ReadCmos(0)
可看到,控制台可正常打印时间的秒数。
四、Linux 测试
Linux 以 Ubuntu 为例。由于我本地收藏的 Ubuntu 镜像是 22.04 的,便直接拿来安装使用了。
1.安装 acpi_call:
sudo apt update sudo apt install acpi-call-dkms sudo modprobe acpi_call
2.调用 ACPI 方法:
# 直接调用 WMAC 方法,WMAC 的定义需传入 3 个参数 # Arg0: Instance # Arg1: Method Id # Arg2: Parameter # 下面示例是调用读取 CMOS 方法,传入的 0ffset 是0x00 echo '\_SB.EC.WMAC 0x01 0x01 0x00' | sudo tee /proc/acpi/call sudo cat /proc/acpi/call # 获取返回值
从上图中返回的结果可知道,byte 3 是读取到的秒数。
引用链接
[1] Windows Instrumentation: WMI and ACPI: https://learn.microsoft.com/zh-cn/previous-versions/windows/hardware/design/dn614028(v=vs.85)
[2] Windows-driver-samples: https://github.com/microsoft/Windows-driver-samples/tree/main/wmi/wmiacpi
版权声明:
作者:bin
链接:https://ay123.net/mystudy/bios/1863/
来源:爱影博客
文章版权归作者所有,未经允许请勿转载。

共有 0 条评论