Piero V.

Debian Stretch e Raspberry Pi 3

A Ottobre dei miei amici mi hanno regalato una Raspberry Pi 3 e avevo già fatto qualche esperimento con le varie distribuzioni Linux.

In particolare avevo provato Debian testing con architettura Arm64, però a quel tempo non ne ero rimasto molto soddisfatto perché avevo dovuto usare un kernel di Ubuntu che non funzionava con dell’hardware come il Wi-Fi ed era poco integrato nel sistema.

Stato corrente

Da dieci giorni Stretch è in freeze completo e tra poco sarà la nuova stable, quindi è un ottimo momento per installarla sulla Raspberry.

Una cosa molto interessante è che è dotata di Linux 4.9, il che è veramente ottimo, perché già dalla versione 4.8 il BCM2837, ovvero il SoC della Raspberry Pi 3, è nella mainline del kernel.

Sulla pagina principale sulle Raspberry Pi sul Wiki di Debian c’è ancora un’informazione errata, ovvero che Debian necessita di un kernel di terze parti per funzionare. Infatti, nella pagina dedicata esclusivamente alla versione 3, viene confermata la compatibilità col kernel fornito e c’è una lista di bug, di cui ho potuto verificare solo il terzo:

  • assenza di segnale su HDMI
  • assenza di supporto a WiFi e Bluetooth
  • MAC address dell’interfaccia ethernet assegnato a caso ad ogni avvio
  • probabilmente non vanno neanche i GPIO, perché necessitano quantomeno di un firmware proprietario

Siccome io la uso come serverino, ho proceduto ugualmente.

Per migliorare il supporto a questa scheda, probabilmente vista anche la sua estrema diffusione, è inoltre stato aggiunto il pacchetto raspi3-firmware, dedicato alla gestione dei blob proprietari della Pi e alla copia di kernel e initrd nella partizione FAT di avvio della Raspberry stessa.

Per l’installazione esistono delle immagini già pronte per Debian, oppure potete usare Debootstrap e QEMU. La prima soluzione può essere sfruttata con tutti gli OS, la seconda invece richiede una distribuzione Linux.

Installazione con Debootstrap

I requisiti, se usate Debian, Ubuntu e derivate, sono debootstrap e qemu-user-static, altre distribuzioni dovrebbero avere pacchetti analoghi.

La vostra scheda SD deve avere due partizioni, la prima FAT per i firmware e la seconda Ext4 per il sistema. Io sono partito da una scheda con Raspbian di cui ho lasciato ex-novo la prima partizione, invece ho formattato la seconda.

Supponendo di aver montato la partizione ext su /media/sd e la partizione FAT su /media/sd/boot/firmware, l’installazione è composta dai seguenti comandi da dare da root:

debootstrap --arch=arm64 --foreign stretch /media/sd mirror # Scarica i pacchetti per un sistema Debian base, il mirror è opzionale
cp /usr/bin/qemu-aarch64-static /media/sd/usr/bin/ # Copia il binario che permette di eseguire i binari ARM64 su una macchina non ARM, non richiesto se siete già su ARM64
chroot /media/sd
debootstrap/debootstrap --second-stage # Installa il sistema base
tasksel install standard # Installa i pacchetti per un sistema standard, non minimale
apt install locales # Installa le lingue, opzionale, solo se non volete il sistema in inglese
dpkg-reconfigure locales # Imposta le lingue da installare
dpkg-reconfigure tzdata # Imposta il fuso orario, passo opzionale
apt install linux-image-arm64 raspi3-firmware # Installa il Kernel. Attenzione: in chroot fallisce, ma va dato lo stesso
apt clean # Pulisce la cache dei pacchetti
echo raspberrypi > /etc/hostname # Al posto di raspberrypi si può mettere un altro nome
cp /boot/vmlinuz-4.9.0-1-arm64 /boot/initrd.img-4.9.0-1-arm64 /usr/lib/linux-image-4.9.0-1-arm64/broadcom/bcm2837-rpi-3-b.dtb /boot/firmware/ # La prima volta il Kernel va copiato manualmente

