没写完,到时候再改

1 阅读3分钟

Linux 风扇底层控制详解(基于 sysfs 与 hwmon 子系统)

在 Linux 系统中,对主板风扇(转速控制、监测)的支持通常由内核硬件监控子系统 hwmon 完成。用户空间通过 /sys/class/hwmon/ 下的虚拟文件接口与内核模块交互,从而读取温度、电压、风扇转速,甚至手动调节风扇转速。本文将以常见的 Nuvoton NCT6775 系列监控芯片为例,详细介绍底层原理和操作方法。

一、内核模块加载

硬件监控芯片需要对应的内核驱动模块。例如 NCT6775 对应模块 nct6775。加载模块:

sudo modprobe nct6775

加载成功后,模块会在 /sys/class/hwmon/ 下创建一个或多个 hwmonX 目录(X 从 0 开始编号)。每个 hwmonX 代表一个硬件监控设备。

查看模块是否加载成功:

lsmod | grep nct6775
dmesg | tail -20          # 查看内核日志,确认芯片被识别

二、sysfs 接口结构:/sys/class/hwmon/

/sys/class/hwmon/ 是 Linux 硬件监控子系统的核心。每个硬件监控芯片对应一个子目录,如 hwmon0/hwmon1/。进入该目录,可看到标准属性文件:

文件/目录说明
name芯片名称,如 nct6775coretemp
fan1_input风扇1 当前转速(单位:RPM)
fan1_label风扇1 标签(可选,如 “CPU Fan”)
pwm1风扇1 的 PWM 占空比(0~255,对应 0%~100%)
pwm1_enable风扇1 控制模式(0=关闭, 1=手动, 2=自动)
temp1_input温度传感器1 的当前值(单位:毫摄氏度)
temp1_label温度传感器标签

编号不一定连续,取决于实际硬件提供的通道数。

查找 NCT6775 对应的 hwmon 目录

for d in /sys/class/hwmon/hwmon*/; do
    if grep -q nct6775 "$d/name" 2>/dev/null; then
        echo "$d"
    fi
done

假设输出为 /sys/class/hwmon/hwmon4/,下文将以此路径为例。

三、风扇转速与 PWM 编号的对应关系

通常 pwm1 控制 fan1pwm2 控制 fan2,依此类推。但具体主板可能重新映射,必须实测确认。

查看所有风扇转速

cat /sys/class/hwmon/hwmon4/fan*_input

或使用 sensors 命令(需要安装 lm-sensors):

sensors | grep -E 'fan[0-9]+|RPM'

列出所有 PWM 通道

ls /sys/class/hwmon/hwmon4/pwm* | grep -E 'pwm[0-9]+$'

输出示例:pwm1 pwm2 pwm3 pwm4 pwm5。如果不存在 pwm6,则说明该芯片最多支持 5 个独立风扇控制。

四、手动控制风扇转速

1. 理解 pwmX_enable 的值

  • 0:关闭风扇(危险,可能导致过热,不推荐)
  • 1:手动模式 – 用户写入 pwmX 的值直接控制占空比
  • 2:自动模式 – 硬件或 BIOS 根据温度自动调节,用户写入 pwmX 无效

2. 手动调节步骤

以控制 pwm2(假设对应 fan2)为例:

# 进入手动模式
echo 1 | sudo tee /sys/class/hwmon/hwmon4/pwm2_enable

# 设置占空比 50%(255 * 0.5 ≈ 128)
echo 128 | sudo tee /sys/class/hwmon/hwmon4/pwm2

# 观察转速变化
cat /sys/class/hwmon/hwmon4/fan2_input

# 恢复自动模式
echo 2 | sudo tee /sys/class/hwmon/hwmon4/pwm2_enable

3. 注意事项

  • 避免过热:手动降低风扇转速可能导致温度升高。测试时应同时监控 CPU/GPU 温度。
  • 不要写入不存在的 pwm:写入 /sys/class/hwmon/hwmon4/pwm6 如果文件不存在,命令会报错。
  • 权限:需要 root 权限,推荐使用 sudo teesudo sh -c 'echo value > file'

五、如何确定 pwm 与风扇的对应关系?

由于主板布局差异,无法仅凭编号判断。最可靠的方法是 实际测试

  1. 记录当前所有 fan*_input 的值。
  2. pwm1 设为手动并写入 255(全速),观察哪个风扇转速上升。
  3. 恢复 pwm1 为自动模式。
  4. 重复对 pwm2pwm3 … 进行测试。
# 测试 pwm1 的示例脚本
for pwm in /sys/class/hwmon/hwmon4/pwm[0-9]*; do
    pwm_num=$(basename "$pwm")
    echo "Testing $pwm_num..."
    echo 1 | sudo tee "${pwm}_enable"
    echo 255 | sudo tee "$pwm"
    sleep 2
    sensors | grep -E 'fan[0-9]+:'
    echo 2 | sudo tee "${pwm}_enable"
done

观察输出中哪个风扇转速显著提高。

六、常见问题与解决

问题 1:pwmX 写入无效

  • 检查 pwmX_enable 是否为 1(手动模式)。
  • 某些芯片需要先设置 pwmX_enable = 1 才能接受 pwmX 写入。
  • 如果 pwmX 文件不存在,说明该通道未提供或芯片不支持。

问题 2:sensors 输出混乱,包含多个芯片

sensors 会聚合所有 hwmon 设备。若要只看 NCT6775 的数据:

sensors nct6775-*   # 具体名称可用 sensors -u 查看

或直接读取对应文件:

cat /sys/class/hwmon/hwmon4/fan*_input

问题 3:模块加载失败

  • 检查主板是否真的有 Nuvoton 监控芯片(常见于华硕、技嘉等主板)。
  • 查看 dmesg 输出:dmesg | grep nct6775。可能提示 No such device 或需要加载 wmi 模块。
  • 尝试先加载 wmisudo modprobe wmi,再加载 nct6775

七、完整控制示例:将所有风扇调至全速

HWMON=/sys/class/hwmon/hwmon4   # 请替换为实际路径
for pwm in $HWMON/pwm[0-9]*; do
    echo 1 | sudo tee "${pwm}_enable" 2>/dev/null
    echo 255 | sudo tee "$pwm" 2>/dev/null
done

恢复自动:

for pwm in $HWMON/pwm[0-9]*; do
    echo 2 | sudo tee "${pwm}_enable" 2>/dev/null
done

八、总结

Linux 下的风扇控制本质是通过 sysfs 文件系统与内核 hwmon 驱动交互。理解 /sys/class/hwmon/ 下的 pwm*fan* 文件的含义,以及 pwm*_enable 的模式切换,即可实现灵活的手动调速。实际使用中,务必先确认芯片型号和可用通道,并通过实测建立映射关系。掌握这些底层接口后,用户可以编写脚本实现自定义风扇曲线,甚至集成到温度监控服务中。

警告:手动干预风扇转速可能导致硬件损坏,请在充分理解散热需求和安全边界的前提下操作。