Aus Raspberry Pi Geek 04/2020

Pi Zero als universeller USB-Stick (Seite 2)

Der Linux-Kernel ist inzwischen bei der zweiten Iteration des Gadget-Supports angekommen. Ursprünglich gab es für den Zweck spezialisierte Treiber, etwa g_ether für die Emulation eines Ethernet-Adapters. Die Konfiguration war sehr einfach. Die Datei /boot/config.txt erhielt dazu die folgende, zusätzliche Zeile:

dtoverlay=dwc2

Die in der Regel einzige Zeile in der Datei /boot/cmdline.txt musste man außerdem zu folgender Zeile ergänzen:

modules-load=dwc2,g_ether

Das funktioniert immer noch, allerdings entfallen die Treiber in Zukunft irgendwann aus dem Kernel. Ein weiterer Nachteil liegt darin, dass die gleichzeitige Konfiguration mehrerer Gerätetypen (etwa Ethernet und Massenspeicher) nie richtig funktioniert hat.

Die nächsten Abschnitte beschreiben deshalb das aktuell gültige Verfahren für die Konfiguration. Die Dtoverlay-Zeile in der /boot/config.txt ist geblieben, ansonsten stellt der RasPi jedoch alle notwendigen Informationen dynamisch bereit.

Der Ablauf sieht dann wie folgt aus: Sie stöpseln den Pi Zero an einen anderen Rechner an. Auf diese Weise erhält er Strom und bootet. Während des Boot-Prozesses konfiguriert ein Skript den Rechner als Gadget, sodass er dann alle passenden Informationen an sein Gegenüber überträgt.

USB-Konfigurationen

Beim Booten erzeugt ein Linux-System für alle angeschlossenen USB-Geräte einschließlich der internen Hubs automatisch einen Eintrag im virtuellen Dateisystem /sys/bus/usb/ (Abbildung 6). Wichtig sind hier unter anderem die Inhalte aller Dateien, die bInterface im Namen tragen. Sie beschreiben, um was für ein USB-Gerät es sich handelt.

Abbildung 6: Virtuelle Dateien im Sys-Dateisystem geben unter anderem Auskunft über die USB-Geräte eines Rechners.

Abbildung 6: Virtuelle Dateien im Sys-Dateisystem geben unter anderem Auskunft über die USB-Geräte eines Rechners.

Um diese Informationen aufzubauen, enthält der Linux-Kernel (wie sein Windows-Gegenstück) eine interne Tabelle mit entsprechenden Informationen. Beim Einstecken eines Geräts tauschen Kernel und Gerät Informationen aus, und der Linux-Kernel erstellt die SysFS-Dateien automatisch.

Da der Pi Zero jetzt aber die Rolle der Peripherie übernimmt, läuft der Prozess umgekehrt: Der Linux-Kernel stellt die Informationen seinerseits der Gegenseite bereit. Dazu gibt es das Config-Filesystem, kurz ConfigFS. Dabei handelt es sich um ein virtuelles Dateisystem analog zum Sys-Filesystem, das nur während der Laufzeit existiert und dessen Inhalt in Teilen dem Sys-Gegenstück sehr ähnelt. Das Erstellen ist nicht schwierig, wohl aber mühsam: Es gilt, diverse Dateien, Verzeichnisse und Links anzulegen – eine typische Aufgabe für ein Skript.

Listing 1 zeigt Ausschnitte eines solchen Skripts und erzeugt beim Booten dynamisch die benötigten Einträge im ConfigFS. Je nachdem, welche Rolle Sie dem Stick zuweisen, sind das andere Dateien. Da die USB-Spezifikation es erlaubt, dass ein Stick mehrere logische Geräte bereitstellt, brauchen Sie sich aber nicht unbedingt zu entscheiden.

Listing 1

