Linux-Wissen: Die Rolle des Init-Systems im Bootprozess

Ferdinand Thommes
61 Kommentare
Linux-Wissen: Die Rolle des Init-Systems im Bootprozess
Bild: SPERA.de | CC BY 2.0

Der „Kampf der Init-Systeme“ bleibt eines der beherrschenden Themen in der Linux-Szene. Erst vor zwei Tagen ist auch Ubuntu auf Systemd gewechselt. Um zu verstehen, welche Bedeutungen den Systemen zukommt, muss der Bootprozess unter Linux betrachtet werden.

Der Einstieg in den Bootprozess ist für alle Betriebssysteme ähnlich und beginnt im BIOS, oder seit einigen Jahren meist im UEFI. Beides sind grundlegende Schnittstellen zwischen den einzelnen Komponenten eines Rechners, deren Firmware und dem Betriebssystem. Ein wichtiges Unterscheidungsmerkmal zwischen BIOS und UEFI ist, neben der Möglichkeit zur Bedienung mit der Maus, Secure Boot, das das Booten auf signierte Bootloader beschränkt. Für die nachfolgenden Ausführungen sind beide Aspekte allerdings nicht von Relevanz. BIOS und UEFI werden im Folgenden synonym genutzt. Die Ausführungen beschränken sich darüber hinaus auf Rechner nach dem IBM-Standard x86.

Das BIOS leitet den Start ein

Wird der Startknopf eines vollständig installierten Rechners gedrückt, führt als erstes der Prozessor den Power-On-Self-Test (POST) durch und signalisiert danach über verschiedene Signal- oder Zahlensequenzen den Zustand des Systems. Im Falle eines Fehlers, der ein weiteres Starten verhindert, gilt es das Signal mit den Angaben des jeweiligen Mainboardherstellers abzugleichen, um den Fehler zu finden.

Als nächstes werden die bootfähigen Speichermedien erkannt, nach Bootsektoren durchsucht und der Code im Bootsektor desjenigen Mediums ausgeführt, das im BIOS als erstes Startmedium definiert ist. Alternativ kann der Anwender durch Eingriff in den frühen Bootprozess ein zu bevorzugendes Medium definieren. Bis hierher läuft der Bootprozess bei allen Betriebssystemen gleich ab. Die Unterschiede beginnen beim Bootloader, denn erst hier wird Code vom Betriebssystem ausgeführt.

Der Bootloader übernimmt

Bei Linux kommt heutzutage meist GRUB zum Einsatz, seltener noch das veraltete LILO. Bei Live-Medien wird oft ISOLinux, ein Bootloader von Syslinux, verwendet. Der Bootloader befindet sich im Bootsektor des Startmediums. Dort befindet sich im ersten Sektor der Master-Boot-Record, auch als MBR bekannt. Die Ausführung des Bootcodes geschieht in zwei Phasen (Stages). In der ersten lädt sich der Bootcode selbst in den Arbeitsspeicher. Er sucht daraufhin die Startadresse der zweiten Phase und lädt auch diese in den Hauptspeicher.

Daraufhin wird dem Anwender ein einfaches Menü angezeigt, das die verfügbaren Betriebssysteme und deren Kernel, die in der Datei /boot/grub/grub.cfg definiert sind, zur Auswahl anbietet . Der Bootloader lädt, falls vorhanden, die temporäre Initial-RAM-Disk initrd beziehungsweise das heute gebräuchlichere virtuelle Dateisystem initramfs in den Hauptspeicher. Es enthält das Abbild eines Dateisystems mit den zum Start des Systems benötigten Dateien und Modulen. Das initramfs-Image kann im Kernel enthalten sein oder kann vom Bootloader aus einer Datei in den RAM geladen werden. Ist das geschehen, übergibt der Bootloader den weiteren Bootprozess an den Kernel.

Das Init-System startet Prozesse und Runlevel

Der Kernel übergibt den Bootprozess daraufhin an Init, das über die Datei /sbin/init gesteuert wird. Hier kam bei Linux über viele Jahre SysVinit, ein Fork des Init-Systems des Unix-Betriebssystems System V, zum Einsatz. In den letzten zwei Jahren hat sich hier zunehmend Systemd durchgesetzt, das heute von den meisten bedeutenden Betriebssystemen und vielen Derivaten eingesetzt wird – seit Version 15.04 Vivid Vervet auch bei Ubuntu.

Das Init-System startet den ersten Prozess des Systems mit der Prozess-ID 1. Der Prozess läuft, solange die Sitzung andauert und startet nun andere Prozesse. Wie er das tut, ist in der Datei /etc/inittab festgelegt. Der Init-Prozess startet und verwaltet auch die verschiedenen Runlevel. Diese definieren verschiedene Systemzustände, die unterschiedlichen Zwecken dienen und jeweils adäquate Dienste zur Verfügung stellen. Sie sind mit den unter Windows im Bootmenü angebotenen Optionen wie etwa Abgesicherter Modus oder Windows normal starten vergleichbar.

Runlevel unter Linux
Runlevel unter Linux (Bild: Wikipedia)

Linux kennt für gewöhnlich sieben Runlevel von 0 bis 6, wobei 0 dem Shutdown und 6 einem Reboot entspricht. Level 1 stellt einen Einzelnutzerbetrieb ohne Netzwerk für Wartungsarbeiten zur Verfügung. Die Runlevel 2 bis 5 sind mehrbenutzerfähig. Bei Debian sind sie identisch, andere Distributionen definieren Runlevel 3 als Terminal ohne und Runlevel 5 mit grafischer Benutzeroberfläche. Runlevel 4 wird selten genutzt.

Init früher und heute

Bis vor zwei Jahren wurde bei Linux standardmäßig SysVinit als Init-System benutzt. Ausnahme war hier Ubuntu, das die Eigenentwicklung Upstart einsetzte. SysVinit hat zwei gravierende Nachteile: Der Bootprozess ist aufgrund der sequenziellen Ausführung der einzelnen Dienste langsam: Die vorgegebene Reihenfolge wird strikt eingehalten und ein Prozess startet grundsätzlich erst dann, wenn der vorherige Prozess fertig initialisiert wurde. Der zweite Nachteil sind die schwer verständlichen Shell-Init-Skripte, in denen der Bootprozess konfiguriert ist.

Hier kann Systemd die Vorteile des parallelen Starts von Diensten ausspielen. Im Resultat kann ein aktuelles System, je nach installierter Software, heute in drei bis zehn Sekunden hochfahren. Systemd ist allerdings nur unter dem Linux-Kernel lauffähig, BSD und andere unixoide Systeme bleiben außen vor, was Systemd gemeinhin als Nachteil angekreidet wird. Ein Teil der Kritik an Systemd ist auch auf die Vielfalt an Diensten zurück zu führen, die nach Ansicht einiger Kritiker die Unix-Philosophie verletzt, indem sie zu viele Aufgaben übernimmt. Die Gegenseite argumentiert, Systemd bestehe aus rund 70 Binärdateien und sei somit vom Aufbau her nicht monolithisch.

Um dem seriellen Abarbeiten zu entgehen, werden die D-Bus-Verbindungen und Sockets zur Interprozesskommunikation bereits vor dem Start des zugehörigen Dienstes gestartet. Bis dahin auflaufende Nachrichten werden bis zur Bereitschaft des Dienstes vom Kernel gepuffert. Die Startbedingungen und Abhängigkeiten der einzelnen Dienste sind in deklarativen, leicht lesbaren Konfigurationsdateien anstatt wie bisher in Shell-Skripten verankert.

Der mit Systemd ausgelieferte Logging-Daemon Journald startet wesentlich früher im Bootprozess, wodurch Fehler im frühen Bootprozess im Systemlog auftauchen und so leichter auffindbar sind. Das Szenario, in dem der Anwender einen hängengebliebenen Bootscreen abfotografiert, um in Foren oder im IRC Hilfe zu bekommen, gehört damit größtenteils der Vergangenheit an.

Nachdem Init alle Prozesse angestoßen hat, startet es die Userspace-Werkzeuge und hängt alle Partitionen ein, die in /etc/fstab definiert sind. Daraufhin wird das System in dem in der Inittab hinterlegten Runlevel gestartet. Meist ist dies Runlevel 5, das einen Anmeldeschirm präsentiert, der nach Eingabe von Benutzername und Passwort die grafische Umgebung startet.

Ein Folgeartikel in der Serie Linux-Wissen wird den Linux-Grafikstack näher beleuchten und auf die einzelnen freien und proprietären Grafiktreiber verschiedener Hersteller eingehen. AMD hatte zuletzt weitreichende Änderungen am Treiber freigegeben.