PVE 环境下 GMKtec NucBox K8 Plus 顶部风扇转速控制教程

GMKtec NucBox K8 Plus 在 Proxmox VE (PVE) 环境下,顶部风扇(fan2)会出现转速疯狂波动的问题:

  • 伴随CPU频率变化,风扇转速在 1100-2200 RPM 之间抽风式变化
  • 实际负载极低,且极易触发
  • 关键原因:PVE 默认不支持 IT8613E 芯片驱动

解决思路:

  1. 手动编译安装 IT87 驱动
  2. 通过 systemd 定时任务,根据 NVMe&Cpu 双温度动态控制风扇转速

环境信息

  • 系统: Proxmox VE 9.x
  • 设备: GMKtec NucBox K8 Plus (原则上同模型的 AMD 主机都适用 如 M7等)
  • 芯片组: IT8613E (需要手动编译驱动)
  • 风扇配置:

    • fan2: 顶部机箱风扇(需要控制)
    • fan3: CPU 风扇(保持 BIOS 自动控制)

第一步:编译安装 IT87 驱动

1. 安装编译工具和内核头文件

apt update
apt install -y git build-essential dkms pve-headers-$(uname -r)

2. 下载 IT87 驱动源码

cd /tmp
git clone https://github.com/frankcrawford/it87.git
cd it87

3. 编译驱动

make clean
make

预期输出:

make -C /lib/modules/6.8.12-4-pve/build M=/tmp/it87 modules
...
CC [M]  /tmp/it87/it87.o
...
LD [M]  /tmp/it87/it87.ko
Skipping BTF generation for /tmp/it87/it87.ko due to unavailability of vmlinux

如果看到 it87.ko 生成成功,即可继续。

4. 安装驱动

make install

5. 加载驱动模块

# 基本加载命令
modprobe it87 force_id=0x8613

# 如果遇到 "Resource conflict" 错误,使用:
modprobe it87 force_id=0x8613 ignore_resource_conflict=1

6. 验证驱动加载

# 检查模块是否加载
lsmod | grep it87

# 查看内核日志
dmesg | grep -i it8 | tail -20

# 安装传感器工具
apt install lm-sensors

# 检测传感器
sensors-detect  # 一路回车

# 查看传感器数据
sensors

预期输出:

it8613-isa-0a30
Adapter: ISA adapter
fan2:        1155 RPM
fan3:        1687 RPM
temp1:        +31.0°C
pwm2:             30%
pwm3:             65%

7. 设置开机自动加载

# 添加模块到自动加载列表
echo "it87" > /etc/modules-load.d/it87.conf

# 设置模块参数
echo "options it87 force_id=0x8613 ignore_resource_conflict=1" > /etc/modprobe.d/it87.conf

# 更新 initramfs
update-initramfs -u

第二步:确认硬件信息

1. 查看传感器数据

sensors

关键输出:

it8613-isa-0a30
fan2:        1155 RPM
pwm2:             30%

nvme-pci-0400
Composite:    +31.9°C

2. 定位风扇控制接口

# 查找 hwmon 编号
ls /sys/class/hwmon/

# 确认 it8613 对应的 hwmon 编号
cat /sys/class/hwmon/hwmon*/name

假设输出为 hwmon7(根据实际情况调整)。


第三步:测试手动控制

1. 切换到手动模式

# 查看当前模式(2=自动, 1=手动)
cat /sys/class/hwmon/hwmon7/pwm2_enable

# 切换到手动模式
echo 1 > /sys/class/hwmon/hwmon7/pwm2_enable

2. 测试不同转速

# PWM 值范围 0-255
echo 51 > /sys/class/hwmon/hwmon7/pwm2   # 20% - 超静音
echo 102 > /sys/class/hwmon/hwmon7/pwm2  # 40% - 正常
echo 153 > /sys/class/hwmon/hwmon7/pwm2  # 60% - 高速

观察风扇转速变化:

watch -n 1 'sensors | grep fan2'

第四步:创建智能控制脚本

1. 编写控制脚本

nano /usr/local/bin/fan2-control.sh

粘贴以下内容:

#!/bin/bash

#======================================
# 双温度源智能风扇控制脚本
# 功能:
#  1. 同时监控 CPU 和 NVMe 温度
#  2. 取最高温度作为控制依据
#  3. 渐进式调整 PWM(避免突变)
#  4. 自动检测 hwmon 路径
#======================================

# 配置区域
FAN_PWM_ID="pwm2"                    # 风扇 PWM 接口
SENSOR_CPU="k10temp-pci-00c3"        # CPU 传感器名称
SENSOR_NVME="nvme-pci-0400"          # NVMe 传感器名称
LOG_FILE="/var/log/fan-control.log"  # 日志文件(可选)
ENABLE_LOG=false                     # 是否启用日志

