Aus Linux-Magazin 03/2022

Kernel- und Treiberprogrammierung mit dem Linux-Kernel – Folge 120

© Jenzig, Photocase.com

Der Raspberry Pi 4 lässt sich komplett ohne SD-Karte per Netzwerk booten – nicht nur für eine Host-Target-Entwicklung ein sehr nützliches Feature .

Baut man die Software für ein anderes System entspannt auf einem leistungsfähigen PC, spricht man von einer Host-Target-Entwicklung. Eine solche vereinfacht sich noch einmal deutlich, wenn die Zielplattform das Booten via Netzwerk unterstützt: Das erspart sowohl das lästige Ablegen der frisch generierten Software auf ein Flash-Speichermedium der Zielplattform als auch den Ärger, der sich ergibt, wenn der Bootvorgang durch einen Fehler missglückt. Dann muss man das versaubeutelte Speichermedium aufräumen und frisch mit bootfähiger Software bespielen. Das erfordert typischerweise mehr als nur ein oder zwei leichtfüßige Kommandos auf der Konsole. Beim Netzwerkboot dagegen lässt sich das funktionsuntüchtige Kompilat ratzfatz gegen ein funktionstüchtiges austauschen, und nach dem nächsten Neustart lässt sich die Zielplattform wieder ansprechen.

Auch der Raspberry Pi bietet das Booten per Netzwerk an, man muss ihn dafür nur geeignet präparieren. Das neueste Modell des Mini-Rechners benötigt dazu nicht einmal eine SD-Karte: Die Raspberry Pi Foundation hat den Raspberry Pi 4 mit einem EEPROM (Electrical Erasable Programmable Read Only Memory) ausgestattet, das die benötigte Konfiguration aufnimmt. Der Inhalt des EEPROMs bleibt auch nach Verlust der Stromversorgung erhalten.

Im Netzwerk selbst, in dem der RasPi per Ethernet-Kabel hängt, stellt ein sogenannter TFTP-Server Abbilddateien von Kernel und Userland (Root-Filesystem) zur Verfügung. Das Userland, also die Sammlung der Anwendungsprogramme, Bibliotheken und sonstigen benötigten Komponenten, kann man auch per NFS (Network File System) in das System einbinden. Dann steht für alle Bedarfsfälle auch ausreichend Speicher zur Verfügung. Im Bereich eingebetteter Systeme ist es aber üblich und sinnvoll, das Userland im Hauptspeicher abzulegen und sich damit beim Booten eine Prüfung des Dateisystems zu ersparen und mögliche Flash-Speicher nicht kaputtzuschreiben. Abgesehen davon kann man so nach dem Start die Netzwerkverbindung kappen, und das System lebt und arbeitet dennoch weiter. Mit einem Verlust der Stromversorgung geht dann freilich auch ein Verlust eventuell veränderter Daten einher. Als naheliegende Gegenmaßnahme speichert man bei Veränderungen daher Daten auf einem dazu erreichbaren Speichermedium (Flash, USB-Stick) ab.

Für das Booten via Netzwerk gilt es, auf der einen Seite den Client geeignet zu konfigurieren, also den Raspberry Pi 4. Auf der anderen Seite benötigt man auf dem Host-System einen TFTP-Server, den es zudem mit den erforderlichen Bootdateien zu betanken gilt.

Let’s serve

Unter Ubuntu bietet sich für den TFTP-Server das einfach zu installierende und zu konfigurierende Paket tftpd-hpa an. Listing 1 zeigt die dazu notwendigen Kommandos. Der Befehl aus der ersten Zeile sorgt für das Einrichten des Servers sowie des später bei der Fehlersuche nützlichen TFTP-Clients.

Listing 1

TFTP-Server einrichten