Il sistema base è installato, ma mancano, però, alcuni importanti file di configurazione.

Il primo è il /etc/fstab del nuovo sistema; questo probabilmente potrà andarvi bene:

/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
/dev/mmcblk0p1  /boot/firmware  vfat    defaults          0       2

proc            /proc           proc    defaults          0       0

Poi creiamo il /boot/firmware/cmdline.txt:

console=ttyAMA0,115200 root=/dev/mmcblk0p2 elevator=deadline fsck.repair=yes rootwait

Infine il /boot/firmware/config.txt:

# Switch the CPU from ARMv7 into ARMv8 (aarch64) mode
arm_control=0x200

enable_uart=1

device_tree=bcm2837-rpi-3-b.dtb
kernel=vmlinuz-4.9.0-1-arm64
# For details on the initramfs directive, see
# https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=10532
initramfs initrd.img-4.9.0-1-arm64

A meno che non usiate la Raspberry tramite seriale, manca anche un altro passaggio fondamentale: la configurazione della rete.

Systemd e i random MAC

Avevo evidenziato come bug quello del cambio del MAC address dell’interfaccia ethernet ad ogni avvio: è molto grave perché con la configurazione predefinita non ci permette di configurare come si deve la rete, che in alcuni casi, come il mio, è l’unica modalità di accesso.

Questo succede perché la scheda della Raspberry, pur essendo saldata, è connessa al SoC tramite USB, non tramite PCI o altri bus. Debian usa Systemd che, dalla versione v197, per avere nomi delle schede persistenti, si affida al MAC address, ma, nel nostro caso, non solo lo sforzo di Systemd è completamente vano, ma ottiene il risultato contrario rispetto a quello desiderato!

Tuttavia è molto facile ovviare al problema: la documentazione è molto precisa e fornisce indicazioni su come impostare manualmente i nomi alle interfacce di rete, sfruttando dei file in /etc/systemd/network/*.link.

La mia soluzione è stata la seguente: creiamo il file /etc/systemd/network/10-ethernet.link (10-ethernet è arbitrario) con il seguente contenuto:

[Match]
Driver=smsc95xx

[Link]
Name=eth0

Questo file indica a Systemd di usare il nome eth0 per le schede ethernet che usano il driver smsc95xx. Esistono anche altri metodi per identificare univocamente la scheda onboard, ma questo mi sembrava il più facile. Inoltre dovrebbe sempre funzionare, a meno che qualcuno non abbia più schede con quel driver. In tal caso vi invito a usare il comando udevadm per trovare le informazioni che vi servono per il matching.

A questo punto per la configurazione della rete vera e propria vi rimando alle istruzioni ufficiali.

Altre osservazioni

Ho usato il sistema per due giorni e mi pare funzioni alla grande. Non penso che ci siano molte differenze tra Raspbian e Debian, per quanto riguarda il software che possono far funzionare.

Ho riscontrato una maggiore facilità nel compilare moduli del kernel con Debian ufficiale: gli header di Linux si installano facilmente e si può usare anche DKMS, invece con Raspbian avevo avuto diversi problemi.

Le differenze principali di compatibilità riguardano invece l’hardware: su Debian Stretch difficilmente verranno aggiunte le eventuali cose che adesso non funzionano.

Infine con Debian potreste avere dei problemi qualora voleste modificare la configurazione del cmdline.txt e del config.txt: il pacchetto raspi3-firmware, almeno allo stato attuale, sovrascrive i file con quelli predefiniti, annullando quindi ogni cambiamento ogni volta che lo script di postinstallazione del kernel viene invocato.

Comunque esite già il bug #848101 che segnala la cosa e magari più avanti proporrò io stesso delle soluzioni basate su sed.

Un commento