# 精确查找 it8613 的 hwmon 路径
HWMON_PATH=$(grep -l "it8613" /sys/class/hwmon/hwmon*/name 2>/dev/null | sed 's|/name||' | head -1)
if [ -z "$HWMON_PATH" ]; then
    echo "错误:未找到 it8613 硬件接口"
    exit 1
fi
# 验证 pwm2 是否存在
if [ ! -f "$HWMON_PATH/$FAN_PWM_ID" ]; then
    echo "错误:$HWMON_PATH 不支持 $FAN_PWM_ID"
    exit 1
fi

#======================================
# 函数:获取温度(带容错)
#======================================
get_temp() {
    local sensor=$1
    local field=$2
    local temp=$(sensors "$sensor" 2>/dev/null | grep "$field" | awk '{print $2}' | sed 's/+//;s/°C//' | cut -d. -f1)
    
    # 容错:如果获取失败或无效,返回默认值 30
    if [ -z "$temp" ] || [ "$temp" -lt 0 ] || [ "$temp" -gt 120 ]; then
        echo 30
    else
        echo "$temp"
    fi
}

#======================================
# 函数:根据温度计算目标 PWM
#======================================
calculate_pwm() {
    local temp=$1
    
    if [ "$temp" -lt 35 ]; then
        echo 51    # 20%
    elif [ "$temp" -lt 45 ]; then
        echo 77    # 30%
    elif [ "$temp" -lt 55 ]; then
        echo 102   # 40%
    elif [ "$temp" -lt 65 ]; then
        echo 128   # 50%
    elif [ "$temp" -lt 70 ]; then
        echo 153   # 60%
    elif [ "$temp" -lt 75 ]; then
        echo 179   # 70%
    else
        echo 230   # 90% - 紧急降温
    fi
}

#======================================
# 主逻辑
#======================================

# 1. 获取温度
CPU_TEMP=$(get_temp "$SENSOR_CPU" "Tctl")
NVME_TEMP=$(get_temp "$SENSOR_NVME" "Composite")

# 2. 取最高温度
MAX_TEMP=$((CPU_TEMP > NVME_TEMP ? CPU_TEMP : NVME_TEMP))

# 3. 计算目标 PWM
TARGET_PWM=$(calculate_pwm "$MAX_TEMP")

# 4. 获取当前 PWM 值
CURRENT_PWM=$(cat "$HWMON_PATH/$FAN_PWM_ID" 2>/dev/null || echo "$TARGET_PWM")

# 5. 渐进式调整(平均值法,避免突变)
NEW_PWM=$(( (CURRENT_PWM + TARGET_PWM) / 2 ))

# 6. 应用设置
echo 1 > "$HWMON_PATH/${FAN_PWM_ID}_enable" 2>/dev/null  # 手动模式
echo "$NEW_PWM" > "$HWMON_PATH/$FAN_PWM_ID" 2>/dev/null

# 7. 可选:记录日志
if $ENABLE_LOG; then
    TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
    PERCENT=$(( NEW_PWM * 100 / 255 ))
    echo "$TIMESTAMP | CPU:${CPU_TEMP}°C NVMe:${NVME_TEMP}°C MAX:${MAX_TEMP}°C | PWM:${NEW_PWM}(${PERCENT}%) | 路径:$HWMON_PATH" >> "$LOG_FILE"
fi

exit 0

2. 赋予执行权限

chmod +x /usr/local/bin/fan2-control.sh

3. 测试脚本

/usr/local/bin/fan2-control.sh
sensors | grep -E "Composite|fan2|pwm2"

第五步:配置自动运行

1. 创建 systemd service

nano /etc/systemd/system/fan2-control.service
[Unit]
Description=Dynamic fan2 control based on NVMe temperature
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/fan2-control.sh

2. 创建定时器(每 20 秒执行一次)

nano /etc/systemd/system/fan2-control.timer
[Unit]
Description=Run fan2 control every 20 seconds
Requires=fan2-control.service

[Timer]
OnBootSec=30
OnUnitActiveSec=20s
Unit=fan2-control.service

[Install]
WantedBy=timers.target

3. 启用并启动服务

systemctl daemon-reload
systemctl enable fan2-control.timer
systemctl start fan2-control.timer

4. 检查运行状态

systemctl status fan2-control.timer
systemctl status fan2-control.service

预期输出:

● fan2-control.timer - Run fan2 control every 20 seconds
     Loaded: loaded (/etc/systemd/system/fan2-control.timer; enabled)
     Active: active (waiting) since Sat 2025-12-27 13:41:26 CST

第六步:监控与调优

1. 实时监控

watch -n 2 '
echo "=== 系统时间 ==="
date "+%Y-%m-%d %H:%M:%S"
echo ""

echo "=== CPU 温度 ==="
sensors k10temp-pci-00c3 | grep Tctl

echo ""
echo "=== NVMe 温度 ===" 
sensors nvme-pci-0400 | grep Composite

echo ""
echo "=== 风扇控制器 (it8613) ==="
sensors it8613-isa-0a30 | grep -E "fan2|pwm2"

