Mittwoch, 7. Januar 2015

Raspberry Pi ohne Bildschirm und Tastatur booten

Mit Hilfe eines seriellen Kabels kann man den Raspberry Pi ganz ohne Bildschirm und Tastatur booten. Und wenn man keine großen Stromverbraucher an den USB-Ports des Raspis hängen hat, reicht auch die normale USB-Stromversorgung über den GPIO-Port. Ein Test-Aufbau auf dem heimischen Schreibtisch vereinfacht sich dadurch erheblich.

Man benötigt für das Login über die serielle Schnittstelle ein speziell für den Raspberry Pi angebotenes serielles USB-Kabel. Ich habe meins für 8,80€ bei Reichelt bestellt. Es nennt sich dort "USB zu TTL für Raspberry Pi, 1,0 m" und die Artikelbezeichnung ist "RPI USB TTL". Man kann kein "gewöhnliches" RS232-USB-Kabel benutzen und die entsprechenden Adern verbinden, weil die Pegel der RS232-Schnittstelle für den GPIO-Port des Raspberry Pi den Tod bedeuten.

Wenn man den Raspi über das Kabel mit dem Computer verbindet, steckt man die rote Ader für die Stromversorgung praktischer weise erst mal nicht. Andernfalls würde er direkt booten und man könnte den Boot-Vorgang im Terminal nicht sehen, da Windows erst mal den Treiber für die serielle Schnittstelle installieren muss.

Wenn Windows den Treiber richtig installiert hat, taucht im Gerätemanager der entsprechende COM-Port mit der Nummer auf, die man für Putty benötigt.

In meinem Fall ist es COM15. Die serielle Schnittstelle des Raspi wird meist mit 115200 Baud betrieben und nicht wie früher üblich mit 9600 Baud. Wenn man in Putty den "Serial" "Connection type" auswählt, kann man COM-Port und Baud-Rate setzen.

Jetzt kann man dem Raspi mit dem roten Kabel seine Versorgungsspannung geben. Die vier Adern des seriellen Kabels müssen folgendermaßen angeschlossen werden

Rot: auf den äußeren beiden Beinen sind die 5 Volt Versorgungsspannung
Schwarz: das dritte Bein ist Ground
Weiß: das vierte Bein ist TX (GPIO 14)
Grün: und das fünfte Bein ist RX (GPIO 15)

Wenn man die Adern richtig gesteckt hat, fängt der Raspi direkt an zu booten.

In Putty kann man parallel verfolgen, wie die Boot-Meldungen durch rauschen. Dank der hohen Baud-Rate geht das angenehm schnell.

Und schließlich kann man sich über die serielle Schnittstelle auch anmelden, ohne dafür eine Tastatur oder einen Monitor bemühen zu müssen.

Hintergrund

Warum funktioniert das so wie oben beschrieben? Grundsätzlich funktioniert eine serielle Konsole an jedem System, das eine serielle Schnittstelle hat. Allerdings muss man jeder Komponente, die eine Ausgabe erzeugt oder Eingaben erwartet, separat mitteilen, dass sie die serielle Schnittstelle nutzen soll. Bei klassischen PC-Systemen sind das die folgenden gemäß der Reihenfolge, wie sie beim Boot aktiv sind:
  1. BIOS: zum Beispiel Phoenix, AMI, OpenBIOS etc.
  2. Boot-Loader: zum Beispiel Grub, Syslinux etc.
  3. Kernel: zum Beispiel Linux.
  4. Konsole: zum Beispiel agetty aus der "util-linux"-Programm-Sammlung.
Viele kommerzielle BIOSe sind nicht in der Lage, für die Ein- und Ausgabe eine serielle Schnittstelle zu verwenden. Man findet die Funktion meist nur bei Server-BIOSen oder bei BIOSen für zum Beispiel Network-Appliances wie dem ALIX-Board. Deswegen ist es heutzutage bei der Verwendung von PC-Hardware meist unüblich geworden, die Konsole auf die serielle Schnittstelle zu legen, was ich aber eher als Mangel betrachte.

Beim Raspi mit Raspbian ist die Situation erfreulicher Weise anders und auch etwas einfacher, weil er weder ein interaktives BIOS noch einen interaktiven Boot-Loader hat. Somit muss man nur noch dem Kernel und der Konsole sagen, dass sie die serielle Schnittstelle verwenden sollen.

Der Kernel wird beim Raspi-Boot-Loader über die Datei "cmdline.txt" auf der SD-Karte parametrisiert. Nachdem das System gebootet ist, ist die SD-Karte unter dem Verzeichnis /boot gemountet:

pi@raspberrypi:~$ cat /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
Der relevante Paramter ist console=ttyAMA0,115200. Die Syntax für den Parameter ist in der Linux-Kernel-Dokumentation zu finden. Das erste Argument ist das serielle Gerät und das zweite die Baud-Rate.

Die Linux-Konsole wird durch den ersten aller Prozesse also Init gestartet. Init wiederum wird durch die Datei /etc/inittab konfiguriert. In der Inittab stehen Programm-Aufrufe pro Runlevel. Der normale Runlevel ist bei Raspbian 2:

pi@raspberrypi:~$ runlevel
N 2
Dem entsprechend muss in der Inittab für Runlevel 2 ein Aufruf von getty konfiguriert sein:
pi@raspberrypi:~$ awk -F: '/^[^#]/ && $2~2' /etc/inittab
id:2:initdefault:
l2:2:wait:/etc/init.d/rc 2
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
1:2345:respawn:/sbin/getty --noclear 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
4:23:respawn:/sbin/getty 38400 tty4
5:23:respawn:/sbin/getty 38400 tty5
6:23:respawn:/sbin/getty 38400 tty6
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
Und dort ist der Aufruf auch in der letzten Zeile zu finden. Wichtig ist, dass überall die gleiche Baud-Rate verwendet wird, da man zum Zeitpunkt der Übergabe der serielle Schnittstelle vom Kernel an Getty in Putty schlecht die Baud-Rate ändern kann.

Wenn man den GPIO-Port 14 für was anderes wie zum Beispiel eine Strom-Trennung verwenden möchte, könnte man den Raspi auch über zwei klassische USB-Seriell-Adapter mit dem PC verbinden: einer käme in den PC und der andere in einen USB-Port des Raspis und verbunden würden die beiden über ein Null-Modem-Kabel. Damit das funktioniert muss im Kernel der passende Treiber für den USB-Seriell-Adapter sein und man müsste anstatt ttyAMA0 das entsprechende Gerät für den USB-Seriell-Adapter verwenden. Typischerweise wäre das ttyUSB0. Allerdings würde dies eine Anpassung am Standard-Raspbian-Image erfordern, was bedeutet, dass man unter Windows die zweite Partition der SD-Karte mounten muss, um dort die Inittab zu ändern. Unter Windows gehört der Schreib-Zugriff auf EXT4-Partitionen nicht zu den Standard-Funktionen. Von Paragon wird ein Tool angeboten, mit dem das möglich sein soll. Wie gut das funktioniert bleibt zu testen.

1 Kommentar:

Thomas hat gesagt…

Danke für den Tipp - sehr hilfreich. Damit erspare ich es mir künftig, nur für die initiale Einrichtung des (danach ausschließlich benutzten) WLAN-Zugangs Bildschirm und Tastatur aufbauen zu müssen.