Soir de migration NAS, je suis dans le shell BusyBox du firmware Netgear recovery. Pas de réseau (pas de driver chargé pour la NIC Marvell, pas de modules dans /lib/modules). Pas de port USB libre. Juste une console série à 9600 baud.
J’ai besoin de pousser un fichier binaire de 3464 octets (chain.c32 syslinux 3.31, récupéré du source kernel.org) sur la partition FAT du flash interne. Comment fait-on ?
Le problème de la console série en binaire pur
Première idée : pipe le fichier brut.
# Côté PC
cat chain.c32 > /dev/ttyUSB0
Ça ne marche pas sur une console qui sert aussi de terminal :
- Caractères de contrôle (
\x03= SIGINT,\x04= EOF,\x1A, etc.) interprétés par le shell distant - Pas de flow control en 8N1 → buffer overflow
- Aucun moyen de vérifier l’intégrité
Solution : encoder en \xNN et envoyer en chunks
L’idée : transformer le binaire en commandes shell qui se construisent côté distant via printf. BusyBox 1.7 (2008) supporte printf '\xNN' parfaitement.
Script Python côté PC :
import time
with open('chain-v331.c32', 'rb') as f:
data = f.read()
CHUNK = 64 # 64 octets par ligne → ~700 chars escape
DELAY = 0.4 # pause sans flow control
with open('/dev/ttyUSB0', 'wb', buffering=0) as ser:
ser.write(b"rm -f /tmp/out && touch /tmp/out\n")
time.sleep(2)
for i in range(0, len(data), CHUNK):
chunk = data[i:i+CHUNK]
escaped = ''.join(f'\\x{b:02x}' for b in chunk)
cmd = f"printf '{escaped}' >> /tmp/out\n"
ser.write(cmd.encode('ascii'))
time.sleep(DELAY)
ser.write(b"md5sum /tmp/out\n")
55 chunks pour 3464 octets, ~30 secondes au total. Le sleep est crucial sans flow control matériel : sans lui, le UART distant rate des bytes.
Vérification d’intégrité
Côté distant après transfert :
# md5sum est dans BusyBox 1.7 (heureusement)
md5sum /tmp/out
b7dcfcbea839adc5d03ae10e63737eb5 /tmp/out
Côté local sur le fichier source : MD5 identique → 0 octet perdu.
Lessons learned
- CHUNK adapté : ligne shell >4 KB → BusyBox refuse. 64 octets binaires = 700 chars escape, large marge.
- Hex (
\xNN) > base64 : BusyBox 1.7 n’a pasbase64(ajouté en 1.20+) nixxd -r.printf '\xNN'est universel. md5sumcôté distant pour valider — sans ça, on ne sait pas si l’écriture a réussi.- Pas de flow control =
sleepindispensable. Avec RTS/CTS matériel on pourrait dégager. - Gros transferts (>1 Mo) : monter le baud rate à 115200 (~10 KB/s) ou trouver un autre canal (xmodem, réseau).