echo ""
echo "=== 当前 hwmon 路径 ==="
grep -l "it8613" /sys/class/hwmon/hwmon*/name 2>/dev/null | sed "s|/name||"

echo ""
echo "=== 脚本运行状态 ==="
if pgrep -f fan-control.sh > /dev/null; then
    echo "✅ 风扇控制脚本正在运行"
else
    echo "❌ 风扇控制脚本未运行"
fi
'

预期输出:

=== 系统时间 ===
2024-01-15 14:30:25

=== CPU 温度 ===
Tctl:         +45.0°C  

=== NVMe 温度 ===
Composite:    +30.9°C  (low  = -273.1°C, high = +81.8°C)

=== 风扇控制器 (it8613) ===
fan2:         717 RPM  (min =    0 RPM)
pwm2:             26%  (freq = 23437 Hz)

=== 当前 hwmon 路径 ===
/sys/class/hwmon/hwmon7

=== 脚本运行状态 ===
✅ 风扇控制脚本正在运行

2. 压力测试

# 安装测试工具
apt install fio

# 持续读写测试(让 NVMe 升温)
fio --name=test --filename=/tmp/testfile --size=2G --rw=randrw --bs=4k --direct=1 --numjobs=4 --time_based --runtime=60s

在另一个终端观察风扇响应:

watch -n 1 'sensors | grep -E "Composite|fan2|pwm2"'

3. 启用日志(可选)

更改脚本中的日志选项

ENABLE_LOG=true

然后:

# 实时查看
tail -f /var/log/fan2-control.log

# 分析温度变化
cat /var/log/fan2-control.log | tail -100

温度策略说明

NVMe 温度PWM 值转速比例使用场景
< 35°C5120%待机/轻度使用
35-45°C7730%日常办公/浏览
45-55°C10240%正常读写/下载
55-65°C12850%高强度 IO/编译
65-70°C15360%持续高负载
> 70°C20480%紧急降温

注意: NVMe 固态硬盘不应长期超过 70°C,超过 80°C 可能触发降频保护 (CPU基本上也是这个区间)。


故障排查

问题 1:编译驱动失败

现象: make: *** No rule to make target 'modules'. Stop.

解决方法:

# 确认内核头文件已安装
dpkg -l | grep pve-headers
apt install pve-headers-$(uname -r)

# 重新编译
cd /tmp/it87
make clean
make

问题 2:加载驱动时 Resource conflict

现象: modprobe: ERROR: could not insert 'it87': Device or resource busy

解决方法:

# 使用 ignore_resource_conflict 参数
modprobe it87 force_id=0x8613 ignore_resource_conflict=1

# 或者卸载可能冲突的模块
rmmod iTCO_wdt iTCO_vendor_support
modprobe it87 force_id=0x8613

问题 3:风扇转速仍然波动

可能原因:

  • BIOS 设置干扰(检查 Smart Fan Control)
  • 温度阈值设置过于敏感

解决方法:

  1. 进入 BIOS 禁用 Smart Fan Control
  2. 加大温度阈值间隔(如 35→40, 45→50)
  3. 降低检测频率(20s → 30s)

问题 4:PVE 内核更新后驱动失效

现象: 系统更新后 sensors 不再显示 it8613

解决方法:

# 重新编译驱动
cd /tmp/it87
make clean
make
make install

# 重新加载模块
modprobe -r it87
modprobe it87 force_id=0x8613 ignore_resource_conflict=1

# 更新 initramfs
update-initramfs -u

使用 DKMS 自动重编译(推荐):

# 安装 DKMS 版本
cd /tmp/it87
make dkms

# 以后内核更新会自动重新编译

卸载方法

# 停止并禁用服务
systemctl stop fan2-control.timer
systemctl disable fan2-control.timer

# 删除服务文件
rm /etc/systemd/system/fan2-control.timer
rm /etc/systemd/system/fan2-control.service
rm /usr/local/bin/fan2-control.sh

# 重载 systemd 配置
systemctl daemon-reload

# 卸载驱动
modprobe -r it87
rm /etc/modules-load.d/it87.conf
rm /etc/modprobe.d/it87.conf

# 删除驱动文件
cd /tmp/it87
make uninstall

# 更新 initramfs
update-initramfs -u

# 恢复风扇自动模式(可选)
echo 2 > /sys/class/hwmon/hwmon7/pwm2_enable

参考资源


总结

✅ 驱动问题解决: 手动编译 IT8613E 驱动
✅ 风扇波动修复: fan2 不再抽风(实际上是安静的抽风)
✅ 智能调速: 根据 NVMe&Cpu 温度动态调整
✅ 开机自启: systemd + 模块自动加载
✅ 低噪音运行: 待机时保持 20% 静音


OK!现在可以享受安静的小主机了 ! 🎉

本文链接:

https://blog.coffox.cc/archives/49/
1 + 6 =
快来做第一个评论的人吧~