2. Dell DDV WMI 介面驅動 (dell-wmi-ddv)¶
2.1. 簡介¶
許多 2020 年之後生產的戴爾筆記型電腦都支援基於 WMI 的介面,用於檢索各種系統資料,如電池溫度、ePPID、診斷資料和風扇/散熱感測器資料。
該介面可能被 Windows 上的 Dell Data Vault 軟體使用,因此被稱為 DDV。目前 dell-wmi-ddv 驅動程式支援介面的第 2 版和第 3 版,並且可以輕鬆新增對新介面版本的支援。
警告
該介面被戴爾視為內部介面,因此沒有可用的供應商文件。所有知識都是透過試錯獲得的,請記住這一點。
2.2. Dell ePPID(電子部件標識)¶
Dell ePPID 用於唯一標識戴爾機器中的元件,包括電池。它的形式類似於 CC-PPPPPP-MMMMM-YMD-SSSS-FFF 幷包含以下資訊
原產國家程式碼 (CC)。
部件號,第一個字元是填充數字 (PPPPPP)。
製造商標識 (MMMMM)。
生產年份/月份/日期 (YMD),以 36 進製表示,Y 是年份的最後一位數字。
生產序列號 (SSSS)。
可選的韌體版本/修訂版 (FFF)。
可以使用 eppidtool python 實用程式來解碼和顯示此資訊。
所有關於 Dell ePPID 的資訊都是使用戴爾支援文件和此網站收集的。
2.3. WMI 介面描述¶
可以使用 bmfdec 實用程式從嵌入式二進位制 MOF (bmof) 資料中解碼 WMI 介面描述
[WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x409"), Description("WMI Function"), guid("{8A42EA14-4F2A-FD45-6422-0087F7A7E608}")]
class DDVWmiMethodFunction {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(1), Implemented, read, write, Description("Return Battery Design Capacity.")] void BatteryDesignCapacity([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(2), Implemented, read, write, Description("Return Battery Full Charge Capacity.")] void BatteryFullChargeCapacity([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(3), Implemented, read, write, Description("Return Battery Manufacture Name.")] void BatteryManufactureName([in] uint32 arg2, [out] string argr);
[WmiMethodId(4), Implemented, read, write, Description("Return Battery Manufacture Date.")] void BatteryManufactureDate([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(5), Implemented, read, write, Description("Return Battery Serial Number.")] void BatterySerialNumber([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(6), Implemented, read, write, Description("Return Battery Chemistry Value.")] void BatteryChemistryValue([in] uint32 arg2, [out] string argr);
[WmiMethodId(7), Implemented, read, write, Description("Return Battery Temperature.")] void BatteryTemperature([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(8), Implemented, read, write, Description("Return Battery Current.")] void BatteryCurrent([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(9), Implemented, read, write, Description("Return Battery Voltage.")] void BatteryVoltage([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(10), Implemented, read, write, Description("Return Battery Manufacture Access(MA code).")] void BatteryManufactureAceess([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(11), Implemented, read, write, Description("Return Battery Relative State-Of-Charge.")] void BatteryRelativeStateOfCharge([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(12), Implemented, read, write, Description("Return Battery Cycle Count")] void BatteryCycleCount([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(13), Implemented, read, write, Description("Return Battery ePPID")] void BatteryePPID([in] uint32 arg2, [out] string argr);
[WmiMethodId(14), Implemented, read, write, Description("Return Battery Raw Analytics Start")] void BatteryeRawAnalyticsStart([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(15), Implemented, read, write, Description("Return Battery Raw Analytics")] void BatteryeRawAnalytics([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]);
[WmiMethodId(16), Implemented, read, write, Description("Return Battery Design Voltage.")] void BatteryDesignVoltage([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(17), Implemented, read, write, Description("Return Battery Raw Analytics A Block")] void BatteryeRawAnalyticsABlock([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]);
[WmiMethodId(18), Implemented, read, write, Description("Return Version.")] void ReturnVersion([in] uint32 arg2, [out] uint32 argr);
[WmiMethodId(32), Implemented, read, write, Description("Return Fan Sensor Information")] void FanSensorInformation([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]);
[WmiMethodId(34), Implemented, read, write, Description("Return Thermal Sensor Information")] void ThermalSensorInformation([in] uint32 arg2, [out] uint32 RawSize, [out, WmiSizeIs("RawSize") : ToInstance] uint8 RawData[]);
};
每個 WMI 方法都接受一個包含 32 位索引的 ACPI 緩衝區作為輸入引數,當使用電池相關的 WMI 方法時,前 8 位用於指定電池。其他 WMI 方法可能會忽略此引數或以不同的方式解釋它。WMI 方法輸出格式各不相同
如果該函式只有一個輸出,則返回相應型別的 ACPI 物件
如果該函式有多個輸出,則返回一個包含相同順序輸出的 ACPI 包
應徹底檢查輸出的格式,因為在發生錯誤的情況下,許多方法可能會返回格式錯誤的資料。
許多電池相關方法的資料格式似乎基於 Smart Battery Data Specification,因此未知的電池相關方法很可能以某種方式遵循此標準。
2.3.1. WMI 方法 GetBatteryDesignCapacity()¶
以 mAh 為單位返回電池的設計容量,作為 u16。
2.3.2. WMI 方法 BatteryFullCharge()¶
以 mAh 為單位返回電池的充滿容量,作為 u16。
2.3.3. WMI 方法 BatteryManufactureName()¶
返回電池的製造商名稱,作為 ASCII 字串。
2.3.4. WMI 方法 BatteryManufactureDate()¶
返回電池的生產日期,作為 u16。日期以以下方式編碼
位 0 到 4 包含生產日。
位 5 到 8 包含生產月。
位 9 到 15 包含生產年份,偏差為 1980 年。
2.3.5. WMI 方法 BatterySerialNumber()¶
返回電池的序列號,作為 u16。
2.3.6. WMI 方法 BatteryChemistryValue()¶
返回電池的化學成分,作為 ASCII 字串。已知的值是
“Li-I”表示鋰離子
2.3.7. WMI 方法 BatteryTemperature()¶
以十分之一度開爾文為單位返回電池的溫度,作為 u16。
2.3.8. WMI 方法 BatteryCurrent()¶
以 mA 為單位返回電池的電流,作為 s16。負值表示放電。
2.3.9. WMI 方法 BatteryVoltage()¶
以 mV 為單位返回電池的電壓,作為 u16。
2.3.10. WMI 方法 BatteryManufactureAccess()¶
返回電池的健康狀況,作為 u16。健康狀況以以下方式編碼
第三個半位元組包含一般故障模式
第四個半位元組包含特定故障程式碼
有效的故障模式是
永久性故障 (
0x9)過熱故障 (
0xa)過電流故障 (
0xb)
所有其他故障模式都被認為是正常的。
以下故障程式碼對永久性故障有效
保險絲熔斷 (
0x0)電池單元不平衡 (
0x1)過電壓 (
0x2)fet 故障 (
0x3)
當電池發出永久性故障訊號時,應忽略故障程式碼的最後兩位。
以下故障程式碼對過熱故障有效
充電開始時過熱 (
0x5)充電期間過熱 (
0x7)放電期間過熱 (
0x8)
以下故障程式碼對過電流故障有效
充電期間過電流 (
0x6)放電期間過電流 (
0xb)
2.3.11. WMI 方法 BatteryRelativeStateOfCharge()¶
以百分比形式返回電池容量,作為 u16。
2.3.12. WMI 方法 BatteryCycleCount()¶
返回電池的迴圈計數,作為 u16。
2.3.13. WMI 方法 BatteryePPID()¶
返回電池的 ePPID,作為 ASCII 字串。
2.3.14. WMI 方法 BatteryeRawAnalyticsStart()¶
執行電池分析並返回狀態程式碼
0x0: 成功0x1: 不支援介面0xfffffffe: 錯誤/超時
注意
此方法的含義仍然很大程度上未知。
2.3.15. WMI 方法 BatteryeRawAnalytics()¶
返回一個緩衝區,通常包含 12 個塊的分析資料。這些塊包含
一個從 0 開始的塊號 (u8)
31 位元組的未知資料
注意
此方法的含義仍然很大程度上未知。
2.3.16. WMI 方法 BatteryDesignVoltage()¶
以 mV 為單位返回電池的設計電壓,作為 u16。
2.3.17. WMI 方法 BatteryeRawAnalyticsABlock()¶
返回一個分析資料塊,索引的第二個位元組用於選擇塊號。
自 WMI 介面版本 3 起支援!
注意
此方法的含義仍然很大程度上未知。
2.3.18. WMI 方法 ReturnVersion()¶
返回 WMI 介面版本,作為 u32。
2.3.19. WMI 方法 FanSensorInformation()¶
返回一個包含風扇感測器條目的緩衝區,以單個 0xff 結尾。這些條目包含
風扇型別 (u8)
風扇轉速,單位為 RPM(小端 u16)
2.3.20. WMI 方法 ThermalSensorInformation()¶
返回一個包含熱感測器條目的緩衝區,以單個 0xff 結尾。這些條目包含
熱型別 (u8)
當前溫度 (s8)
最低溫度 (s8)
最高溫度 (s8)
未知欄位 (u8)
注意
TODO:找出最後一個位元組的含義。
2.4. ACPI 電池匹配演算法¶
用於將 ACPI 電池與索引匹配的演算法基於 OEM 軟體日誌訊息中找到的資訊。
基本上,對於每個新的 ACPI 電池,索引 1 到 3 後的電池序列號都與 ACPI 電池的序列號進行比較。由於 ACPI 電池的序列號可以編碼為普通整數或十六進位制值,因此需要檢查兩種情況。然後選擇第一個具有匹配序列號的索引。
序列號 0 表示相應的索引未與實際電池關聯,或者關聯的電池不存在。
某些機器(如戴爾 Inspiron 3505)僅支援單個電池,因此忽略電池索引。因此,驅動程式依賴於 ACPI 電池掛鉤機制來發現電池。
2.5. 逆向工程 DDV WMI 介面¶
找到一個受支援的戴爾筆記型電腦,通常是 2020 年之後生產的。
轉儲 ACPI 表並搜尋 WMI 裝置(通常稱為“ADDV”)。
解碼相應的 bmof 資料並檢視 ASL 程式碼。
嘗試透過將控制流與其他 ACPI 方法(例如電池相關方法的 _BIX 或 _BIF)進行比較來推斷特定 WMI 方法的含義。
使用內建的 UEFI 診斷程式檢視風扇/散熱相關方法的感測器型別/值(有時覆蓋靜態 ACPI 資料欄位可用於測試不同的感測器型別值,因為在某些機器上,此資料不會在熱重置時重新初始化)。
或者
載入
dell-wmi-ddv驅動程式,如有必要,使用force模組引數。使用 debugfs 介面訪問原始風扇/熱感測器緩衝區資料。
將資料與內建的 UEFI 診斷程式進行比較。
如果您的戴爾筆記型電腦上提供的 DDV WMI 介面版本不受支援,或者您看到未知的風扇/熱感測器,請在 bugzilla 上提交錯誤報告,以便可以將它們新增到 dell-wmi-ddv 驅動程式中。
有關更多資訊,請參見報告問題。