$ sudo apt -y install tftpd-hpa tftp-hpa
$ cd /tmp/
$ wget https://github.com/raspberrypi/firmware/archive/master.zip
$ unzip master.zip
$ sudo mv firmware-master/boot/* /srv/tftp/
$ sudo chmod -R 755 /srv/tftp/

Zum Bestücken des TFTP-Servers mit den Bootdateien für den Raspberry Pi holen Sie aus dem zugehörigen Github-Repository die Datei »master.zip« (Zeile 3), die Sie zum Beispiel im Verzeichnis »/tmp/« auspacken und dann nach »/srvr/tftp/« verschieben (Zeile 5). Ein abschließendes »chmod« (Zeile 6) sorgt dafür, dass der TFTP-Server definitiv Zugriff auf die abgelegten Daten erhält. Die müssen Sie allerdings noch leicht modifizieren und ergänzen, damit nicht nur der Kernel geladen wird, sondern auch das Root-Filesystem.

Die Konfiguration des TFTP-Servers findet sich im Verzeichnis »/etc«, Sie müssen sie aber üblicherweise nicht anfassen. Zu Debug-Zwecken kann es sinnvoll sein, dem TFTP-Server in der Datei »/etc/default/tftpd-hpa« beim Start die Optionen »–secure« und »–verbose« mitzugeben. So können Sie nach einem Neustart des TFTP-Servers (Listing 2, erste Zeile) dessen Aktivitäten beobachten (zweite Zeile).

Listing 2

Server überwachen

$ sudo systemctl restart tftpd-hpa
$ tail -f /var/log/syslog | grep tftp

Verändere dich

Die Datei »/srvr/tftp/config.txt« enthält Konfigurationsparameter zur Steuerung des Bootvorgangs, die der Bootloader auswertet. Dazu gehören unter anderem Device-Tree-Overlays [1], über die der Kernel Informationen zur eingesetzten Hardware erhält.

Außerdem lassen sich dort die Namen der zu ladenden Abbilddateien spezifizieren. In Listing 3 sind das die beiden letzten Zeilen, die als Kernel die Datei »kernel7l.img« (32-Bit-Kernel) und als Userland die Datei »rootfs.cpio« festlegen. Die beiden (optionalen) Zeilen darüber aktivieren die serielle Schnittstelle, was den im Bereich eingebetteter Systeme immer noch üblichen Zugriff per Terminalemulation ermöglicht.

Ergänzen Sie also die vier Zeilen in der Datei »config.txt«. Die Datei »rootfs.cpio« befindet sich übrigens noch nicht in unserem Verzeichnis »/srvr/tftp/«. Zum Testen kopieren Sie eine von uns per Buildroot gebaute Version aus dem Download-Bereich zu diesem Artikel ins Verzeichnis. Von dort beziehen Sie auch die Abbilddatei »kernel7l.img« und befördern sie an dieselbe Stelle – dazu später noch mehr.

Listing 3

Ergänzungen in config.txt

[all]
enable_uart=1
dtoverlay=disable-bt
kernel=kernel7l.img
initramfs rootfs.cpio followkernel

Früchtekuchen

Um den Raspberry Pi geeignet zu konfigurieren, müssen Sie das Netzwerk-Setup kennen. Um es kurz zu machen: Sie benötigen lediglich die IP-Adresse des TFTP-Servers. Im Detail gilt es, zwei Varianten zu unterscheiden. Im ersten Fall befinden sich sowohl das Host-System mit dem TFTP-Server im lokalen Netz als auch das Zielsystem, also der via Ethernet angebundene Raspberry Pi. Im zweiten Fall hängt der Mini-Rechner ohne den Umweg über ein Gateway direkt per Ethernet am Host-System. Der Unterschied: Im ersten Fall integrieren Sie den RasPi sorgsam ins lokale Netz, im zweiten Fall bestimmen Sie die Netzwerkparameter selbst.

So könnten Sie sich, um beim zweiten Fall zu bleiben, beispielsweise für die private Netzadresse 192.168.42.0/24 entscheiden und dem Host die IP-Adresse 192.168.42.1 zuweisen. Der RasPi bekommt die IP-Adresse 192.168.42.42. Auf dem Ubuntu-Host wählen Sie dazu die Netzwerkeinstellungen aus. Unter dem Feld kabelgebunden erstellen Sie durch Anklicken des kleinen, unscheinbaren Pluszeichens ein neues Profil, in das Sie im Reiter Identität einen Namen eingeben (im Beispiel »tftp-server«). Im Reiter IPv4 wählen Sie die Methode manuell aus und geben die Adresse 192.168.42.1 mit der Netzmaske 255.255.255.0 ein (Abbildung 1). Sobald das Profil aktiviert ist, verifizieren Sie in einer Konsole durch Eingabe von »ip -br a« die Adresszuteilung.

Abbildung 1: Die Konfiguration der Netzwerkparameter auf dem Host-Rechner.

Abbildung 1: Die Konfiguration der Netzwerkparameter auf dem Host-Rechner.

Dasselbe Kommando nutzen Sie auch, um die IP-Adresse herauszufinden, wenn Sie sich per Ethernet mit dem lokalen Netz verbunden haben (Fall eins). Am besten konfigurieren Sie den Router so, dass Ihr Rechner diese IP-Adresse grundsätzlich erhält, sonst bleibt die Freude über ein funktionstüchtiges Booten via Netzwerkes nur von kurzer Dauer. Im Router legen Sie auch die IP-Adresse für den Raspberry Pi fest, wozu Sie aber klassischerweise die MAC-Adresse des Mini-Rechners benötigen.

Da Sie den RasPi ohnehin auf konventionelle Weise per SD-Karte zur Programmierung des EEPROM booten müssen, nutzen Sie die Gelegenheit, die MAC-Adresse und die standardmäßig vom Router (zum Beispiel einer Fritzbox) zugewiesene Adresse zu evaluieren und im Router zu fixieren. Die Adresse des Kleinstrechners müssen Sie in diesem Szenario übrigens nicht zwangsweise konfigurieren: Sie lässt sich auch beim Booten vom DHCP-Server (Router) zuweisen. Die Vergabe einer festen Adresse erleichtert aber später eine potenziell notwendige Fehlersuche.

Ob nun Fall eins oder zwei vorliegt: Letztlich benötigen Sie zur Konfiguration insbesondere die IP-Adresse des Host-Systems.

RasPi konfigurieren

Booten Sie den Raspberry Pi 4 mit einem Standard-Pi-OS. Falls noch nicht eingerichtet, finden Sie beispielsweise in der RasPi-Dokumentation [2] eine Anleitung zur Installation. Loggen Sie sich nach dem Booten ein.

Eventuell müssen Sie noch das Programm Rpi-eeprom per »apt install rpi-eeprom« installieren. Mit ihm lassen sich die Konfigurationsparameter durch den Aufruf »sudo -E rpi-eeprom-config –edit« programmieren. Geben Sie die Parameter wie in Listing 4 gezeigt ein. Dabei passen Sie die IP-Adressen an, wobei Sie die Zeile mit der »CLIENT_IP« in den meisten Setups wie beschrieben auch weglassen können. Nach dem Abspeichern der Konfiguration und dem Verlassen des Programms steht zwingend ein Neustart an. Das klappt am schnellsten über den Befehl »reboot« auf der Konsole. Erst damit landet die Konfiguration tatsächlich im EEPROM. In Listing 4 finden sich auch einige Timing-Parameter. Möglicherweise können Sie in Ihrem Setup darauf verzichten, wir haben damit aber in unterschiedlichen Umgebungen ein zuverlässigeres Bootverhalten erzielt.

Listing 4

EEPROM-Konfiguration

[all]
BOOT_UART=1
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=1
DHCP_TIMEOUT=30000
DHCP_REQ_TIMEOUT=1000
TFTP_FILE_TIMEOUT=20000
TFTP_IP=192.168.178.223
BOOT_ORDER=0xf12
SD_BOOT_MAX_RETRIES=2
NET_BOOT_MAX_RETRIES=2
CLIENT_IP=192.168.178.203
SUBNET=255.255.255.0

Über die Parameter »BOOT_ORDER«, »SD_BOOT_MAX_RETRIES« und »NET_BOOT_MAX_RETRIES« optimieren Sie gegebenenfalls das Bootverhalten. Mit »BOOT_ORDER« konfigurieren Sie die Bootpriorisierung, wenn beim Netzwerk-Boot noch eine SD-Karte im Slot steckt. Der abzuspeichernde Wert umfasst bis zu acht Hex-Ziffern, die der RasPi von rechts nach links interpretiert (Abbildung 2). Die in Listing 4 verwendete Kombination »0xf12« besagt, dass der RasPi zunächst versucht, per Netzwerk zu booten (»0x2«). Schlägt das fehl, greift Priorität 2, also das Booten per SD-Karte (»0x1«). Sollte auch dieser Versuch nicht von Erfolg gekrönt sein, fängt der RasPi wieder bei Priorität eins an (»0xf«). Der Code »0xf12« priorisiert also beim Booten das Netzwerk, selbst wenn eine SD-Karte im Slot steckt. Eine Beschreibung der wichtigsten Parameter finden Sie in der Tabelle “EEPROM-Konfigurationsparameter (Auswahl)”, weitere Informationen liefert die RasPi-Dokumentation [3].

Abbildung 2: Konfiguration von Bootprioritäten.

Abbildung 2: Konfiguration von Bootprioritäten.

Parameter

Vorgabe

Bedeutung

»BOOT_UART«

0

Aktiviert Debug-Ausgaben über die serielle Schnittstelle.

»WAKE_ON_GPIO«

1

Ermöglicht das Aufwecken aus dem Low-Power-Mode.

»POWER_OFF_ON_HALT«

0

Versetzt den Raspberry Pi bei einem Halt in den Low-Power-Mode.

»BOOT_ORDER«

Legt die Bootpriorität fest.

»MAX_RESTARTS«

-1

Anzahl der Restarts, bevor ein Full-Reset erfolgt.

»SD_BOOT_MAX_RETRIES«

0

Anzahl der Bootversuche über die SD-Karte.

»NET_BOOT_MAX_RETRIES«

0

Anzahl der Bootversuche via Ethernet.

»DHCP_TIMEOUT«

Timeout in Millisekunden.

»DHCP_REQ_TIMEOUT«

Timeout in Millisekunden.

»TFTP_FILE_TIMEOUT«

Timeout für den Datei-Download (zwischen 5000 und 30 000 Millisekunden).

»TFTP_IP«

IP-Adresse des TFTP-Servers.

»TFTP_PREFIX«

Aktiviert einen gerätespezifischen Datei-Download.

»TFTP_PREFIX_STR«

Verzeichnisname für den gerätespezifischen Datei-Download.

»CLIENT_IP«

“”

IP-Adresse des Raspberry Pi.

»SUBNET«

“”

Subnetzmaske.

»GATEWAY«

“”

IP-Adresse eines Gateways.

»MAC_ADDRESS«

“”

Überschreibt die hinterlegte MAC-Adresse.

»DISABLE_HDMI«

0

Deaktiviert Bootnachrichten per HDMI.

Stunde der Wahrheit

Um das Booten via Netzwerk zu testen, fahren Sie den Raspberry Pi herunter, kappen die Stromversorgung und entnehmen die SD-Karte. Anschließend setzen Sie den Mini-Rechner wieder unter Strom. Auf dem Host-System – also auf dem Rechner, auf dem der TFTP-Server läuft – starten Sie eine Konsole und sehen sich mithilfe des Kommandos »tail -f /var/log/syslog | grep tftp« die Log-Ausgaben an, die in etwa so ausfallen sollten wie in Abbildung 3. Geben Sie dem Bootvorgang etwas Zeit, insbesondere wenn Kernel und Root-Dateisystem (Userland) etwas umfangreicher ausfallen.

Abbildung 3: Das Syslog verschafft einen Überblick über den Bootvorgang.

Abbildung 3: Das Syslog verschafft einen Überblick über den Bootvorgang.

Hat der RasPi gebootet, können Sie sich mit ihm verbinden (Abbildung 4). Der Login-Name lautet root, das Passwort ebenfalls. Dazu verwenden Sie die serielle Schnittstelle und eine Terminalemulation wie Minicom. Typischerweise starten Sie Minicom auf dem Ubuntu-Rechner mit der Option »-D /dev/ttyUSB0«. Vergessen Sie nicht, Hardware Flow Control auf Nein zu setzen (Abbildung 5).

Abbildung 4: Nach einem Neustart klappt nun das Login auf dem Testsystem.

Abbildung 4: Nach einem Neustart klappt nun das Login auf dem Testsystem.

Abbildung 5: Die Minicom-Konfiguration für den Zugriff über die serielle Schnittstelle.

Abbildung 5: Die Minicom-Konfiguration für den Zugriff über die serielle Schnittstelle.

Besser loggen Sie sich statt über die serielle Schnittstelle per SSH auf dem frisch gebooteten RasPi ein. Dazu benötigen Sie dessen IP-Adresse, die Ihnen entweder der Router oder der Netzwerkscanner Nmap verraten. Es gibt einen weiteren Weg, die IP-Adresse zu evaluieren. Dazu laden Sie aus dem Download-Bereich zu diesem Artikel noch die Abbilddatei »kernel7l.img« herunter und legen sie im Verzeichnis »/srvr/tftp/« ab. Mit dem passenden Kernel spannt der Raspberry Pi 4 ein WLAN unter dem Namen »Linux-Magazin« auf. Das Passwort des drahtlosen Netzes lautet »kern-technik«.

Falls Sie sich mit MQTT [4] auskennen, finden Sie nun unter dem Topic »system/ipaddress/eth0« die IP-Adresse im lokalen Netz, unter »system/ipaddress/wlan0« lassen Sie sich die IP-Adresse im WLAN anzeigen. Das Topic »system/date« liefert die aktuelle Systemzeit, sofern der Raspberry Pi Netzzugriff hat. Den Screenshot in Abbildung 6 haben wir mit der Android-App IoTMQTTPanel erstellt. Die zur Konfiguration des MQTT-Servers benötigte IP-Adresse lautet im Übrigen 192.168.99.1.

Abbildung 6: Mit dem Testsystem per WLAN verbunden, lassen sich via MQTT Infos abrufen.

Abbildung 6: Mit dem Testsystem per WLAN verbunden, lassen sich via MQTT Infos abrufen.

Troubleshooting

Gibt der Raspberry Pi nach dem Neustart kein Lebenszeichen von sich, ist Troubleshooting angesagt. Testen Sie als erstes den TFTP-Server mithilfe des TFTP-Clients, den Sie eingangs auf dem Host miteingerichtet haben. Listing 5 zeigt die Kommandos, mit denen Sie die Datei »config.txt« herunterladen. Lassen Sie in einem separaten Terminalfenster das Kommando »tail -f /var/log/syslog | grep tftp« mitlaufen. Funktioniert der TFTP-Server und sehen Sie im Log Ausgaben, setzen Sie den verkabelten Raspberry Pi unter Strom.

Listing 5

config.txt holen

$ tftp 192.168.42.1
tftp> get config.txt
tftp> quit

Falls keine Log-Nachrichten erscheinen, liegt wohl ein Netzwerkproblem vor. Überprüfen Sie dann die auf dem RasPi konfigurierten IP-Adressen. Über einen per HDMI am Mini-Rechner angeschlossenen Monitor erhalten Sie beim Bootvorgang eingeschränkt Informationen. Insbesondere können Sie ersehen, ob eine Netzverbindung existiert, und wenn ja, welche IP-Adresse der Raspberry Pi verwendet. Weitergehende Infos bekommen Sie mit einem USB-to-Serial-Adapter. Haben Sie den richtig angeschlossen und die Terminalemulation (Minicom) geeignet konfiguriert, können Sie wesentliche Teile des Bootvorgangs auf dem RasPi verfolgen.

Fazit

Die Konfiguration des TFTP-Servers und das Einrichten des Raspberry Pi zum Netzwerkboot nimmt etwas Zeit in Anspruch. Ist das aber einmal erfolgreich erledigt, bootet der RasPi recht zuverlässig. Gerade bei der Host-Target-Entwicklung will man das Feature schon bald nicht mehr missen. (jlu)

Die Autoren

Eva-Katharina Kunst ist seit den Anfängen von Linux Fan von Open Source. Jürgen Quade, Professor an der Hochschule Niederrhein, führt auch für Unternehmen Schulungen zu den Themen Treiberprogrammierung und Embedded Linux durch.

Infos

  1. Device Trees und Pincontrol: Eva-Katharina Kunst, Jürgen Quade, “Kern-Technik – Folge 68”, LM 06/2013, S. 76, https://www.lm-online.de/28999
  2. “Getting Started”: https://www.raspberrypi.com/documentation/computers/getting-started.html
  3. “Raspberry Pi 4 Boot EEPROM”: https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-4-boot-eeprom
  4. MQTT: Rainer Poisel, “Volks-Schalter”, LM 07/2017, S. 30, https://www.lm-online.de/39317
DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben