内核驱动程序 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_smmX)。许多其他属性可以被读取或写入

名称

权限

描述

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 处理程序会查看 eaxebxecxedxesiedi 寄存器的内容。每个寄存器都有特殊用途

寄存器

用途

eax

在 SMM 前保存命令代码,在 SMM 后保存第一个结果。

ebx

保存参数。

ecx

未知,设置为 0。

edx

在 SMM 后保存第二个结果。

esi

未知,设置为 0。

edi

未知,设置为 0。

SMM 处理程序可以通过以下方式之一指示失败:

  • eax 的低十六位设置为 0xffff

  • 完全不修改 eax

  • 设置进位标志(仅限传统 SMM 接口)

传统 SMM 接口

当使用传统 SMM 接口时,通过将命令代码的最低有效字节写入特殊 IO 端口 0xb20x84 来触发 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 命令代码

命令代码

命令名称

描述

0x0025

获取 Fn 键状态

SMM 后返回按下的 Fn 键

  • eax 的第 9 位指示音量增大

  • eax 的第 10 位指示音量减小

  • 两位同时指示音量静音

0xa069

获取电源状态

SMM 后返回当前电源状态

  • eax 的第 1 位指示电池已连接

  • eax 的第 3 位指示交流电已连接

0x00a3

获取风扇状态

SMM 后返回当前风扇状态

  • eax 的第 1 字节保存当前风扇状态(0 - 2 或 3)

0x01a3

设置风扇状态

设置风扇速度

  • ebx 的第 1 字节保存风扇编号

  • ebx 的第 2 字节保存期望的风扇状态(0 - 2 或 3)

0x02a3

获取风扇转速

返回当前风扇转速(RPM)

  • ebx 的第 1 字节保存风扇编号

  • eax 的第 1 字保存当前风扇转速(RPM,SMM 后)

0x03a3

获取风扇类型

返回风扇类型

  • ebx 的第 1 字节保存风扇编号

  • eax 的第 1 字节保存风扇类型(SMM 后)

    • 第 5 位指示坞站风扇

    • 1 表示处理器风扇

    • 2 表示主板风扇

    • 3 表示显卡风扇

    • 4 表示电源风扇

    • 5 表示芯片组风扇

    • 6 表示其他风扇类型

0x04a3

获取标称风扇转速

返回每个风扇状态下的标称转速 (RPM)

  • ebx 的第 1 字节保存风扇编号

  • ebx 的第 2 字节保存所查询的风扇状态(0 - 2 或 3)

  • eax 的第 1 字保存标称风扇转速(RPM,SMM 后)

0x05a3

获取风扇转速容差

返回每个风扇状态的转速容差

  • ebx 的第 1 字节保存风扇编号

  • ebx 的第 2 字节保存所查询的风扇状态(0 - 2 或 3)

  • eax 的第 1 字节返回转速容差

0x10a3

获取传感器温度

返回测量的温度

  • ebx 的第 1 字节保存传感器编号

  • eax 的第 1 字节保存测量的温度(SMM 后)

0x11a3

获取传感器类型

返回传感器类型

  • ebx 的第 1 字节保存传感器编号

  • eax 的第 1 字节保存温度类型(SMM 后)

    • 1 表示 CPU 传感器

    • 2 表示 GPU 传感器

    • 3 表示 SODIMM 传感器

    • 4 表示其他传感器类型

    • 5 表示环境传感器

    • 6 表示其他传感器类型

0xfea3

获取 SMM 签名

如果接口受支持,则返回戴尔签名(SMM 后)

  • eax 保存 1145651527 (0x44494147 或 “DIAG”)

  • edx 保存 1145392204 (0x44454c4c 或 “DELL”)

0xffa3

获取 SMM 签名

0xfea3 相同,请同时检查。

还有其他命令用于启用(0x31a30x35a3)和禁用(0x30a30x34a3)自动风扇速度控制。然而,这些命令在许多机器上会导致严重的副作用,因此默认情况下不使用。

在某些机器(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 读取错误或传感器已停用。