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

寄存器

用途

eax

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

ebx

保存参数。

ecx

未知,设置为 0。

edx

在 SMM 之后保存第二个结果。

esi

未知,设置为 0。

edi

未知,设置为 0。

SMM 处理程序可以通过以下方式发出失败信号:

  • eax 的低 16 位设置为 0xffff

  • 完全不修改 eax

  • 设置进位标志(仅限旧式 SMM 接口)

旧式 SMM 接口

使用旧式 SMM 接口时,通过将命令代码的最低有效字节写入特殊的 ioport 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 位表示已连接 AC 电源

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 种常规风扇状态,但在 “魔法” 状态下,为此状态报告的额定转速是一个占位符值,但并非总是可检测到的。

固件错误

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