内核驱动程序 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
为某个值;请查找使得 /sys/class/hwmon/hwmonX/name
的内容为 dell_smm
的 X
)。许多其他属性可以被读取或写入
名称 |
权限 |
描述 |
---|---|---|
fan[1-4]_input |
只读 |
风扇转速 (RPM)。 |
fan[1-4]_label |
只读 |
风扇标签。 |
fan[1-4]_min |
只读 |
最小风扇转速 (RPM) |
fan[1-4]_max |
只读 |
最大风扇转速 (RPM) |
fan[1-4]_target |
只读 |
预期风扇转速 (RPM) |
pwm[1-4] |
读写 |
控制风扇 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-4]
。这使得使用其中一个热管理控制器可以轻松控制风扇。
模块参数¶
- force:bool
强制加载,不检查支持的型号。(默认值: 0)
- ignore_dmi:bool
即使 DMI 数据不匹配也继续探测硬件。(默认值: 0)
- restricted:bool
仅允许具有
CAP_SYS_ADMIN
能力集的进程或在使用传统/proc/i8k
接口时以 root 身份运行的进程控制风扇。在这种情况下,普通用户将能够读取温度和风扇状态,但无法控制风扇。如果您的笔记本电脑与其他用户共享且您不信任他们,您可能需要使用此选项。(默认值: 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
中看到交流电状态,必须通过将 power_status=1
参数传递给 insmod 来显式启用此选项。如果交流电状态不可用,则会打印 -1。
该驱动程序还提供了一个 ioctl 接口,可用于获取相同信息和控制风扇状态。ioctl 接口可以通过 C 程序或使用 i8kctl 工具从 shell 访问。有关如何使用 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
的低十六位设置为0xffff
完全不修改
eax
设置进位标志(仅限传统 SMM 接口)
传统 SMM 接口¶
当使用传统 SMM 接口时,通过将命令代码的最低有效字节写入特殊 IO 端口 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 种常规风扇状态,但在“魔术”状态下,为此状态报告的标称 RPM 是一个占位符值,但该值并非总是可检测的。
固件错误¶
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 读取错误或传感器已停用。