Introduction
Pour un article qui sortira peut-être sur papier (je croise les doigts), j’avais besoin de tester différents types d’OS à installer sur un Raspberry Pi Zero 2 W.
Comme je ne connaissais ni Alpine, ni les spécificités du Pi Zero 2 W, je suis tombé sur pas mal de trucs que je ne connaissais pas.
Même si au final, l’article papier ne traite pas d’installation d’Alpine Linux (ni même ne l’utilise), je me suis dit que c’était dommage de ne pas publier cette expérience Alpine + RPi Zero, donc la voici.
Pourquoi Alpine Linux ?
Principalement pour sa légèreté et sa faible consommation de ressources. Sur un nano-ordinateur avec seulement 512 Mo de RAM, chaque mégaoctet compte. Alpine Linux est connu pour être minimaliste et aussi un peu controversé (notamment dans le monde Docker) pour le remplacement de la glibc par musl (ce qui provoque parfois des surprises).
L’objectif de cet article est d’avoir une installation headless (sans écran ni clavier) accessible en SSH via WiFi, avec une RAM optimisée au maximum.
On va voir plein de détails techniques intéressants, notamment sur la gestion de la RAM du GPU et la configuration du swap avec zswap !
Téléchargement de l’image Alpine Linux pour Raspberry Pi
La première chose à faire est de télécharger l’image, avant de pouvoir la copier sur une carte microSD qui sera insérée dans le rpi avant boot.
Coup de bol, Alpine Linux propose des images spécifiques pour Raspberry Pi, on ne va pas avoir besoin d’ajouter à la main le firmware des RPi.

On va récupérer la dernière version disponible depuis le site officiel. Exemple :
wget https://dl-cdn.alpinelinux.org/alpine/v3.23/releases/aarch64/alpine-rpi-3.23.2-aarch64.tar.gz
Cette image est spécialement compilée pour l’architecture ARM64 (aarch64) des Raspberry Pi récents (donc mon RPi Zero 2 W).
Configuration headless avec le fichier overlay
Une fois l’image flashée sur votre carte microSD (avec Raspberry Pi Imager par exemple), on va préparer le système pour un accès headless.
Alpine Linux supporte ce qu’on appelle des “overlay files” qui permettent de préconfigurer le système avant le premier boot. C’est documenté dans la documentation officielle sur l’installation headless.
Montez le contenu de votre carte microSD sur votre machine et déposez le fichier overlay à la racine de cette carte microSD :
wget https://github.com/macmpi/alpine-linux-headless-bootstrap/raw/469ee440e7d394cca0976c78f357e7a0e1c82cc4/headless.apkovl.tar.gz
Note : c’est assez flippant de monter un fichier aussi sensible provenant d’un repo github tiers (github.com/macmpi), mais Alpine Linux se veut rassurant en nous disant :
Note: The author of above repo macmpi also maintains a number of packages for Alpine Linux.
Je suis pas beaucoup plus rassuré… mais bon, c’est “officiel”
Ce fichier headless.apkovl.tar.gz configure Alpine pour :
- Booter en mode DHCP
- Activer SSH automatiquement
- Permettre la connexion root sans mot de passe (attention à ne pas laisser ça comme ça trop longtemps !)
Pour que le Raspberry Pi se connecte automatiquement à votre réseau WiFi, créez un fichier wpa_supplicant.conf à la racine de la microSD :
cat > wpa_supplicant.conf << EOF
country=FR
network={
key_mgmt=WPA-PSK
ssid="mySSID"
psk="myPassPhrase"
}
EOF

Remplacez évidemment mySSID et myPassPhrase par vos informations WiFi.
Note : Le projet alpine-linux-headless-bootstrap propose d’autres options de configuration très utiles, comme la définition d’un mot de passe root, d’une adresse IP fixe, etc. Plus d’infos dans leur README.
Premier boot et installation permanente
Une fois le premier boot effectué, connectez-vous en SSH :
ssh root@<ip_du_raspberry>

Attention : Par défaut, le mot de passe root est vide ! Mais on n’a pas besoin de changer ça si on réalise immédiatement l’installation qui suit.
À ce stade, Alpine tourne entièrement en RAM (image “live”). Pour l’installer définitivement, nous allons utiliser l’utilitaire setup-alpine dont les options sont décrites dans wiki.alpinelinux.org/wiki/Installation.
setup-alpine
Voici un petit extrait des informations demandées (somme tout assez classiques pour une install d’OS) :


