Je voulais piloter le ventilateur d’un vieux NAS Netgear ReadyNAS Ultra 2 sous Debian. Je creuse la doc, plus 15 ans de forums : « le ventilo ReadyNAS est piloté via /dev/ttyS1, port série interne, protocole propriétaire Netgear \x00/\x01/\x02/\x03 ». Tout le monde recopie ce mantra.
J’avais même rédigé un script qui fait printf '\x02' > /dev/ttyS1, valeurs notées « indicatives, à valider ». Je m’apprêtais à brancher un sniffeur logique pour reverse-engineer le PIC interne.
Avant de me lancer, un réflexe : ls /sys/class/hwmon/
$ cat /sys/class/hwmon/hwmon0/name
it8721
C’est une puce ITE IT8721 Super-IO, exactement la même qu’on trouve sur des cartes mères grand public. Driver kernel it87 chargé natif. PWM exposé en sysfs, RPM lisible. Aucun protocole proprio. Aucun port série.
echo 1 > /sys/class/hwmon/hwmon0/pwm1_enable # mode manuel
echo 200 > /sys/class/hwmon/hwmon0/pwm1
cat /sys/class/hwmon/hwmon0/fan1_input # → 3054 RPM ✅
Mais pas si vite — le test sur la durée a révélé une mécanique firmware qu’aucune doc ne mentionne, et qui m’a fait passer plusieurs itérations avant un réglage qui tient.
Itération 1 — script pwm=80, écriture toutes les 15 secondes. À l’oreille : oscillation audible. À la mesure (échantillon RPM toutes les 3s) : 1654 ↔ 1834 ↔ 1278 ↔ 2096. Variation 25 %. Pourquoi ? Le firmware IT87 reset périodiquement le PWM vers son auto_start interne, même en mode manuel. Une espèce de smart guardian hardware qui considère que « le soft a oublié d’alimenter le ventilo ».
Itération 2 — réécriture toutes les 2 secondes au lieu de 15. Mieux mais pas suffisant : le firmware reste plus rapide que la boucle, et capture en flagrant délit pwm_lu=50 pendant que le script écrit 80.
Itération 3 — boucle 1 seconde. Là, la fenêtre est plus courte que le reset firmware. Mais nouveau piège révélé par un sweep méthodique de pwm 70 → 100, puis 71 → 78 par incréments de 1 :
pwm=70 : RPM 1146-1654 (delta 508 — explose)
pwm=71 : RPM 1121-1662 (delta 541 — explose encore)
pwm=72 : RPM 1662-1683 (delta 21 — seuil net)
pwm=73 : RPM 1687-1700 (delta 13)
pwm=80 : RPM 1819-1824 (delta 5)
pwm=100: RPM 2096-2122 (delta 26)
Le firmware change de comportement entre pwm=71 et pwm=72. Sous 72, il considère qu’on est en dérive (sans doute un seuil de protection moteur), et reset agressivement. À partir de 72, il laisse passer.
Itération 4 (et insight final) — pwm=72 stable c’est bien, mais ~1700 RPM reste audible. Au tout début de la session j’avais lu pwm=50 / RPM=1268. Comment ça pouvait marcher si pwm=50 oscille ?
Test : écrire pwm=50 une seule fois sans réécrire en boucle. Résultat : RPM stable 1254-1259 sur 90s (delta 5 RPM). Le firmware n’oscille plus !
Le mécanisme : le firmware IT87 a une valeur « native » pwm1_auto_start=50 qu’il respecte si on l’écrit. Entre 51 et 71, il considère qu’on essaie de descendre sous son auto_start et reset agressivement. À 72+, il laisse passer mais peut reset périodiquement (d’où la boucle 1s nécessaire).
Donc en mode idle, on n’écrit pas en boucle — on écrit pwm=50 une fois, et le firmware tient la valeur tranquille.
Réglage final hybride :
while :; do
eval_target # recalcule pivot thermique
if [ "$target" = 50 ]; then
# Mode idle : ecrit 1x, le firmware tient la valeur stable
echo 50 > pwm1
sleep 15
else
# Mode chaud : boucle 1s pour neutraliser le firmware reset
for _ in $(seq 1 15); do
echo $target > pwm1
sleep 1
done
fi
done
Mesure : RPM 1254-1259 (delta 5, variation 0,4 %). 1256 RPM stable, c’est ce que le NAS faisait à l’achat il y a 15 ans. Et c’est inaudible.
Lessons learned :
- Pour du hardware grand public ré-utilisé sous Linux moderne, toujours commencer par
lsmodetls /sys/class/hwmon/— pas de driver custom à écrire. - Le sysfs facilite mais ne suffit pas — il faut tester sur la durée pour révéler les comportements firmware non documentés.
- L’instrumentation (mesure RPM toutes les secondes) révèle des oscillations qu’on n’entend pas en visuel. Sans la mesure, on aurait laissé le ventilo s’user.
- Faire un sweep méthodique des paramètres révèle les zones de stabilité — mais peut être trompeur si on n’identifie pas les valeurs « natives » du firmware. Mon sweep m’avait fait conclure « pwm ≥ 72 = stable » — vrai, mais j’avais raté que pwm=50 (la valeur auto_start) est aussi stable, pour une autre raison : le firmware respecte sa propre cible.
- Quand un soft et un firmware se parlent, demander à voir ce que le firmware aurait fait sans soft est un excellent debug. La valeur initiale lue à la première session (
pwm=50, RPM=1268) était la vraie référence — j’ai mis 5 itérations pour y revenir. - Le bon réglage n’a pas une seule dimension. Il faut les bonnes valeurs ET le bon timing : pwm=72 nécessite réécriture chaque seconde, pwm=50 nécessite de ne PAS réécrire. Mode hybride selon palier.
Au final : 70 lignes de bash, hystérésis et logique hybride incluses. Pas le sniffeur logique sur PIC inconnu — mais plusieurs heures de tuning par mesure, et un retour humble à la valeur que le hardware indiquait dès la première lecture.
#sysadmin #linux #embedded #lm-sensors #hwmon #nas #homelab #reverseengineering #it87 #fancontrol