文章
适配thinkbook的风扇控制器
本文目录 7
bg
重装系统之后摆脱了联想自带的应用商店和电脑管家,但是突然怀念起电脑管家的“降温除尘”功能了
在网上搜索了一下只有控制thinkpad的风扇的小程序,没有针对thinkbook的,借助寇德叉的帮助搓了一个
代码以及最后的程序见github
涉及到的一些东西以前也不是很了解,这里补充一下
WMI
WMI, Windows Management Instrumentation(Windows 管理规范):相当于Windows操作系统提供出来的一个系统管理界面
上层的程序可以通过它来查询/控制:
- CPU、硬盘等硬件信息;
- Windows 服务;
- 系统设置;
- 某些厂商提供的 BIOS 功能;
- 某些 ACPI 设备
BIOS
一台机器有很多硬件,cpu、dram(memory)、ssd(disk)等等,OS统筹这些硬件,把接口开放给上面的应用
但是DRAM这种是通电之后就直接清空的硬件,那么机器刚通电的时候,操作系统要怎么初始化进去呢?因此就需要一个通电可以恢复的东西,他就是Firmware固件,在PC中通常就是BIOS/UEFI,他们会被存在**Flash Memory(闪存)**中
通电之后,CPU复位之后的第一件事就是从一个固定的PC开始执行指令,而这个地址叫作Reset Vector复位向量,它会被映射到主板Firmware的地方
ACPI
在windows启动之后,系统要进行电源管理、温度、睡眠、设备控制等等的操作;而每一块主板对于这些的操作都是不尽相同的,因此BIOS还需要提供一张表ACPI, Advanced Configuration and Power Interface(高级配置与电源接口),相当于写给OS的硬件说明书
在Windows的注册表里可以读到加载的ACPI
HKEY_LOCAL_MACHINE\HARDWARE\ACPI
ACPI里不止存了一些静态的数据,还包括AML, ACPI Machine Language(ACPI 机器语言,二进制码)以及用它写成的小程序
比如读取一个温度传感器的路径就是
Windows
↓
ACPI interpreter
↓
执行 AML method
↓
访问 EC
↓
读取温度传感器
EC
风扇特殊的地方在于,大多数机器里都有一个嵌入式控制器Embedded Controller,这个EC可以在OS完全不参与的情况下自己控制风扇,比如BIOS在开机的时候配置好风扇转动的策略,然后CPU/sensors给EC传数据,进而控制风扇
找接口
既然联想电脑管家有这个功能,那么说明这台机子肯定有对应的接口,但是直接去找无异于大海捞针
既然这样直接监视一下电脑管家的“降温除尘”用了驱动提供的什么设备,调用了什么接口就好了
经过观察,电脑管家的过程是这样的:
↓
打开 \\.\EnergyDrv
↓
调用 DeviceIoControl
↓
发送 {6, 1, 1}
↓
启动脉冲式除尘
照着这个思路复刻一遍,最后的效果还是和原来的降温除尘一样是脉冲式的,不会一直持续
这样之后寇德叉去扫了一下这台机子的 BIOS/ACPI 接口,从注册表里的HKEY_LOCAL_MACHINE\HARDWARE\ACPI的AML反编译成ASL(ACPI source language),然后顺着含着FA1S字样找了一下,发现了这样的判断逻辑
如果功能编号是 0x04030001
返回 FA1S × 100
如果功能编号是 0x04030002
返回 FA2S × 100
似乎是找到了两个风扇对应的编号
这个时候在root\wmi中又发现了很多包含LENOVO的类,其中的 LENOVO_OTHER_METHOD 里提供里通用的读写器
GetFeatureValue(IDs)
SetFeatureValue(IDs, value)
再把刚刚得到的设备代码送进去试一试
GetFeatureValue(0x04030001)
GetFeatureValue(0x04030002)
oi得到了风扇的转速,那再测试一下写入并改变转速的功能
SetFeatureValue(0x04030001, 4500)
SetFeatureValue(0x04030002, 4800)
随后每秒执行:
GetFeatureValue(0x04030001)
GetFeatureValue(0x04030002)
看到两个返回值迅速上升到约:
风扇 1:4500~4800 RPM
风扇 2:4900~5100 RPM
而且持续高速,不再像除尘模式那样断断续续
最后写入:
SetFeatureValue(0x04030001, 0)
SetFeatureValue(0x04030002, 0)
风扇又恢复了 BIOS 自动调速
代码
由于用到了WMI来对系统进行操作,所以寇德叉这里用微软的C#来写的(本人不会),也就简单的调用了一些windows和Lenovo给的接口
主要使用了.NET Framework这个库,来让C#程序能使用System.Management去访问Windows WMI