内核驱动 dell-smm-hwmon¶
- 版权所有:
© 2002-2005 Massimo Dal Zotto <dz@debian.org>
- 版权所有:
© 2019 Giovanni Mascellani <gio@debian.org>
描述¶
在许多戴尔笔记本电脑上,可以查询系统管理模式 (SMM) BIOS 以获取风扇和温度传感器的状态。可以使用诸如 sensors
之类的用户空间实用程序来返回读数。用户空间套件 i8kutils 也可用于读取传感器并自动调整风扇速度(请注意,它目前使用已弃用的 /proc/i8k
接口)。
sysfs
接口¶
可以通过 sysfs
上的标准 hwmon
接口查询和设置温度传感器和风扇,位于目录 /sys/class/hwmon/hwmonX
下,其中 X
为某个值(搜索 X
,使得 /sys/class/hwmon/hwmonX/name
的内容为 dell_smm
)。可以读取或写入许多其他属性。
名称 |
权限 |
描述 |
---|---|---|
fan[1-3]_input |
只读 |
风扇转速,单位为 RPM。 |
fan[1-3]_label |
只读 |
风扇标签。 |
fan[1-3]_min |
只读 |
风扇最小转速,单位为 RPM |
fan[1-3]_max |
只读 |
风扇最大转速,单位为 RPM |
fan[1-3]_target |
只读 |
预期风扇转速,单位为 RPM |
pwm[1-3] |
读写 |
控制风扇 PWM 占空比。 |
pwm1_enable |
只写 |
启用或禁用自动 BIOS 风扇控制(并非所有笔记本电脑都支持,请参阅下面的详细信息)。 |
temp[1-10]_input |
只读 |
温度读数,单位为毫摄氏度。 |
temp[1-10]_label |
只读 |
温度传感器标签。 |
由于 SMM 接口的性质,每个 pwmX 属性控制风扇编号 X。
禁用自动 BIOS 风扇控制¶
在某些笔记本电脑上,BIOS 每隔几秒钟自动设置风扇速度。因此,此驱动程序设置的风扇速度很快会被覆盖。
通过在属性 pwm1_enable
中写入值 1
,可以实验性地支持禁用自动 BIOS 风扇控制,至少在已知相应 SMM 命令的笔记本电脑上(写入 2
再次启用自动 BIOS 控制)。即使您有多个风扇,所有风扇都会同时设置为启用或禁用自动风扇控制,并且,尽管名称如此,pwm1_enable
会为所有风扇设置自动控制。
如果 pwm1_enable
不可用,则表示您的硬件未将用于启用和禁用自动 BIOS 风扇控制的 SMM 代码列入白名单。其他笔记本电脑适用的代码也可能适用于您的笔记本电脑,或者您可能需要发现新的代码。
检查内核树中的文件 drivers/hwmon/dell-smm-hwmon.c
中的列表 i8k_whitelist_fan_control
:作为第一次尝试,您可以尝试添加您的机器并使用已知的代码对。如果在重新编译内核后,您看到存在 pwm1_enable
并且有效(即,您可以手动控制风扇速度),请提交您的发现作为内核补丁,以便其他用户可以从中受益。有关提交补丁的信息,请参阅 Documentation/process/submitting-patches.rst。
如果没有任何已知代码适用于您的机器,则您需要进行一些探测,因为不幸的是,戴尔没有发布其 SMM 的数据表。您可以尝试使用 此存储库中的代码来探测您机器上的 BIOS 并发现相应的代码。
同样,当您找到新代码时,我们很乐意收到您的补丁!
thermal
接口¶
该驱动程序还将风扇导出为热冷却设备,其 type
设置为 dell-smm-fan[1-3]
。这允许使用热调节器之一轻松进行风扇控制。
模块参数¶
- force:bool
强制加载,而不检查受支持的型号。(默认值:0)
- ignore_dmi:bool
即使 DMI 数据不匹配,也继续探测硬件。(默认值:0)
- restricted:bool
仅允许设置了
CAP_SYS_ADMIN
功能的进程或以 root 身份运行的进程在使用旧版/proc/i8k
接口时控制风扇。在这种情况下,普通用户将能够读取温度和风扇状态,但不能控制风扇。如果您的笔记本电脑与其他用户共享,并且您不信任他们,您可能需要使用此选项。(默认值:1,仅在CONFIG_I8K
可用时才可用)
- power_status:bool
在
/proc/i8k
中报告 AC 状态。(默认值:0,仅在CONFIG_I8K
可用时才可用)
- fan_mult:uint
风扇转速的乘法因子。(默认值:自动检测)
- fan_max:uint
最大可配置风扇转速。(默认值:自动检测)
旧版 /proc
接口¶
警告
此接口已过时且已弃用,不应在新应用程序中使用。此接口仅在使用选项 CONFIG_I8K
编译内核时可用。
只需读取 /proc/i8k
文件即可访问内核驱动程序提供的信息。例如
$ cat /proc/i8k
1.0 A17 2J59L02 52 2 1 8040 6420 1 2
从 /proc/i8k
读取的字段是
1.0 A17 2J59L02 52 2 1 8040 6420 1 2
| | | | | | | | | |
| | | | | | | | | +------- 10. buttons status
| | | | | | | | +--------- 9. AC status
| | | | | | | +-------------- 8. fan0 RPM
| | | | | | +------------------- 7. fan1 RPM
| | | | | +--------------------- 6. fan0 status
| | | | +----------------------- 5. fan1 status
| | | +-------------------------- 4. temp0 reading (Celsius)
| | +---------------------------------- 3. Dell service tag (later known as 'serial number')
| +-------------------------------------- 2. BIOS version
+------------------------------------------ 1. /proc/i8k format version
负值(例如 -22)表示 BIOS 不返回相应的信息。这在某些型号/BIOS 上是正常的。
出于性能原因,/proc/i8k
默认情况下不报告 AC 状态,因为此 SMM 调用执行需要很长时间,并且不是真正需要的。如果您想在 /proc/i8k
中查看 ac 状态,则必须通过将 power_status=1
参数传递给 insmod 来显式启用此选项。如果 AC 状态不可用,则会打印 -1。
该驱动程序还提供了一个 ioctl 接口,该接口可用于获取相同的信息并控制风扇状态。可以从 C 程序或使用 i8kctl 实用程序的 shell 访问 ioctl 接口。有关如何使用 ioctl 接口的更多信息,请参阅 i8kutils
的源文件。
SMM 接口¶
警告
SMM 接口是通过反复试验进行逆向工程的,因为戴尔没有提供任何文档,请记住这一点。
该驱动程序使用 SMM 接口将命令发送到系统 BIOS。此接口通常由戴尔的 32 位诊断程序或较新的笔记本电脑型号上的内置 BIOS 诊断程序使用。当 BIOS 代码执行时间过长时,SMM 可能会导致短暂的挂起。
系统 BIOS 内的 SMM 处理程序会查看 eax
、ebx
、ecx
、edx
、esi
和 edi
寄存器的内容。每个寄存器都有其特殊用途
寄存器 |
用途 |
---|---|
eax |
在 SMM 之前保存命令代码,在 SMM 之后保存第一个结果。 |
ebx |
保存参数。 |
ecx |
未知,设置为 0。 |
edx |
在 SMM 之后保存第二个结果。 |
esi |
未知,设置为 0。 |
edi |
未知,设置为 0。 |
SMM 处理程序可以通过以下方式发出失败信号:
将
eax
的低 16 位设置为0xffff
完全不修改
eax
设置进位标志(仅限旧式 SMM 接口)
旧式 SMM 接口¶
使用旧式 SMM 接口时,通过将命令代码的最低有效字节写入特殊的 ioport 0xb2
和 0x84
来触发 SMM。此接口未在 ACPI 表中描述,因此只能通过发出测试 SMM 调用来检测。
WMI SMM 接口¶
在现代戴尔机器上,SMM 调用是通过 ACPI WMI 完成的
#pragma namespace("\\\\.\\root\\dcim\\sysman\\diagnostics")
[WMI, Provider("Provider_DiagnosticsServices"), Dynamic, Locale("MS\\0x409"),
Description("RunDellDiag"), guid("{F1DDEE52-063C-4784-A11E-8A06684B9B01}")]
class LegacyDiags {
[key, read] string InstanceName;
[read] boolean Active;
[WmiMethodId(1), Implemented, read, write, Description("Legacy Method ")]
void Execute([in, out] uint32 EaxLen, [in, out, WmiSizeIs("EaxLen") : ToInstance] uint8 EaxVal[],
[in, out] uint32 EbxLen, [in, out, WmiSizeIs("EbxLen") : ToInstance] uint8 EbxVal[],
[in, out] uint32 EcxLen, [in, out, WmiSizeIs("EcxLen") : ToInstance] uint8 EcxVal[],
[in, out] uint32 EdxLen, [in, out, WmiSizeIs("EdxLen") : ToInstance] uint8 EdxVal[]);
};
一些机器仅支持 WMI SMM 接口,而一些机器则同时支持两种接口。驱动程序会自动检测是否存在哪些接口,如果不存在旧式 SMM 接口,则将使用 WMI SMM 接口。WMI SMM 接口通常比旧式 SMM 接口慢,因为需要调用 ACPI 方法才能触发 SMM。
SMM 命令代码¶
命令代码 |
命令名称 |
描述 |
---|---|---|
|
获取 Fn 键状态 |
返回 SMM 后按下的 Fn 键
|
|
获取电源状态 |
返回 SMM 后的当前电源状态
|
|
获取风扇状态 |
返回 SMM 后的当前风扇状态
|
|
设置风扇状态 |
设置风扇速度
|
|
获取风扇速度 |
返回当前风扇转速(RPM)
|
|
获取风扇类型 |
返回风扇类型
|
|
获取额定风扇速度 |
返回每个风扇状态下的额定转速(RPM)
|
|
获取风扇速度公差 |
返回每个风扇状态的速度公差
|
|
获取传感器温度 |
返回测量的温度
|
|
获取传感器类型 |
返回传感器类型
|
|
获取 SMM 签名 |
如果支持该接口,则返回戴尔签名(SMM 后)
|
|
获取 SMM 签名 |
与 |
还有其他命令用于启用(0x31a3
或 0x35a3
)和禁用(0x30a3
或 0x34a3
)自动风扇速度控制。但是,这些命令在许多机器上都会导致严重的副作用,因此默认情况下不使用。
在一些机器上(Inspiron 3505、Precision 490、Vostro 1720 等),风扇支持第 4 种 “魔法” 状态,这向 BIOS 发出信号,表示应该为特定风扇启用自动风扇控制。但是,也有一些机器支持第 4 种常规风扇状态,但在 “魔法” 状态下,为此状态报告的额定转速是一个占位符值,但并非总是可检测到的。
固件错误¶
SMM 调用在某些机器上可能会表现不稳定
固件错误 |
受影响的机器 |
---|---|
读取风扇状态返回虚假错误。 |
Precision 490 OptiPlex 7060 |
读取风扇类型会导致风扇行为异常。 |
Studio XPS 8000 Studio XPS 8100 Inspiron 580 Inspiron 3505 |
与风扇相关的 SMM 调用耗时过长(约 500 毫秒)。 |
Inspiron 7720 Vostro 3360 XPS 13 9333 XPS 15 L502X |
如果您在戴尔机器上遇到类似问题,请在 Bugzilla 上提交错误报告,以便我们可以应用解决方法。
限制¶
SMM 调用在某些机器上执行时间过长,会导致短暂停顿和/或音频故障。此外,在挂起后需要恢复风扇状态,以及自动模式设置。读取温度传感器时,高于 127 度的值表示 BIOS 读取错误或传感器已停用。