Comme indiqué dans mon article décrivant mon réseau, je dispose de 3 Raspberry Pi 0 W auxquels sont branchés mes onduleurs USB ; de quoi me permettre de les superviser depuis Home Assistant. Ils tournaient plutôt bien sur Raspberry Pi OS (basé sur une debian Bookworm), et j’ai mis très longtemps avant de me décider à les mettre à jour vers Trixie. C’est chose faite, mais ça ne s’est pas fait sans mal.
Avertissement : article d’humeur dans lequel je suis vulgaire.
« Installation » de Raspberry Pi OS
Pour commencer, la fondation Raspberry Pi recommande de ne pas faire un apt full-upgrade.
Personnellement, ça me gonfle : c’est bien beau de se baser sur une distro si c’est pour ne pas en suivre les principes élémentaires, d’autant qu’il était possible de le faire par le passé.
Donc, on télécharge le Raspberry Pi Imager. Je suis docile : c’est la méthode mise en avant par l’entreprise, devant leur solution cloud, mais le téléchargement direct des images est encore possible.
Dès le lancement du Raspberry Pi Imager, on sent que tout est fait pour nous tenir la bite pour pisser (avec télémétrie activée par défaut, en plus de ça). On sélectionne la board avec de jolies images, puis l’application nous montre les systèmes compatibles, en mettant bien en avant les éditions desktop. Les versions « Lite », elles, se retrouvent planquées derrière une icône privée de ses couleurs, reléguées au second plan.
Le ton est donné : le Raspberry Pi est une machine desktop avant tout. Il est loin le temps des machines pour les makers, et on va voir plus loin que cette rupture est bien ancrée jusque dans le système d’exploitation.
Première carte flashée, j’en ai deux autres strictement identiques à produire, à l’exception du nom d’hôte. Je m’attendais à une procédure plus simple, surtout quand je clique sur le bouton pour flasher une autre carte. Sauf que ça revient à repartir depuis le premier écran. C’était bien la peine de me proposer l’option si c’est pour que je me farcisse à nouveau toutes les options chiantes (notamment la désactivation du cloud dont je me contrefous).
Premier boot
Je le sais, le premier boot est long parce que la partition racine est redimensionnée. Je m’attendais à ce que le deuxième boot soit plus court : il fallait une vingtaine de secondes à Bookworm pour démarrer.
Là, il lui a fallu plus de 3 minutes.
root@ups-eaton-3s-850:~# systemd-analyze
Startup finished in 13.550s (kernel) + 3min 260ms (userspace) = 3min 13.811s
multi-user.target reached after 1min 45.004s in userspace.
root@ups-eaton-3s-850:~# systemd-analyze blame | head -50
1min 13.085s cloud-final.service
50.295s NetworkManager.service
18.785s cloud-init-main.service
15.316s dev-mmcblk0p2.device
6.848s apt-daily-upgrade.service
5.302s systemd-rfkill.service
4.469s rpi-resize-swap-file.service
3.939s cloud-init-local.service
3.585s sys-kernel-tracing.mount
3.535s keyboard-setup.service
3.528s sys-kernel-debug.mount
3.472s user@0.service
3.450s run-lock.mount
3.409s kmod-static-nodes.service
3.404s dev-mqueue.mount
3.359s modprobe@configfs.service
3.344s systemd-logind.service
3.319s modprobe@drm.service
3.318s systemd-udev-trigger.service
3.126s NetworkManager-wait-online.service
3.028s modprobe@fuse.service
2.409s systemd-fsck@dev-disk-by\x2dpartuuid-641adb19\x2d01.service
2.398s avahi-daemon.service
2.363s bluetooth.service
2.348s e2scrub_reap.service
2.339s systemd-timesyncd.service
2.320s systemd-journald.service
2.058s systemd-tmpfiles-setup.service
2.048s systemd-modules-load.service
1.969s systemd-remount-fs.service
1.968s systemd-udevd.service
1.915s wpa_supplicant.service
1.899s systemd-binfmt.service
1.862s dbus.service
1.849s systemd-udev-load-credentials.service
1.831s cloud-config.service
1.749s sshswitch.service
1.728s systemd-random-seed.service
1.719s systemd-tmpfiles-setup-dev-early.service
1.719s systemd-sysctl.service
1.649s sys-kernel-config.mount
1.605s sys-fs-fuse-connections.mount
1.528s rpi-eeprom-update.service
1.518s systemd-journal-flush.service
1.300s cloud-init-network.service
1.297s systemd-user-sessions.service
1.198s alsa-restore.service
1.014s rpi-setup-loop@var-swap.service
964ms systemd-hostnamed.service
945ms console-setup.service
La moitié de ce temps de boot est dû au machin de cloud que j’avais désactivé au moment de créer la carte SD. Bonjour la confiance, ça valait le coup de me demander.
On dégage tout ça :
systemctl disable cloud-init-local cloud-config cloud-final
apt purge cloud-init -y
rm -rf /etc/cloud /var/lib/cloud /var/log/cloud-init*
apt autoremove --purge -y
reboot
Ça réduit de moitié le temps de boot, comme attendu :
Startup finished in 13.556s (kernel) + 1min 27.400s (userspace) = 1min 40.957s
multi-user.target reached after 1min 27.389s in userspace.
55.001s NetworkManager.service
15.441s dev-mmcblk0p2.device
7.221s systemd-rfkill.service
4.449s rpi-resize-swap-file.service
3.615s sys-kernel-debug.mount
3.606s user@0.service
3.573s sys-kernel-tracing.mount
3.534s keyboard-setup.service
3.468s run-lock.mount
3.457s avahi-daemon.service
3.416s kmod-static-nodes.service
3.343s modprobe@configfs.service
3.326s dev-mqueue.mount
3.299s modprobe@drm.service
3.213s modprobe@efi_pstore.service
3.175s systemd-udev-trigger.service
3.008s modprobe@fuse.service
2.910s e2scrub_reap.service
2.696s systemd-logind.service
2.563s dbus.service
2.465s ssh.service
2.411s systemd-fsck@dev-disk-by\x2dpartuuid-641adb19\x2d01.service
2.364s systemd-journald.service
2.318s systemd-timesyncd.service
2.231s systemd-hostnamed.service
1.998s systemd-modules-load.service
1.932s sshswitch.service
1.914s rpi-eeprom-update.service
1.909s systemd-remount-fs.service
1.906s systemd-udevd.service
Néanmoins, à peine installé, le système pèse déjà près de 2.5G, mais pour le moment, c’est le cadet de mes soucis.
Optimisation du réseau
Maintenant, c’est Network Manager qui fout sa merde.
En fait, il passe son temps à attendre (et faire attendre) le système.
Je vous passe les détails parce que moi-même, je n’ai pas tout compris, mais en gros, le combo Network Manager + netplan, c’est de la merde en barre (je le savais déjà, mais sur une machine comme le Pi 0 W, c’est punitif).
J’ai fini par passer à un combo beaucoup plus docile, composé de dhcpcd et wpa_supplicant, avant de virer Network Manager.
apt install dhcpcd wpasupplicant
nano /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
On colle la configuration adaptée :
country=FR
ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev
update_config=0
network={
ssid="{{ wifi_ssid }}"
psk={{ wifi_psk }}
key_mgmt=WPA-PSK
}
(Remplacez les {{ ... }} par le nom du réseau et la clé)
Attention : dhcpcd ne définit pas le clientid de la machine comme le fait Network Manager.
Du coup, le serveur DHCP n’attribue pas la bonne IPv4 au Raspberry Pi (mais étonnamment, l’IPv6 est correcte).
Il faut modifier /etc/dhcpcd.conf, et ajouter la ligne clientid (putain de hack à la con).
Ensuite :
systemctl enable dhcpcd
systemctl enable wpa_supplicant@wlan0
systemctl disable NetworkManager NetworkManager-dispatcher
reboot
Pendant le debug, je remarque d’ailleurs que la couche bluetooth est installée et active, ainsi que avahi.
apt purge -y bluez avahi-daemon network-manager network-manager-l10n
apt autoremove --purge -y
Une fois ces modifications effectuées, le boot prend un peu plus de 45 secondes.
Il y a clairement encore de la marge pour optimiser.
Mais avant, il faut régler la question d’apt…
Apt et les miroirs
Une fois sur deux (bon, presque toujours), une commande apt foire parce qu’il n’arrive pas à joindre un miroir russe (mirror.truenetwork.ru).
Dans /etc/apt/sources.list.d/raspbian.sources, on remplace l’URIs par défaut par :
URIs: http://mirrors.ircam.fr/pub/raspbian/raspbian/
Puis :
apt update
C’est réglé, cocorico 🐓.
Nettoyage des paquets
Là, il y a une sacrée liste. Je ne vais pas entrer dans les détails pour chacun, mais je vais évoquer les cas les plus symptomatiques. En substance, je nettoie tout ça :
apt purge -y cloud-init bluez avahi-daemon rpi-connect-lite rpicam-apps-lite rpicam-apps-core v4l-utils alsa-utils alsa-topology-conf alsa-ucm-conf build-essential gcc g++ gdb strace linux-headers-rpi-v6 linux-headers-rpi-v7 linux-image-rpi-v7 linux-image-rpi-v8 linux-image-6.12.75+rpt-rpi-v7 linux-image-6.12.75+rpt-rpi-v8 manpages manpages-dev apt-listchanges udisks2 rpi-update rpi-eeprom rpi-keyboard-config rpi-keyboard-fw-update usb-modeswitch usb-modeswitch-data ntfs-3g exfatprogscifs-utils firmware-atheros firmware-libertas firmware-mediatek firmware-realtek linux-headers-6.12.75+rpt-common-rpi linux-headers-6.12.75+rpt-rpi-v6 linux-libc-dev libc6-dev gcc-14 gcc-14-arm-linux-gnueabihf libgcc-14-dev cpp-14 cpp-14-arm-linux-gnueabihf binutils binutils-arm-linux-gnueabihf binutils-common libbinutils mkvtoolnix console-setup console-setup-linux keyboard-configuration kbd xkb-data rpi-swap rpi-loop-utils systemd-zram-generator kms++-utils libkms++0 libdrm-omap1 shared-mime-info ncurses-term bluez-firmware libmtp-runtime
Ne copiez pas aveuglément cette liste. Ce sont des paquets « en trop » selon mon usage (serveur headless). C’est juste pour vous donner une idée de la quantité de trucs préinstallés pour une image considérée comme minimale par Raspberry Pi.
initramfs
Par défaut, le système génère trois initramfs, dont seul le suffixe diffère : -v6, -v7 et -v8.
Sur le Pi 0W (ARMv6), seul le premier est utilisé.
Les deux autres sont destinés à une architecture 64 bits.
Pourquoi générer un (plus encore : deux) initramfs pour une architecture qui ne sera jamais supportée sur le Pi 0W ?
Pour faire des économies ?
Outils de dev
Honnêtement, qui va aller s’amuser à compiler quelque chose sur un Pi 0 W ? J’ai essayé un jour. J’ai déjà pas la patience de compiler un truc sur une machine moderne à 16 cœurs, c’est pas pour m’amuser à le faire sur une machine équivalente à un Pentium III. Pas en 2026.
Économies de la carte mémoire
On le sait : une carte SD, surtout sur un Pi, ça s’use. Donc, j’ai fait quelques optimisations pour éviter la journalisation sur la carte. De toute façon, sur une machine qui se contente de relayer les infos d’un onduleur, on n’a pas besoin de journalisation à long terme.
mkdir -p /etc/systemd/journald.conf.d /etc/sysctl.d
cat >/etc/systemd/journald.conf.d/10-volatile-low-write.conf <<'EOF'
[Journal]
Storage=volatile
RuntimeMaxUse=16M
MaxRetentionSec=1day
Compress=no
SyncIntervalSec=5m
EOF
cat >/etc/sysctl.d/99-sdcard-low-write.conf <<'EOF'
vm.dirty_writeback_centisecs = 1500
vm.dirty_expire_centisecs = 3000
EOF
systemctl restart systemd-journald
sysctl --system
journalctl --vacuum-time=1s
rm -rf /var/log/journal
reboot
Désactivation des modules inutilisés
Je n’ai pas besoin de l’audio, de la caméra ni du GPU sur un serveur. Par défaut, la moitié de la mémoire vive y est allouée ! On nettoie tout ça :
cp -a /boot/firmware/config.txt /boot/firmware/config.txt.pre-headless
cp -a /boot/firmware/cmdline.txt /boot/firmware/cmdline.txt.pre-headless
sed -i 's/^dtparam=audio=on/dtparam=audio=off/' /boot/firmware/config.txt
sed -i 's/^camera_auto_detect=1/camera_auto_detect=0/' /boot/firmware/config.txt
sed -i 's/^auto_initramfs=1/auto_initramfs=0/' /boot/firmware/config.txt
sed -i 's/^dtoverlay=vc4-kms-v3d/# dtoverlay=vc4-kms-v3d/' /boot/firmware/config.txt
cat >>/boot/firmware/config.txt <<'EOF'
# Headless UPS appliance optimizations
disable_splash=1
dtoverlay=disable-bt
gpu_mem=16
EOF
sed -i 's/ ds=nocloud;i=rpi-imager-[^ ]*//g' /boot/firmware/cmdline.txt
systemctl disable --now hciuart.service 2>/dev/null || true
reboot
Il reste encore à blacklister des modules noyau :
cat >/etc/modprobe.d/99-headless-ups-blacklist.conf <<'EOF'
blacklist drm
blacklist vc4
blacklist snd_bcm2835
blacklist bcm2835_v4l2
blacklist bcm2835_codec
blacklist bcm2835_isp
blacklist bcm2835_mmal_vchiq
blacklist vc_sm_cma
EOF
systemctl mask modprobe@drm.service
reboot
Services système
Clavier, console, hibernation, tout ça, ça dégage.
systemctl disable --now keyboard-setup.service console-setup.service
systemctl mask keyboard-setup.service console-setup.service
systemctl disable --now rpi-zram-writeback.timer rpi-zram-writeback.service 2>/dev/null || true
systemctl mask rpi-zram-writeback.timer rpi-zram-writeback.service 2>/dev/null || true
systemctl mask \
systemd-hibernate.service \
systemd-hybrid-sleep.service \
systemd-suspend.service \
systemd-suspend-then-hibernate.service \
sleep.target \
suspend.target \
hibernate.target \
hybrid-sleep.target
systemctl disable --now e2scrub_all.timer e2scrub_reap.service dpkg-db-backup.timer
systemctl mask e2scrub_all.timer e2scrub_reap.service dpkg-db-backup.timer
systemctl daemon-reload
reboot
Système utilisable
À ce stade, le système démarre en un peu plus de 30 secondes, tourne avec moins de 40M de mémoire vive, et occupe 1.1G sur la carte SD. C’est pas mal du tout, mais :
- Tout cela est à faire en triple,
- Tout cela sera à refaire à la prochaine mise à jour majeure,
- GNU-Linux pourrait être encore plus frugal
Pour me faciliter la vie, j’ai installé ansible et j’ai créé quelques playbooks, mais ce n’est clairement pas une solution sur le long terme. Pourtant, les Pi 0 W sont parfaitement capables de durer encore quelques années, et avec les optimisations sur l’écriture des cartes SD, elles aussi peuvent durer quelques années. Elles pourraient voir passer plusieurs mises à jour majeures avant de rendre l’âme.
Un manque certain de sobriété
Alors qu’on est en pleine crise de la NAND, je trouve que la politique de Raspberry Pi est scandaleuse. Le système est bloaté (comme quoi, ça arrive aussi dans le Libre), rempli ras-la-gueule de trucs qui ne servent à rien. C’est lent, lourd, chiant à maintenir. Franchement, quelqu’un qui veut se mettre au Pi pour bricoler un peu va vite déchanter.
Vous me direz : non mais quel abruti je suis de ne pas avoir acheté le Raspberry Pi 2 W, quelle idée de s’emmerder avec un machin d’il y a 10 ans.
Merde.
Je n’ai pas besoin de plus.
D’ailleurs, pour ce que j’en fais, un Pi 0 W est même overkill.
Pour tout dire, s’il existait un truc comme nut sur ESP8266, j’aurais installé des ESP8266 au lieu des Pi.
Mais on digresse.
J’ai divisé par deux les besoins en stockage, j’ai fortement réduit la pression sur la mémoire. Ça a demandé un peu de travail, et je suis certain que parmi mes lecteurs, quelques-uns sont sensibles à ça et font pareil chez eux. Ils se vantent parfois – à raison – en brandissant des captures d’écran, exhibant la frugalité de leurs systèmes. Bravo à eux : ils doivent bien se marrer en voyant la crise de la NAND. Et moi aussi.
Conclusion
J’ai déjà fait un rant sur le Raspberry, et je râle souvent sur la plateforme ou son constructeur. À chaque fois, je me dis que la prochaine fois, je passe sur un Orange Pi, ou un autre concurrent.
Maintenant que je les ai, je veux les utiliser un maximum. Force est de constater que leur constructeur ne me facilite pas la tâche. Ce ne sont pas de mauvaises machines, mais l’OS est tellement claqué au sol…
Vous savez quoi, ça m’a donné envie de me faire un petit LFS. Je viens de passer plusieurs jours à configurer un Raspberry Pi OS pour le faire maigrir, autant partir de rien et faire les choses à ma façon…
Soutenir le site
Si mon travail vous a été utile, vous pouvez contribuer aux frais qui permettent au site de rester en ligne, sans publicité intrusive.
Le paiement se fait sur la plateforme choisie : je ne reçois ni ne stocke vos données bancaires.
Taxonomies
Entreprises
Tags
- Bon-Sens 3
- Crise 10
- Frugalité 1
- Geek 39
- Informatique 86
- Linux 36
- Mémoire 34
- NAND 1
- Nut 1
- Onduleur 1
- Rant 12
- Raspberry Pi 0 W 1
- Raspberry Pi OS 1
- Serveur 92
- Système 1
Richard Dern