PTXdist: Schon gewusst? Heute: Mal eben neu booten

Jürgen Borleis | | PTXdist, DidYouKnow

Wer während der Entwicklung an einem embedded System selbiges immer wieder mal komplett neu starten muss, wird es zu schätzen wissen, wenn so wenig wie möglich getan werden muss, um bei veränderten Daten das System im konsistenten Zustand zu halten.

Kaffee entspannt

Die Einleitung war schon ganz schön kompliziert. Vorallem ist es kontraproduktiv, so lange Sätze zu schreiben. Aber das ist wie eine Tür: Da müssen wir durch.

Konkret geht es darum, dass ich bei meinem embedded System während der Entwicklung niemals Diskjockey spielen will: Es dauert einfach zu lange beispielsweise eine SD-Karte neu zu bespielen, nur um eine inhaltliche Änderung am Root-Dateisystem auf dem embedded System auszuprobieren.

Ich will also mein embedded System komplett über Netzwerk betreiben. Und "komplett" meint hier, dass es auch den Kernel und ggf. dessen Devicetree beinhalten soll. Gehen wir davon aus, dass der Bootlader des embedded Systems das NFS-Protokoll und darüber hinaus auch noch die BootLoaderSpec beherrscht (wer wie ich den Bootlader barebox einsetzt ist jetzt fein raus). Beide Eigenschaften plus ein NFS-Dienst bieten zusammen die Möglichkeit, das embedded System komplett und konsistent über Netzwerk zu betreiben. Die Möglichkeiten eines NFS-Dienst habe ich bereits hier besprochen.

Ich benutze auf allen meinen embedded Systemen den Bootloader barebox, so dass ich diesen auch hier im Beispiel voraussetze.

Der NFS-Dienst muss das BSP-Unterverzeichnis platform-<name>/root exportieren. Das ist das Root-Dateisystem für das embedded System und es muss aus seiner Sicht einen Pfad auf dieses BSP-Unterverzeichnis verwenden. Das BSP-Unterverzeichnis entsteht, wenn ptxdist go durchgelaufen ist.

Zunächst muss im Bootloader barebox die verwendete Netzwerk-Schnittstelle geeignet konfiguriert werden. Das kann mittels statischer Konfiguration oder auch per DHCP erfolgen.

Um den Linux-Kernel und seinen Devicetree über Netzwerk zu laden, definiere ich im barebox-Environment einen weiteren sog. automount-Eintrag. Ich verwende auf meinem embedded System die Schnittstelle eth0 und somit sieht mein automount-Eintrag wie folgt aus:

barebox:/ edit /env/init/automount
 [...]
 mkdir -p /mnt/nfs
 automount /mnt/nfs 'ifup eth0 && mount -t nfs ${eth0.serverip}:/<path> /mnt/nfs'
 [...]

Die hier mit <path> markierte Stelle ist bei mir durch den aktuellen Pfad zu meinem per NFS exportierten Root-Dateisystem ersetzt.

Jetzt macht bereits der Bootloader barebox Gebrauch vom Netzwerk, aber der Linux-Kernel benötigt noch eine entsprechende Parametrisierung, um ebenfalls für sein Root-Dateisystem Netzwerk zu verwenden. Auch das ergänzt der Bootloader barebox für mich, wenn in der Konfigurationsdatei der BootLoaderSpec der Eintrag linux-appendroot true enthalten ist. Dazu gleich mehr. Soweit zur Vorbereitung des embedded Systems.

Auf PTXdist-Seite (meinem Enwicklungsrechner) genügt es nun in der Plattform im Untermenü bootloader spec entries den Menüpunkt default bootloader spec entry zu aktivieren. Da PTXdist die oben zitierte Zeile linux-appendroot true nicht selbst einfügt, muss ich das selber tun. Dazu kopiere ich mir die Vorlage dieser BootLoaderSpec-Konfigurationsdatei in mein BSP, also die Datei default.conf aus dem Pfad projectroot/loader/entries im PTXdist-Installationsverzeichnis in mein BSP-lokales projectroot/loader/entries-Verzeichnis und ergänze darin eine Zeile mit dem gewünschen linux-appendroot true-Inhalt. Im Ergebnis sollte das dann in etwa so aussehen:

title             @TITLE@
version           @VERSION@
options           @CMDLINE@
linux-appendroot  true
linux             @KERNEL@
@DEVICETREE@

Nun lasse ich mittels ptxdist go das Root-Dateisystem-Verzeichnis auf meiner lokalen Festplatte bauen, starte den NFS-Dienst (falls ich das noch nicht getan haben sollte) und schalte mein embedded System ein. Es genügt nun das ich folgendes, einfaches Boot-Kommando anwende:

barebox:/ boot /mnt/nfs

Bei mir sieht das dann etwa so aus:

barebox 2017.09.0 #2 Mon Sep 04 11:55:04 CEST 2017

Board: jb's board
detected i.MX53 revision 2.1
running /env/bin/init...

Hit any key to stop autoboot:    3
barebox:/ boot /mnt/nfs
booting 'PTXdist - jb's board'
blspec: booting PTXdist - jb's board from none
Adding "root=/dev/nfs nfsroot=192.168.23.4:/<path>,v3,tcp ip=dhcp" to Kernel commandline

Loading ARM Linux zImage '/mnt/nfs//boot/zImage'
Loading devicetree from '/mnt/nfs//boot/imx53-board.dtb'
commandline: root=/dev/nfs nfsroot=nfsroot=192.168.23.4:/<path>,v3,tcp ip=dhcp

Mein embedded System wurde per DHCP konfiguriert und damit wird diese Methode von barebox auch an den Kernel übergeben (ip=dhcp). Auch hier taucht die <path>-Komponente wieder auf. barebox hat diese direkt aus der automount-Einheit übernommen und für den Kernel entsprechend aufbereitet.

Um das oben dargestellte Boot-Kommando nicht bei jedem Start erneut eingeben zu müssen, kann ich auch das automatisieren:

barebox:/ nv boot.default=/mnt/nfs
barebox:/ saveenv

Ich für meinen Teil bin nun bereits entspannt beim Arbeiten und nutze den hohen Druck lieber in meiner Kaffee-Maschine...