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 | 芯片名称,如 nct6775、coretemp |
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 控制 fan1,pwm2 控制 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 tee或sudo sh -c 'echo value > file'。
五、如何确定 pwm 与风扇的对应关系?
由于主板布局差异,无法仅凭编号判断。最可靠的方法是 实际测试:
- 记录当前所有
fan*_input的值。 - 将
pwm1设为手动并写入 255(全速),观察哪个风扇转速上升。 - 恢复
pwm1为自动模式。 - 重复对
pwm2、pwm3… 进行测试。
# 测试 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模块。 - 尝试先加载
wmi:sudo 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 的模式切换,即可实现灵活的手动调速。实际使用中,务必先确认芯片型号和可用通道,并通过实测建立映射关系。掌握这些底层接口后,用户可以编写脚本实现自定义风扇曲线,甚至集成到温度监控服务中。
警告:手动干预风扇转速可能导致硬件损坏,请在充分理解散热需求和安全边界的前提下操作。