电池作为现在笔记本必不可少的部件,通过 ACPI 和 Windows 进行交互。
对此,ACPI Spec 定义了几个 Table。换一句话说,Windows 只要能够正确读取出 Table,那么就可以根据上面的信息展示给客户一个电池。
第一个是 _BIX (Battery Information Extended) (特别注意ACPI 4.0定义的 _BIF (Battery Information)已经废止 ),其中给出了电池的信息。
偏移名称 | 大小 | 解释 |
Revision | DWORD | 目前版本号为 1 |
Power Unit | DWORD | 电池容量单位: 0 – [mWh], 同时充放电速度将会以[mW]为单位 1 – [mAh], 同时充放电速度将会以[mA]为单位 |
Design Capacity | DWORD | 设计容量,单位由上面的 Power Unit 给出 取值范围: 0x00000000-0x7FFF FFFF 0xFFFFFFFF 未知容量 |
Last Full Charge Capacity | DWORD | 充满后的预期容量 取值范围: 0x00000000-0x7FFF FFFF 0xFFFFFFFF 未知容量 |
Battery Technology | DWORD | 电池位置 0x0000 0000 主电池 0x0000 0001 第二块电池 |
Design Voltage | DWORD | 设计电压, 取值范围 0x000000000 – 0x7FFFFFFF in [mV] 0xFFFFFFFF – 未知电压 |
Design Capacity of Warning | DWORD | OEM 设置的告警容量值 取值范围 0x000000000 – 0x7FFFFFFF in [mWh] or [mAh] |
Design Capacity of Low | DWORD | OEM 设置的低容量值 取值范围 0x000000000 – 0x7FFFFFFF in [mWh] or [mAh] |
Cycle Count | DWORD | 充电循环次数 取值范围 0x000000000 – 0xFFFFFFFF |
Measurement Accuracy | DWORD | 电池容量测量准确度,以1/1000为单位,比如:80000表示80% |
Max Sampling Time | DWORD | _BST 中两次测量的最大间隔时间,比如,当前电池容量,放电速度或者剩余容量。以为毫秒单位。0xFFFFFFFF表示该位置无效。 |
Min Sampling Time | DWORD | _BST 中两次测量的最小间隔时间。以为毫秒单位。0xFFFFFFFF表示该位置无效。 |
Max Averaging Interval | DWORD | _BST 中两次测量的平均最大间隔时间。 |
Min Averaging Interval | DWORD | BST 中两次测量的平均最小间隔时间。 |
Battery Capacity Granularity 1 | DWORD | 电池在告警容量值和低容量值之间的颗粒度 |
Battery Capacity Granularity 2 | DWORD | 电池在告警容量值和充满容量值之间的颗粒度 |
Model Number | 零结尾ASCII字符串 | OEM 定义的电池型号 |
Serial Number | 零结尾ASCII字符串 | OEM 定义的电池序列号 |
Battery Type | 零结尾ASCII字符串 | OEM 定义的电池类型 |
OEM Information | 零结尾ASCII字符串 | OEM 定义的在UI上展示的电池OEM信息 |
Battery Swapping Capability | DWORD | 0x0 不可更换电池,例如,内部密封电池,用户无法接触到 0x1关机之后可更换电池 0x10 热插拔电池 |
第二个是 _BST (Battery Status), 这个用于报告当前电池的状态信息。
偏移名称 | 大小 | 解释 |
Battery State | DWORD | Bit0 为1表示正在放电 Bit1 为1表示正在充电 Bit2 为1表示电池预警 |
Battery Present Rate | DWORD | 电池充放电速度 取值范围 0x000000000 – 0x7FFFFFFF以[mW]或者[mA]为单位 0xFFFFFFFF – 未知速度 |
Battery Remaining Capacity | DWORD | 电池剩余容量 取值范围 0x000000000 – 0x7FFFFFFF以[mWh]或者[mAh]为单位 0xFFFFFFFF – 未知容量 |
Battery Present Voltage | DWORD | 电池电压 取值范围 0x000000000 – 0x7FFFFFFF以[mV]为单位 0xFFFFFFFF – 未知电压 |
以本人的电脑(HP 840 G6)为例,设备管理器中可以看到电池:
使用 HE 直接读取 ACPI Table:
根据上面的整理出两个对应的Table, 放在 BAT0 设备中
Device (BAT0)
{
Name (_HID, EisaId ("PNP0C0A") /* Control Method Battery */) // _HID: Hardware ID
Name (_UID, One) // _UID: Unique ID
Method (_DSM, 4, Serialized) // _DSM: Device-Specific Method
{
If (LEqual (Arg0, ToUUID ("4c2067e3-887d-475c-9720-4af1d3ed602e") /* Battery Thermal Limit */))
{
Switch (ToInteger (Arg2))
{
Case (0x03)
{
Return (Package (0x01)
{
0x1E
})
}
}
}
Else
{
Return (Package (0x01)
{
Zero
})
}
}
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x1F)
}
Method (_BIX, 0, NotSerialized) // _BIX: Battery Information Extended
{
Return ( Package (0x15)
{
1,
1,
20000,
20000,
0,
4300,
2000,
1000,
10,
80000,
1000,
500,
750,
500,
0x64,
0x64,
"LABZBAT0",
"202410",
"MODOL1",
"LABZBAT0",
One
})
}
Method (_BST, 0, NotSerialized) // _BST: Battery Status
{
Return ( Package (0x04) {
1,
100,
10000,
4200
})
}
}
}
接下来选择使用 VirtualBox 虚拟机,根据【参考1】,替换内部的 ACPI Table, 最终效果如下:
就是说,我们成功的在这个虚拟机中安装了一块电量为 50% 的电池。
本文提到的修改后的 ACPI 源代码可以在这里下载:
参考: