Serie: Embedded Linux - Das Komplizierte

Mi, 15. Juni 2022, Götz

Den meisten Nutzern und Nutzerinnen wird einmal von der immerwährenden Voraussage gehört haben, dass dieses Jahr das Jahr des Linux Desktops wird. Dieser – inzwischen ironische, leicht fatalistische Spruch – ist wahr geworden. Wie, werdet ihr euch fragen? Im Kleinen, wo den sonst! Bekannt dürfte das Smartphone sein, dieses arbeitet mit Android und das wiederum hat einen Linux Kernel. Einen sehr stark veränderten Kernel, aber ein Linux Kernel. Auch auf eurem Fernseher läuft ein Linux, auf der Set-Top-Box, dem Router, dem Smart-Home, der intelligenten Soundanlage, … die Liste lässt sich beliebig fortsetzten. Im industriellen Bereich, z. B. der Robotik, hat sich Linux ebenso durchgesetzt.

Aber wie kann ein Betriebssystem so wandelbar sein? Es kann auf einer Set-Top-Box arbeiten, mit einem 500MHz Armv7 Prozessor. Aber auch kann es bei einem Roboter Kamera-, Radar-, LiDAR und Audiodaten verarbeiten.
Dazu muss man die Begrifflichkeiten trennen: Kernel und Userland. Das, was wir als Linux bezeichnen, ist nur die Basis, der Kern des Betriebssystems. Der Kernel steuert den Prozessor an, sein Speicherinterface, seine Beschleuniger für mathematische Operationen und Interfaceschnittstellen, so z. B. CAN, SPI und I2C. Das Userland abstrahiert diese Schnittstellen. Zwischen Userland und Hardware liegt der Kernel. Aber Achtung! Viele erliegen hier der falschen Annahme, dass die ganze „Intelligenz“ der Komponentenansteuerung im Kernel liegt. Bei komplexen Systemen, so der Bildverarbeitung, leistet der Kernel nur die Initialisierung und „Übersetzung“ der Kommunikationsdaten zwischen Hardware und Userland.

Ein gutes Beispiel ist hierfür das Libcamera Projekt. Der Kernel bietet Treibermodule, die die Kommunikation zwischen Software und Grafikkern bereitstellen, die Bibliothek Libcamera hingegen erzeugt die Daten und Befehle für die Verarbeitung. Das Userland (Libcamera) ist nur zu bestimmten Kernelversionen kompatibel, und zwar denen, die das genutzte Interface bereitstellen!

Das wirft eine Frage auf: Kann man Userland und Kernel trennen? Die Antwort ist komplex und endet in einem klaren: Es kommt darauf an. Für die Kapselung spricht, dass jedes Hardwareinterface sich durch ein Softwareinterface abbilden lässt. Ein in Software gekapseltes Hardwareinterface nennt man Treiber. Im Falle Linux beschreibt ein solches Stück Software ein Kernelmodul. Das Softwareinterface kann durch passende Software aus dem Userland angesprochen werden und damit der Hardware Befehle erteilen. Durch einen Paketmanager lässt sich die Software aus dem Userland leicht austauschen.

Der Linux Anwender kennt das, jeder Zugriff über ein open() Systemaufruf spricht durch die verschiedenen Ebenen des Userlands und Kernels einen Datenträger an und lädt eine Datei. Es ist dabei egal, ob diese Datei auf einer CD, Festplatte oder USB-Stick liegt. Dabei ist open() auch eine Form von abstraktem Interface. Indem jede Schnittstelle als Datei angeboten wird, können auch Schnittstellen, wie der I2C, als Datei gelesen und geöffnet werden.

Andererseits gibt es auch komplexere Systeme, am anschaulichsten sind hier Kamerasysteme. Sie kommunizieren über viele Schnittstellen, bekannt dürften dabei USB, CSI (Camera-Serial-Interface) und Ethernet sein. Jede Schnittstelle hat unzählige Formate (= Protokolle) wie Daten übertragen werden können. Bei Ethernet können die Bilder als UDP, TCP oder eine Serie an Ethernet-Frames übertragen werden. Bei CSI können die Bilder schon verarbeitet (RGB-Matrix) oder unverarbeitet (Bayers-Format) eintreffen. Wo ist hier der Unterschied zu einem „normalen“ Systemaufruf? Schliesslich liegt auf meiner Platte auch kein Treiber zum Lesen eines PDFs, warum sollte der Treiber sich um mein Bildformat kümmern? Eingebettete Systeme nutzen im Regelfall bestimmte Rechenwerke, um mathematische Operationen zu beschleunigen. Dies hat zwei Hauptgründe:

  • Kosten: Jede aufwendige Berechnung erfordert einen leistungsstarken Prozessor. Diese sind meist kostspielig, sodass die Entwicklung/Verwendung eines speziellen Rechenwerks billiger ist. Das Rechenwerk kann nur die geforderte Berechnung durchführen, diese aber billig und schnell.

  • Energie: Aufwendige Berechnungen benötigen viel Energie. Durch spezielle Schaltkreise kann der Energiebedarf drastisch gesenkt werden. Matrixoperationen können Element für Element berechnet werden oder durch ein spezielles Rechenwerk als eine, atomare Operation. Dabei benötigt das spezialisierte Rechenwerk viel weniger Energie, da hier insgesamt weniger Schaltungsvorgänge innerhalb des Rechenwerks benötigt werden.

Im Fall der Kamera ist das ein Bildprozessor, der bestimmte Algorithmen ausführt, um aus dem Bild im Bayers-Format eine Punkt-Matrix zu generieren. Aber auch die Generierung eines Videostreams ist möglich. Aus Sicht des Anwenders gibt der Kernel somit ein Bild im Rohformat (Bayers), als Pixelmatrix oder als Frame eines Videosignals aus. Dazu muss das Userland mit den entsprechenden Treibern kommunizieren, Einstellungen vornehmen und Datenendpunkte erzeugen. Der hier beschriebene Anwendungsfall bedeutet für jeden Kamera- und Prozessorhersteller eine einzigartige Lösung. Die Schnittstellen von Bildprozessor und Kamera sind nicht einheitlich. Auch bietet nicht jedes System die gleichen Funktionen an, manche Funktionen sind zusammengefasst, andere separiert. So funktioniert die Software aus dem Userland nur mit bestimmter Hardware und bestimmten Treibern.

Das Problem gibt es bei jeder Form von Betriebssystem. Einheitliche Interfaces bilden sich erst im Laufe der Zeit heraus, wenn Standards geschaffen werden.

Es lässt sich aber auch nicht scharf zwischen dem ersten Anwendungsfall und dem zweiten trennen, es gibt einen fliessenden Übergang. Eingebettete Linuxsysteme zeichnen sich darüber aus, dass man sie eher dem zweiten Fall zuordnen kann. Mehrere spezialisierte Hardwarekomponenten arbeiten zusammen, um eine Aufgabe zu erfüllen. Ein Debian, Ubuntu oder Fedora kann das nicht alles abdecken. Der Aufwand jede Kombination abzubilden, wäre enorm und ist nicht zu leisten.

Im Bereich des Embedded Linux gibt es zwei Lösungen: Buildroot und Yocto. Damit werden für die verwendete Hardware und Anforderung angepasste Kombinationen aus Kernel und Userland erzeugt.

Bildquelle: https://www.raspberrypi.com/news/an-open-source-camera-stack-for-raspberry-pi-using-libcamera/

Tags

Embedded, Kernel, Libcamera, Treiber, Userland, Wettbewerb