Suivez les instructions, puis rebootez :
reboot
Optimisation de la RAM GPU
Par défaut sur un Raspberry Pi, une (grande) partie de la RAM est allouée au GPU pour le traitement graphique. Sur un serveur headless, ça ne sert strictement à rien.
Vérifions d’abord la RAM disponible avant optimisation :
free -m
total used free shared buff/cache available
Mem: 417 37 325 0 55 369
Swap: 0 0 0
Seulement 417 Mo disponibles sur les 512 Mo théoriques. Voyons comment récupérer ces précieux mégaoctets.
Idéalement, on va vouloir mettre l’option gpu_mem=16 dans /boot/config.txt pour n’allouer que 16 Mo au GPU (on ne peut pas mettre moins, et il faut des multiples de 16).
Mais attention, il y a un piège !

Lorsque vous réglez gpu_mem à 16 Mo, le bootloader du Raspberry Pi tente de charger des fichiers de firmware allégés :
start_cd.elffixup_cd.dat
Sauf que ces fichiers ne sont pas présents sur votre partition de boot. Si on met juste gpu_mem=16 dans /boot/config.txt et qu’on reboot, le Pi refusera de démarrer (LED ACT clignotant généralement 4 fois).
Solutions pour minimiser la RAM GPU
Vous avez deux options :
Option 1 : Mettre gpu_mem=32 dans /boot/config.txt
C’est la solution de facilité (qui a dit fainéant ?), il n’y a rien à faire. Vous récupérez quand même 32 Mo de RAM.
Option 2 : Télécharger les fichiers de firmware allégés (celle que je préfère)
On n’est pas à quelques Mo près sur la carte microSD, ce qui n’est pas le cas de la RAM, où chaque Mo compte.
Si vous voulez vraiment descendre à 16 Mo, récupérez les fichiers manquants :
cd /boot
wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/start_cd.elf
wget https://raw.githubusercontent.com/raspberrypi/firmware/master/boot/fixup_cd.dat
Puis modifiez /boot/config.txt :
[...]
gpu_mem=16
start_file=start_cd.elf
fixup_file=fixup_cd.dat
Après reboot, vérifiez le gain :
free -m
total used free shared buff/cache available
Mem: 465 37 393 0 35 416
Swap: 0 0 0
On passe de 417 Mo à 465 Mo disponibles ! Soit presque 50 Mo de récupérés, ce qui représente environ 10% de RAM supplémentaire. Sur un système aussi contraint, c’est significatif.
Configuration du swap avec zswap
Sur un système avec seulement 512 Mo de RAM, il est plus que judicieux de configurer du swap. Or, Alpine Linux n’en configure pas par défaut. Je vais ici en configurer un avec zswap, qui compresse les pages de mémoire avant de les écrire sur le disque (ce qui limite la taille des accès à la carte microSD au passage).
Création du swapfile
# Créer un swapfile de 2 Go
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
Configuration persistante
Pour rendre le swapfile et zswap persistants au reboot, créez /etc/fstab :
echo "/swapfile none swap sw 0 0" >> /etc/fstab
Créez un script de démarrage pour Alpine :
cat > /etc/local.d/swap.start << 'EOF'
#!/bin/sh
swapon /swapfile
EOF
chmod +x /etc/local.d/swap.start
rc-update add local default
Enfin, éditez /boot/cmdline.txt et ajoutez à la fin (sur une seule ligne) :
zswap.enabled=1 zswap.compressor=lz4 zswap.max_pool_percent=20 zswap.accept_threshold_percent=85 zswap.shrinker_enabled=Y
Quelques explications sur ces paramètres :
compressor=lz4: utilise lz4, rapide et efficace pour la compressionmax_pool_percent=20: zswap n’utilisera pas plus de 20% de la RAM (~93 Mo) comme cache de compression avant d’écrire sur le swapfile disqueaccept_threshold_percent=85: n’accepte de compresser que si le taux de compression attendu est d’au moins 85%shrinker_enabled=Y: permet de libérer automatiquement la mémoire compressée si nécessaire
Le principe : zswap agit comme un cache rapide en RAM (compressé) devant le swapfile de 2 Go sur disque. Les pages sont d’abord compressées dans zswap, puis évacuées vers le disque si nécessaire.
Conclusion
Pas vraiment de conclusion à cet article, en réalité.
Je me suis pris pas mal de “murs”, ne sachant pas utiliser Alpine (au delà des usages que j’en avais fait avec Docker), et j’ai découvert quelques subtilités liées au firmware du Raspberry Pi Zero avec lequel je fais joujou depuis quelques semaines maintenant.
D’où cet article ;-)
Bon hack !
