Linux-Boot: Von UEFI bis systemd
March 14, 2026
Linux, UEFI, BIOS, GRUB, systemd, initramfs
Der Computer läuft unter einem Betriebssystem, dessen Kernel zunächst als Programm in den Speicher geladen wird. Auf dem Weg durchläuft jedoch das System mehrere Schichten: Beim Laden des Linux-Kernels arbeiten Firmware, Bootloader-Software (z.B. GRUB) und ein init-Prozess wie init oder systemd. Aber wo endet Bootloader und fängt systemd an? Was passiert tatsächlich in den ersten Sekunden nach dem Start des Systems?
Beim Spaziergang durch diese Schichten antworten wir auch auf solche Fragen wie: Wer erhält zuerst die Steuerung? Wann wird PID 1 gestartet? Und wo kann das System ausfallen?
Nach dem Power-Tastendruck und der Stromversorgung des Prozessors muss er etwas rechnen. Der Prozessor kann nur Programme ausführen. Dafür greift er über den Datenbus auf den Arbeitsspeicher (RAM) zu. Nach dem Ausschalten des Computers verliert der RAM jedoch seinen Inhalt. Dafür gibt es in der Konstruktion des Computers einen Festwertspeicher (eng. read-only memory, ROM).
ROM (BIOS-Chip). Quelle.
Dieser Speicher behält seinen Dateninhalt auch ohne externe Energieversorgung. Das Programm, das der Prozessor nach dem Start ausführen muss, befindet sich im Festwertspeicher. Dieses Programm erhält als erstes die Steuerung.
Schicht 1 - Firmware (BIOS/UEFI)
Das Programm ist eine Firmware, die die Hardware-Ausstattung initialisiert und nach einem Betriebssystem zum Laden sucht. Auf IBM-PC-kompatiblen Computern nennt man dieses Programm ursprünglich BIOS (eng. Basic Input -output System), aber heute heißt es UEFI (eng. Unified Extensible Firmware Interface). In Wirklichkeit sind BIOS und UEFI keine einzelnen Programme, die im ROM gespeichert sind, sondern eine Sammlung von Vereinbarungen darüber, wie eine Firmware funktionieren soll, um einen Computer zu starten.
Nach der Initialisierung der Hardware bestimmt die Firmware ein Startlaufwerk. Dies kann eine CD/DVD, ein USB-Gerät, eine Festplatte (HDD/SSD) oder eine Netzwerkschnittstellenkarte sein. Und weiter hängt es von der Art der Firmware ab: Das BIOS liest einen Maschinencode aus dem Master Boot Record (MBR) in den Arbeitsspeicher. Der MBR befindet sich im ersten Sektor eines Datenspeichers und enthält ein Startprogramm. Wegen seiner geringen Größe (512 Bytes) kann das Startprogramm keine komplexen Handlungen ausführen. Deshalb lädt es ein anderes komplexes Programm in den RAM, nämlich einen Bootloader.
Ladeprozess des Betriebssystems. Quelle.
UEFI unterscheidet sich vom BIOS dadurch, dass es nicht den MBR liest, sondern Bootparameter aus der Bootreihenfolge erhält. Die Bootreihenfolge kann mit dem Befehl sudo efibootmgr -v überprüft werden. Die Ausgabe wird etwa:
BootOrder: 0001,0000, ...
Boot0000*
Windows Boot Manager HD(... ,bd35d166-c62a-4fbd-8191-4288d3568b24,
...)/File(\EFI\Microsoft\Boot\bootmgfw.efi)
Boot0001*
debian HD(... ,ee09f46e-1a0a-4b5f-bb7a-23771ff7ca5f,
...)/File(\EFI\debian\grubx64.efi)
Dies ist die Ausgabe von meinem Computer. Hier erkennt man, dass Windows und Debian auf meiner Maschine zusammen installiert sind. Ein Rechner mit zwei oder mehr installierten Betriebssystemen wird als Dual-Boot-System bezeichnet.
Gemäß der Bootreihenfolge liest UEFI Einträge aus den Bootparametern mit einem Namen der Bootloaderdatei \EFI\debian\grubx64.efi und GUID (eng. Globally Unique Identifier) der Partition ee09f46e-1a0a-4b5f-bb7a-23771ff7ca5f anhand dessen wählt UEFI einen Speicherbereich, der als ESP (EFI System Partition) bezeichnet wird. ESP ist ein Dateisystem für Bootloader (Windows Boot Manager, GRUB) und andere EFI-Applikationen. Auf dieser Partition findet UEFI die .efi-Datei vor. Die Datei wird in den Speicher geladen und UEFI leitet die Steuerung an den gelesenen Code weiter.
Hinweis: Experimentumgebung
Für die folgenden Experimente verwende ich eine virtuelle Maschine, um den Bootprozess isoliert untersuchen zu können.
Um zu überprüfen, ob die CPU-Hardware die Virtualisierung unterstützt, kann man folgenden Befehl ausführen:
cat /proc/cpuinfo | grep --color -E "vmx|svm|lm"
vmx– Intel VT-x Virtualisierungserweiterungsvm– AMD-V Virtualisierungserweiterung
Diese Flags zeigen, dass die CPU Hardwarevirtualisierung unterstützt. lm bedeutet, dass der Prozessor 64-Bit-Architektur hat.
Für die Virtualisierung wird virt-manager benötigt. Linux-Distributionen wie Debian, Ubuntu und Fedora enthalten normalerweise alle erforderlichen Werkzeuge. Wenn Sie eine andere Distro installiert haben, vergewissern Sie sich, dass die entsprechenden Pakete installiert sind:
qemu-kvmlibvirt-daemonlibvirt-clientsvirt-manager
Außerdem ist ein ISO-Abbild der Linux-Distro notwendig. Ich werde debian-13.3.0-amd64-netinst.iso benutzen, da es relativ leicht (~ 750 MB), aktuell zum Zeitpunkt der Erstellung dieses Artikels, komplett und einfach bei der Installation ist. Kopieren Sie das ISO-Abbild in das /var/lib/libvirt/images/ Verzeichnis, das virt-manager standardmäßig verwendet:
cp debian-13.3.0-amd64-netinst.iso /var/lib/libvirt/images/
Anschließend folgen Sie den Einstellungen im Virtual Machine Manager. Alternativ kann eine virtuelle Maschine auch mithilfe des virt-install Utilitys erstellt werden.
Schicht 2 - Bootloader (GRUB)
Die Steuerung übernimmt ein Bootloader, der bei Linux-Distros standardmäßig GRUB (GNU GRUB - GRand Unified Bootloader) ist. Seine Hauptaufgabe ist, den Kernel des Betriebssystems in den RAM zu laden und die Systeminitialisierung vorzubereiten.
GRUB-Menü und Kernel-Parameter
Beim Systemstart zeigt GRUB ein Menü mit Kernelversionen und verfügbaren Betriebssystemen. Durch Drücken der Taste e können Kernel-Parameter bearbeitet werden. Diese Parameter steuern das Verhalten des Linux-Kernels während des Startvorgangs.
Beispiel für Kernel-Parameter.
Eine typische Konfiguration enthält:
linux /boot/vmlinuz-6.12.73+deb13-amd64 root=/dev/sda1 ro quiet
initrd /boot/initrd.img-6.12.73+deb13-amd64
Hier:
- linux — Pfad zum Kernel-Image
- initrd — initramfs-Image
- ro quiet — Kernel-Parameter
Das Stammverzeichnis (Root) kann als eine Datei des Gerätes (/dev/sda1) angegeben werden, auf den meisten heutigen PCs ist das ein UUID (bb12a6f1-2abe-4679-8189-acbbcc9b81ad).
Diese Parameter werden vom Bootloader direkt an den Kernel übergeben. Dies kann aus dem laufenden System überprüft werden:
cat /proc/cmdline
Wenn man beispielsweise den Parameter quiet entfernt, werden die Kernel- und Systeminitialisierungsmeldungen während des Bootvorgangs angezeigt.
Beispiel für das Log des Kernels und systemd.
initrd (eng. Initial RAM Disk) oderinitramfs sind ein vorläufiges komprimiertes Dateisystem-Abbild (/boot/initrd.img-6.12.73+deb13-amd64) , das vom Bootloader in den RAM geladen und vom Kernel als temporäres Root-Dateisystem verwendet wird. Der Kernel verwendet dieses temporäre Dateisystem, um:
- Treiber zu laden
- das echte Root-Dateisystem zu finden
- notwendige Initialisierung durchzuführen
Moderne Linux-Distributionen verwenden in der Regel initramfs statt initrd. Ohne initramfs könnte der Kernel oft das Root-Dateisystem nicht finden.
Die Konfiguration von GRUB befindet sich in /boot/grub/grub.cfg oder in /boot/grub2/grub.cfg. Diese Datei muss man nicht editieren. grub.cfg wird automatisch aus der /etc/default/grub-Datei und dem /etc/grub.d/-Verzeichnis generiert. Diese Dateien können geändert werden, um GRUB einzustellen.
Wenn in der linux-Zeile beispielsweise temporär einen Parameter wie systemd.unit=rescue.target hinzugefügt wird, startet das System in den Rettungsmodus - eine gute Gelegenheit, die Wirkung von Kernel-Parametern zu beobachten. In diesem Fall startet systemd mit minimalen Diensten.