015 USBCONF_DIR="/sys/kernel/config/usb_gadget/g1"
016 NODE="USB0"
017 C=1
018
021 init_start() {
022
023   echo 0x1d6b > idVendor  # Linux Foundation
024   echo 0x0104 > idProduct # Multifunction Composite Gadget
025   echo 0x0100 > bcdDevice # v1.0.0
026   echo 0x0200 > bcdUSB    # USB2
027   echo 0xEF   > bDeviceClass
028   echo 0x02   > bDeviceSubClass
029   echo 0x01   > bDeviceProtocol
030
031   # OS descriptors
032   mkdir -p os_desc
033   echo 1       > os_desc/use
034   echo 0xcd    > os_desc/b_vendor_code
035   echo MSFT100 > os_desc/qw_sign
036
037   mkdir -p strings/"$LANG_ID"
038   echo "$SERIAL_NO" > strings/"$LANG_ID"/serialnumber
039   echo "$MANUFACTURER" > strings/"$LANG_ID"/manufacturer
040   echo "$PRODUCT" > strings/"$LANG_ID"/product
041
042   mkdir -p "configs/c.$C/strings/$LANG_ID"
043   echo "$DESCRIPTION" > "configs/c.$C/strings/$LANG_ID/configuration"
044   ln -s "configs/c.$C" os_desc
045   echo 250 > "configs/c.$C/MaxPower"
046 }
047
056 create_storage() {
065
066   # configure gadget
067   mkdir -p "functions/mass_storage.$NODE"
068   echo 1 > "functions/mass_storage.$NODE/stall"
069   echo 0 > "functions/mass_storage.$NODE/lun.0/cdrom"
070   echo 0 > "functions/mass_storage.$NODE/lun.0/ro"
071   echo 0 > "functions/mass_storage.$NODE/lun.0/nofua"
072   echo "$USB_FILE" > "functions/mass_storage.$NODE/lun.0/file"
073
074   ln -s "functions/mass_storage.$NODE" "configs/c.$C/"
075 }
076
079 create_serial() {
080   mkdir -p "functions/acm.$NODE"
081   ln -s "functions/acm.$NODE" "configs/c.$C/"
082 }
083
108 # ---- main program   --------------------------------------------------------
109
110 # source configuration file
111 . /etc/raspi2go.conf
112
113 # load modules
114 modprobe libcomposite
115 sleep 1
116
117 # initialize gadget
118 mkdir -p "$USBCONF_DIR"
119 cd "$USBCONF_DIR"
120 init_start
121
122 # create configuration
123 [ "$USB_MASS_STORAGE" = 1 ] && create_storage
124 [ "$USB_SERIAL" = 1 ]       && create_serial
125 [ "$USB_ETHERNET" = 1 ]     && create_network
126 [ "$USB_HID" = 1 ]          && create_hid
127
128 init_end
129
130 # start additional services
131 [ "$USB_SERIAL" = 1 ] && systemctl start [email protected]

Das Skript erzeugt in den Zeilen 23 bis 46 in der Funktion init_start() grundlegende Dateien. Dazu gehören Dinge wie Informationen über Hersteller, Typ sowie die maximale Leistungsaufnahme des Gadgets. Die Funktionen create_storage() und create_serial() erstellen dagegen spezifische Dateien, Verzeichnisse und Links für einen Massenspeicher beziehungsweise die serielle Schnittstelle.

Sie installieren das Skript samt passendem Systemd-Service über das Github-Projekt [6]. Der Systemd-Service läuft ab dem Booten und wendet die Konfiguration einmalig an. Als Basis diente im Beispiel ein aktuelles Raspbian Lite; die Pixel-Version funktioniert zwar ebenfalls, allerdings tut sich der Pi Zero schwer mit der grafischen Oberfläche.

Mit den Befehlen aus Listing 2 installieren Sie die Software und passen die /boot/config.txt an. Anschließend nehmen Sie in der Datei /etc/raspi2go.conf diverse Einstellungen vor – etwa, welche Rolle der Pi übernimmt oder wie das “Produkt” heißt. Ein Neustart aktiviert die Einstellungen.

Listing 2

$ git clone https://github.com/bablokb/raspi2go.git
$ cd raspi2go
$ sudo tools/install

Für die Installation selbst sowie für spätere Updates hängen Sie den Pi Zero wie üblich per OTG-Adapter ans LAN oder greifen per WLAN darauf zu. Solange Sie nicht den angelöteten USB-Anschluss nutzen, bleibt alles beim Alten. Ist der Service installiert, gibt der Pi Zero im Host-Modus zwar ein paar Fehlermeldungen im System-Log aus, doch die dürfen Sie ignorieren.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 7 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben