Der Linux Boot Prozess
Am Anfang war alles so einfach...
Gehen wir mal an den Anfang der 1990'er Jahre zurück, also zu den Tagen, wo Linux noch weitgehend unbekannt war.
Der Linux Kernel (wie eigentlich die Kernel aller anderen Betriebssysteme auch) kann nicht direkt durch das BIOS gestartet werden. Das liegt im Wesentlichen daran, das das BIOS keine Vorstellung davon hat auf welchem Speichermedium der Kernel liegt, was ein Dateisystem ist oder wie man darin die richtige Datei (den Kernel) findet. Zum Start eines Betriebssystems brauchte man deshalb etwas das als Bindeglied zwischen BIOS und dem relativ großen Betriebssystemkern vermitteln kann.
Man hatte sich für Personal Computer als Teil des Partitionsschemas von Festspeichern einen winzigen Bereich am Anfang des Speichermediums reserviert, der beim Start versucht wird, durch das BIOS zu starten. Dies war der Master Boot Record. In diesen wirklich winzigen Speicher passt nicht ein kompletter Kern eines Betriebssystems mit all seinen Treibern und Komponenten. Weshalb kleine darauf spezialisierte Programme diese Aufgabe übernommen haben.
Für Linux wurde z.B. der Linux Loader, kurz LILO geschrieben, der in den MBR installiert wurde und in der Lage ist den Linux Kernel in der Rootpartition zu finden und zu starten. Damit sah die Folge von Abläufen ungefähr so aus:
- start des BIOS
- start des BootLoaders (z.B. LILO) →
- start des Linux Kernels
- start des INIT Programs in der Root Partition
- start aller weiteren nötigen Programme zur Initialisierung - z.B. zur Konfiguration von Netzwerk Schnittstellen, start des grafischen Desktops etc. etc.
Wenn der Kernel startet, übergibt ihm der BootLoader einige Einstellungen. Die beiden wichtigsten sind
- wo der Kernel die Root Partition findet (root=) und
- welches Programm aus der Root Partition für den initialen Start der Userland Programme verwendet wird (init=).
Die Kerneloption init= kann immer noch sehr nützlich sein, um damit ein System zu reparieren, das beim Start im Userland Probleme hat. Dafür stellt man den Parameter auf eine Systemshell wie bash.
Etwa so:
init=/usr/bin/bash
Dann landet man sofort nach dem start des Kernels in der Shell und kann von dort aus versuchen das Problem zu beheben. Vorraussetzung ist natürlich, das man diesen Parameter noch beeinflussen kann. Beim weit verbreiteten Bootloader GRUB kann man vor dem Start alle Parameter einsehen und auch abändern.
Als Userland bezeichnet man die Programumgebung außerhalb des eigentlichen Betriebsystemkerns. Das ist der Teil mit dem wir gewöhnlich mit dem Betriebsystem interagieren. Der Betriebsystemkern (Kernel) initialisiert die Hardware, verwaltet den Zugang und bietet den Userland Programmen über definierte, abstrakte Schnittstellen Zugriff auf diese Resourcen an. Der direkte Zugriff auf die Hardware und insbesondere den Speicher aus dem Userland ist nicht mehr möglich. Damit ist es so gut wie ausgeschlossen das ein Userland Programm das ganze System zum Absturz bringen kann. Dies ist ein sehr wichtiger Stabilitätsfaktor von unixoiden Betriebssystemen.
Der Kernel wird modular
Zu Beginn war der Linux Kernel ein monolitisches Gebilde. Eine große Datei in der alles enthalten war was der Kernel zum Start für das gegebene System benötigte. Das stellte sich aber sehr schnell als ein Problem heraus. Zum einen konnte der Kernel nich beliebig wachsen. Es gab und gibt hier Grenzen, wie groß ein Kernprogramm maximal sein darf. Aber auch war es unmöglich ohne den Kernel neu zu übersetzen das System mit neuer oder geänderter Hardware auszustatten. Man stelle sich unter solchen Bedingungen einen Tausch des Mainboards vor.
Deshalb wurde Ende der 90'er Jahre der Linux Kernel modular. Das bedeutet, das Treiber, die nicht für den direkten Start des System notwendig sind, in Dateien ausgelagert werden, die dem Kernel zur Laufzeit hinzugefügt und auch wieder entfernt werden können. Das öffnete die Tür für den heutigen quasi „universal“ Kernel, der auf sehr vielen Varianten der gleichen Plattform direkt startbar ist. Damit gab es aber nun ein Henne-Ei-Problem. Wie konnte man nötige Treiber zum Start des Userlands dynamisch nachladen bevor das eigentliche Userland gestartet wurde?
Ein Problem und dessen Lösung: Die Erfindung der INITRD
Die Antwort auf dieses Problem: Man startet einfach ein Userland vor dem Userland. Dieses erste Userland kümmert sich dann um das Laden aller benötigten Treiber, konfiguriert diese, falls nötig und startet dann das eigentliche Userland. Über diesen Umweg konnte man das Laden des Linux Kernels komplett dynamisieren. Das Filesystem dieses ersten Userlands befindet sich in einer komprimierten Datei die vom Kernel in eine RAM Disk geladen wird. Diese Datei enthält neben eingien Scripten auch die für das System nötigen Treiberdateien, da ja das eigentliche Root Filesystem zu diesem Zeitpunkt noch nicht verfügbar ist.
Beim Start des Linux Kernels wird mit dem Kernelparameter initrd= auf diese Archivdatei verwiesen.
Aber sind denn alle möglichen Treiber bereits in diesem Archiv enthalten?
Nein, sind sie nicht. Die initrd enthält nur eine Auswahl an Treibern, als Kopien der im eigentlichen Userland liegenden Treiberdateien.
Aus diesem Grund ist es beim Update des Kernels aber auch bei Änderungen an der Hardware zwingend nötig die initrd Datei neu erstellen zu lassen, da ansonsten die initrd Datei fehlt oder eventuell nicht die benötigten Treiber enthält. Unter Arch basierten Linux Distributionen verwendet man mkinitcpio
Für Debian und Ubuntu lautet das nötige Kommando: update-initramfs
Es hat sich als Standard etabliert, das die initrd Datei unter dem Pfad /boot also an der gleichen Stelle, wo auch der Linux Kernel abgelegt ist.
Eine sehr beliebte Fehlerquelle für Bootprobleme: Die initrd Datei wurde nicht aktualisiert. In der Regel kümmert sich der Paketmanager darum, das dies passiert. Aber wenn einem zum Beispiel in den Paketmanager Logs die Fehlermeldung nicht aufgefallen ist…
Zum Glück lässt sich das Problem beheben: Einfach die initrd neu erstellen lassen.
Aber: Sollte die Datei komplett fehlen oder ein zentraler Treiber nicht enthalten sein, so wird man um eine etwas aufwändigere Reperatur nicht herum kommen.
GRUB als Bootmanager
Der Bootmanager GRUB ist eine Alternative zum sehr einfachen, oben erwähnten LILO Bootloader. GRUB ist ein wesentlich mächtigerer Bootloader. Er bietet Menus zur Auswahl von verschiedenen Kerneln und Betriebssystemen, beherrscht das Booten über das Netzwerk, von RAID Laufwerken und verschlüsselten Laufwerken. GRUB bietet einen Editor in dem man die Startparameter auch nachträglich verändern kann.
Die Funktionsvielfalt von GRUB passt natürlich nicht in den winzigkleinen Master Boot Record. Weshalb GRUB auch modular ist und aus einem Kern im Master Boot Record und nachladbaren Modulen besteht. Ein kleiner Teil sitzt im Master Boot Record, der größere Teil liegt in /boot entweder in einer eigenen Partition oder als Teil der Root Partition.
Der modulare Aufbau von GRUB hat allerdings auch zur Folge, das, wenn der GRUB Loader aus dem Master Boot Record seine weiteren Module nicht finden kann, es zu einem blockierten Systemboot kommt. Hier hilft es GRUB nochmals neu zu installieren. Dazu muss man in das nicht startbare System ohne es zu starten. Klingt komisch? Geht aber. Was man dafür machen muss findet sich hier
XXX
[to be continued]