Oder mit init=/bin/bash wird das System in den Notfallmodus gestartet. Bei diesem Ansatz wird bash als Prozess mit PID 1 gestartet.
Dies kann mit dem Befehl ps -p 1 überprüft werden. In diesem Modus wird systemd nicht gestartet, und das System befindet sich in einem minimalen Zustand. Das ist hilfreich, wenn Sie das Passwort für root vergessen haben und es geändert werden muss.
Nach dem Laden von Kernel und initrd/initramfs übergibt GRUB die Steuerung vollständig an das Kernel-Image. Ab diesem Zeitpunkt beginnt die Kernel-Initialisierung.
Schicht 3 - Linux-Kernel
Das Kernel-Image initialisiert die grundlegende Hardware, entpackt sich selbst und bindet das vom Bootloader geladene initramfs ein.
Danach beginnt architekturspezifischer Code ausgeführt zu werden, der von der CPU-Architektur abhängt. Für die Architektur x86 beispielsweise ist es arch/x86/kernel/head_64.S für x86_64 oder arch/x86/kernel/head_32.S für x86_32 . Der Code ist hier noch in Assembler geschrieben. An diesem Punkt wird die Funktion aufgerufen, die in init/main.c sich befindet:
start_kernel()
start_kernel ist der Beginn der architekturunabhängigen Initialisierung und ihre zentrale Funktion. Die Funktion übernimmt unter anderem folgende Aufgaben:
- konfiguriert und initialisiert eine Interrupt-Steuerung (
local_irq_disable(),init_IRQ(),local_irq_enable()) - initialisiert CPU (
boot_cpu_init(),setup_arch()) - initialisiert RAM (
mm_core_init()) - initialisiert den Scheduler (
sched_init()) - erstellt Systemzeit und Timer (
timekeeping_init(),time_init()) - initialisiert Subsysteme (
fork_init(),security_init(),vfs_caches_init(),signals_init(),cgroup_init()) - ruft
rest_init()auf
In rest_init() beginnt der Übergang zum Prozessmodell. Hier startet PID 1 - user_mode_thread() mit kernel_init() und kernel_thread(). PID 0 (swapper) geht in Leerlaufschleife (idle loop):
schedule_preempt_disabled();
cpu_startup_entry(CPUHP_ONLINE);
kernel_init() ist eine Brücke zum Benutzerraum. Die Funktion initialisiert auch Treiber, registriert Hardware und mount Root-Dateisystem (prepare_namespace(), pivot_root()) und schließlich startet sie den ersten Benutzerprozess (run_init_process()), eigentlich den Prozess init (PID 1).
Dies ist keine vollständige Liste der Funktionen, Einstellungen und Initialisierungen, die der Linux-Kernel ausführt. In Wirklichkeit ist es mehr, aber hier sind grundlegende Schritte des Kernel-Boot.
Während des Ladeprozesses zeigt der Linux-Kernel viele Meldungen, die untersucht werden können mit:
dmesg | less
oder:
journalctl -k
Ein Beispiel für Meldungen des Kernels.
initramfs
Für das Einhängen des Dateisystems benötigt der Kernel ein Modul für die Arbeit mit dem Festspeicher und dem Dateisystem, aber um das Modul einzulesen, braucht der Kernel ein Dateisystem, von dem dieses Modul gelesen werden kann. initrd/initramfs löst dieses Henne-Ei-Problem.
Mithilfe dieser Befehle kann man die initramfs-Struktur ansehen (der Dateiname kann variieren):
mkdir /tmp/initramfs
cd /tmp/initramfs
unmkinitramfs /boot/initrd.img-6.12.73+deb13-amd64
Ein Beispiel für eine initramfs Struktur.
initramfs enthält early und main Verzeichnis. early enthält die Aktualisierung des Microcodes für CPU, zum Beispiel für Intel:
kernel/x86/microcode/GenuineIntel.bin
Der Microcode ist CPU-Firmware, die bestimmt, wie die CPU Instruktionen ausführt.
main beinhaltet grundlegend initramfs. Das Abbild hat Verzeichnisse und ausführbaren Dateien für den Laden des Kernels wie z.B. Shell. Für Server und Desktop-Systeme ist initrd ein temporäres Dateisystem für einen kurzen Moment des Übergang zum Root-Dateisystem. In eingebetteten Systemen ohne Aufzeichnungsgeräte für Dateispeicherung kann initrd ein permanentes Dateisystem sein.
Panic
Wenn während des Kernelstarts ein Fehler auftritt wie ein fehlendes Modul in initramfs oder ein falscher Pfad zum Abbild, zeigt der Kernel eine Fehlmeldung an, die als Kernel Panic bezeichnet wird.
Eine Panic, bei der der Kernel das Dateisystem nicht einbinden kann.
Die Kernelroutine, die solche Situationen behandelt, heißt panic(). Sein Quellcode befindet sich im Modul kernel/panic.c. Die Funktion wurde implementiert, um eine Fehlermeldung auszugeben, für die nachträgliche Fehlerbehebung auf die Festplatte zu speichern und entweder auf einen manuellen Neustart zu warten oder einen automatischen Neustart zu initiieren.
Schicht 4 - systemd (PID 1)
Nachdem der Linux-Kernel das Root-Dateisystem aus der initramfs-Umgebung eingebunden hat und mithilfe von switch_root oder pivot_root() zum eigentlichen Root-Dateisystem gewechselt hat, startet er schließlich den Init-Prozess.
Der Kernel versucht dabei nacheinander folgende Programme zu starten:
/sbin/init
/etc/init
/bin/init
/bin/sh
In modernen Linux-Distributionen ist dieser Prozess in der Regel systemd, welcher als grundlegender Prozess fungiert. Dieser Prozess erhält PID 1 und wird zum Elternprozess für alle weiteren Prozesse im System.
Dies kann überprüft werden mit:
ps -p 1
Eine typische Ausgabe ist beispielsweise:
PID TTY TIME CMD
1 ? 00:00:02 systemd
Auch symbolische Links zeigen häufig auf systemd:
ls -l /usr/sbin/init
Beispiel:
... init -> ../lib/systemd/systemd*
Der Prozess übernimmt anschließend die weitere Systeminitialisierung:
- startet Systemdienste
- bindet Dateisysteme ein
- konfiguriert das Netzwerk
- startet Benutzersitzungen
Alle weiteren Prozesse des Systems werden entweder von systemd gestartet oder sind Nachkommen von Prozessen, die systemd gestartet hat.
Damit wird systemd zum zentralen Prozess der Systemverwaltung.
Zusammenfassung
Die ersten Sekunden des Linux-Bootvorgangs durchlaufen mehrere Ebenen:
- Firmware (UEFI/BIOS) – initialisiert die Hardware und wählt das Boot-Gerät aus
- Bootloader (GRUB) – lädt den Kernel und das initramfs
- Linux-Kernel – initialisiert die Hardware und interne Subsysteme
- initramfs und init-Prozess – finden das Root-Dateisystem und starten PID 1
Nach dem Start von systemd wechselt das System in den normalen Betriebsmodus und beginnt mit dem Start von Diensten und Benutzerprozessen.