Boot
Siehe auch
Was passiert zwischen dem Einschalten der Maschine bis zum Erscheinen des Login-Prompts? Das Verständnis des Boot-Prozesses hilft beim Troubleshooting sowie bei der Performance-Optimierung des Systems.
Ein x86-basierter Rechner prüft und initialisiert mit Hilfe seines BIOS zunächst seine Hardware im sogenannten POST (Power On Self Test). Die BIOS-Software findet sich in einem ROM-Chip auf dem (virtuellen) Motherboard. Der Rest des Boot-Prozesses liegt in der Hand von Linux, hier RHEL.
Nach dem POST startet der Boot Loader und liest aktuelle Zeit- und Hardware-Informationen aus dem batteriegepufferten CMOS. Der Boot Loader ist in der Regel auf einer Festplatte des Rechners gespeichert, entweder im Boot-Sektor (bei klassischen BIOS/MBR-Systemen) oder auf einer EFI-Partition (für aktuelle (Unified) Extensible Firmware Interface oder EFI/UEFI-Systeme). Bis dahin greift die Maschine nicht auf vorhandene Massenspeicher zu.
Für Linux existieren eine ganze Reihe an Boot-Loadern; RHEL verwendet GRUB2 (den GRand Unified Boot loader), andere sind beispielsweise ISOLINUX, um von CD zu booten. GRUB2 präsentiert eine Benutzeroberfläche, um den Bootvorgang von RHEL kontrollieren oder andere parallel installierte Betriebssysteme starten zu können. Der Boot-Loader ist für das Laden des Kernel-Images und der Initial RAM Disk (die einige wichtige Dateien und Gerätetreiber enthält, ohne die das System nicht staren kann) in den Hauptspeicher verantwortlich.
Der Boot-Loader ist in zwei unterschiedliche Teile gegliedert.
- Erster Teil
Auf BIOS-Systemen ist der Boot-Loader im MBR (Master Boot Record), dem ersten Sektor der Festplatte, abgelegt, der genau 512 Bytes gross ist. Der Boot-Loader sucht nach dem Start in der Partitionstabelle nach einer bootfähigen Partition - ist diese gefunden, sucht er den zweiten Teil des Boot-Loaders (in unserem Fall GRUB2) und lädt diesen in den Hauptspeicher.
Auf EFI/UEFI-Maschinen liest die UEFI-Firmware ihre Boot-Einträge aus ihrem Boot-Manager, um zu ermitteln, welche UEFI-Applikation von wo geladen werden soll (sprich, auf welcher Festplatte und Partition die EFI-Partition gefunden werden kann). Daraufhin lädt die Firmware die UEFI-Applikation (GRUB2). Klingt kompliziert, ist aber zuverlässiger als die alte MBR-Methode.
- Zweiter Teil
Der zweite Teil des Boot-Loaders liegt unter
/boot
. Ein Auswahlmenü hilft, den Boot-Prozess detailliert zu kontrollieren oder ein parallel installiertes Betriebssystem zu starten. Ist das Betriebssystem ausgewählt, lädt der Boot-Loader im Fall von Linux dessen Kernel in den Hauptspeicher und gibt die Kontrolle an diesen ab.Parallel lädt der Boot-Loader das Initial RAM–based Filesystem (initramfs) in den Hauptspeicher. Kernel sind meistens komprimiert abgelegt, daher dekomprimiert der Kernel sich zunächst selbst. Anschliessend prüft und initialisiert er die Hardware des Systems mit Hilfe der eingebauten Gerätetreiber aus dem virtuellen Dateisystem und konfiguriert den Hauptspeicher. Zur initialisierten Hardware gehören die Prozessoren, I/O-Subsysteme, Speichersysteme usw. Der Kernel lädt jetzt auch die ersten Anwendungen aus dem User-Space.
Das initramfs Dateisystem-Image enthält alle für das Mounting des root-Dateisystems notwendigen Treiber, Programme und Binärdateien. Eines davon ist udev
(userspace /dev), welches für die Ermittlung aktiver Massenspeicher, das Laden der entsprechenden Kernelmodule und die Zuordnung der notwendigen Treiber verantwortlich ist. Ist das root-Dateisystem gefunden, wird es auf Fehler geprüft und gemountet. mount
teilt dem Betriebssystem mit, dass ein Dateisystem zur Verfügung steht und hängt es in den globalen Verzeichnisbaum ein (der mount point). Ist hier alles erfolgreich verlaufen, wird initramfs beendet und der User Space startet - bis RHEL 6 mit init
(„upstart“), ab RHEL 7 mit systemd
.
Der User Space startet; systemd
ist der erste darin ausgeführte Prozess. systemd
startet alle System-Dienste (Daemons) massiv parallel auf Basis von einheitlichen Konfigurationsdateien, die deklarative Initialisierungs-Anweisungen enthalten. Eine Menge an Systemdiensten, ihre Abhängigkeiten und Startreihenfolge untereinander definiert ein Target - beispielsweise das Multi-User-Target (bis zum Erscheinen des Bash-Prompts) oder das Graphical-Target (bis zum Start des GNOME- oder KDE-Desktops).
Shutdown und Neustart
systemctl poweroff
systemctl reboot
Die altbekannten Befehle poweroff
, halt
und reboot
sind als „Legacy“ klassifiziert, und werden seit RHEL 7 auf Systemd umgeleitet.
Um einen Server zu einer festen Uhrzeit herunterzufahren oder neu zu starten, verwendet man:
# Halt at 12:30
shutdown -h 12:30
# Poweroff now
shutdown -P now
# Reboot in 5 minutes
shutdown -r +5
Bemerkung
Es kann vorkommen, dass
shutdown
,poweroff
undrestart
nicht funktionieren, beispielsweise wenn das Dateisystem nicht verfügbar ist. In diesem Fall muss man den Kernel direkt anweisen, den Neustart wie folgt durchzuführen:
echo 1 > /proc/sys/kernel/sysrq; echo b > /proc/sysrq-trigger
Dieser Neustart ist hart, das heisst es werden keine Prozesse heruntergefahren oder Dateisysteme ausgehängt.
Runlevel vs. Systemd-Targets
RHEL bis Version 6 kennt verschiedene Runlevel - das sind Systemzustände, die beim Boot-Vorgang durchlaufen werden und diverse Dienste in einer wohldefinierten Reihenfolge starten (z.B. wird erst im höchsten Runlevel die grafische Benutzeroberfläche gestartet). Beim Shutdown werden die Runlevel in umgekehrter Reihenfolge durchlaufen. Sie bedeuteten im Detail:
- Runlevel 0
Herunterfahren.
- Runlevel 1
Einzelnutzer-Modus, Single User Mode. Nur die wichtigsten Services werden gestartet, das System startet also z.B. ohne Netzwerk; damit sind nur lokale Ressourcen verfügbar. Wird vornehmlich für Wartungsarbeiten verwendet. Das System loggt sich automatisch mit dem root-Account ohne Passwort-Angabe ein. Bootet man in den Runlevel 1, lässt sich so auch ein verlorengegangenes root-Passwort zurücksetzen. Das ist kein Sicherheitsloch, da hier eh schon ein physischer Zugriff auf die Maschine besteht.
- Runlevel 2
Mehrbenutzer-Modus ohne Netzwerk, nur lokale Ressourcen verfügbar.
- Runlevel 3
Mehrbenutzer mit Netzwerk und allen Diensten, jedoch ohne grafische Benutzeroberfläche. Die Standard-Kommandozeile.
- Runlevel 4
Nicht definiert.
- Runlevel 5
Runlevel 3, zusätzlich mit grafischer Oberfläche (z.B. GNOME).
- Runlevel 6
Neu booten.
Um z.B. in den Runlevel 1 zu wechseln, verwendet man bis RHEL-Version 6 das Kommando
init 1
Damit werden die meisten Daemons ohne Neustart abgeschaltet.
Durch die Einführung von systemd
sind die bis RHEL 6 bekannten Runlevel verschwunden. Der Runlevel 3 heisst in RHEL 7 nun multi-user.target, Runlevel 5 wird graphical.target genannt.
Man erreicht diese Targets beim Boot mit der Kernel-Parameter-Angabe systemd.unit=
.
- rescue.target
Single-User Mode Umgebung ohne Netzwerk, aber mit lokalen Dateisystemen; wird zur Reparatur von Systemen verwendet, die nicht mehr sauber booten können. Erfordert das root-Passwort.
- emergency.target
Minimalste Umgebung, die dann verwendet wird, wenn man nicht mehr in den Rescue-Modus starten kann. Hier wird das root-Dateisystem read-only gemountet.
- multi-user.target
Entspricht ungefähr Runlevel 3.
- graphical.target
Entspricht ungefähr Runlevel 5.
Systemd
Systemd-Targets
Auf einem Minimal-System:
basic.target Basic System
cryptsetup.target Encrypted Volumes
getty.target Login Prompts
local-fs-pre.target Local File Systems (Pre)
local-fs.target Local File Systems
multi-user.target Multi-User System
network.target Network
paths.target Paths
remote-fs.target Remote File Systems
slices.target Slices
sockets.target Sockets
swap.target Swap
sysinit.target System Initialization
timers.target Timers
Wichtig: default.target
gibt es auch noch, ist aber auf den meisten Servern gleich dem basic.target
.
Das „höchste“ Target ist das graphical.target, welches von einem laufenden multi-user.target abhängt - ohne dieses gibt es keine grafische Oberfläche. Die folgende Skizze zeigt die Abhängigkeiten der Targets untereinander:
graphical.target (früher: Runlevel 5)
└─multi-user.target (früher: Runlevel 3)
├─basic.target
│ ├─paths.target
│ ├─slices.target
│ ├─sockets.target
│ ├─sysinit.target
│ │ ├─cryptsetup.target
│ │ ├─local-fs.target
│ │ └─swap.target
│ └─timers.target
├─getty.target
└─remote-fs.target
Obiges Bild erhält man per systemctl list-dependencies | grep target
Spezifisches Target booten
Beispiel: zur Installation eines Grafikkarten-Treibers muss in den Multi-User-Target gebootet werden. Nach dem Neustart das Boot-Menü anhalten, gewünschte Kernel-Version wählen und e für „edit“ drücken. Nach der Zeile beginnend mit linux /vmlinuz...
, linux16 /vmlinuz...
oder linuxefi /vmlinuz...
suchen und ergänzen:
systemd.unit=multi-user.target
Targets zur Laufzeit wechseln
Wer z.B. in einer laufenden Kommandozeile die graphische Oberfläche starten, etwas umkonfigurieren und danach beenden möchte, führt das hier aus:
systemctl isolate graphical.target
...
systemctl isolate multi-user.target
Default-Target setzen
Damit RHEL beispielsweise immer in die graphische Oberfläche bootet, führt man aus:
systemctl set-default graphical.target
# or
ln -s /usr/lib/systemd/system/graphical.target /etc/systemd/system/default.target
Boot unterbrechen, Maschine reparieren
Um zum Troubleshooting in einen Rescue-Modus zu booten, gibt es verschiedene Möglichkeiten:
RHEL-/Fedora-Installationsmedium einlegen (ISO/USB/CD-ROM), von diesem booten und im Boot-Menü „Troubleshooting“ auswählen.
Falls kein externes Medium verwendet werden kann, Boot-Menü anhalten, gewünschte Kernel-Version wählen und e für „edit“ drücken. Nach der Zeile beginnend mit
linux /vmlinuz...
,linux16 /vmlinuz...
oderlinuxefi /vmlinuz...
suchen und Zeile je nach Anforderung mit einem der unten stehenden Statements ergänzen:Level
Boot-Parameter
root-Passwort nötig
FS-Status
Bemerkung
0
rd.break
nein
ro
direkt nach initramfs, daher Chroot nötig;
mount -o remount,rw /sysroot; chroot /sysroot; ...; touch ./autorelabel; exit; exit
1
systemd-unit=emergency.target
ja
ro
kein Netz, keine Mounts etc.;
mount -o remount,rw /; ...; exit
2
systemd-unit=rescue.target
ja
rw
kein Netz, keine Mounts etc.
Siehe auch man kernel-command-line
.
/boot
Das /boot
-Verzeichnis enthält die wenigen notwendigen Dateien, um das System zu starten. Für jede installierte Kernel-Version werden vier Dateien vorgehalten:
config
: die Kernel-Konfiguration zu Debug-Zweckeninitramfs
: das initiale RAM-DateisystemSystem.map
: Kernel-Symboltabelle, ebenfalls zu Debug-Zweckenvmlinuz
: das komprimierte Image des Linux-Kernels. Während des Boot-Vorgangs wird er entpackt, ins RAM geladen und ausgeführt.
Während des Boot-Vorgangs ist auch von Interesse:
initrd
: die initial ramdisk ist ein temporäres Dateisystem, das vom Linux-Kernel während des Bootvorgangs verwendet wird.
Eine automatisierte Installation muss richtig booten können. Dafür müssen folgende Parameter vorhanden, gesetzt oder bekannt sein:
Pfad zu einer initrd:
/path/to/CentOS-7-x86_64-Minimal-1810-initrd.img
Pfad zum Kernel:
/path/to/CentOS-7-x86_64-Minimal-1810-vmlinuz
Evtl. Kickstart-Parameter:
ks=/path-or-url/to/ks.cfg ip={{ IP }}::{{ Gateway }}:{{ Netmask }}:{{ FQDN }}:eth0:none nameserver={{ DNS1 }} nameserver={{ DNS2 }}"
Unter /boot
findet sich auch der Grand Unified Bootloader (GRUB).
GRUB
GRUB Boot-Loader wiederherstellen (BIOS)
Fehlerhafte /etc/default/grub
; auch im Rescue-Modus bootet die Maschine nicht richtig oder endlos?
System von einem Installationsmedium booten, z.B. einem CentOS 7 Minimal-ISO.
Im Boot-Screen Esc drücken und als Kommando
linux rescue
eingeben.Root-Umgebung auf die Systemumgebung legen:
chroot /mnt/sysimage
Anschliessend kann man mittels Vim, nano & Co. der
/etc/default/grub
zu Leibe rücken, mitlvm vgdisplay
LVMs untersuchen undgrub2-mkconfig
neu anwenden.
Boot-Loader neu installieren?
Wie oben in den Rescue Modus booten, aber als letzten Schritt
/sbin/grub2-install /dev/sda1
ausführen (angenommen,sda1
ist die zerstörte Boot-Partition)cat /etc/default/grub
usw.
GRUB Boot-Loader wiederherstellen (UEFI)
Aus Versehen Windows neu installiert, und das vorher per Dual-Boot vorhandene Fedora wird nicht mehr zum Starten angeboten?
Mit Fedora Live booten, dann im Terminal:
su -
mount /dev/fedora_markus/root /mnt
mount /dev/sda7 /mnt/boot
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
chroot /mnt
# SecureBoot safe:
dnf -y reinstall grub2-efi shim
grub2-mkconfig --output=/boot/efi/EFI/fedora/grub.cfg
root-Passwort zurücksetzen
Reset password, reset root password? So geht’s:
Maschine (neu) starten.
Boot-Menü anhalten, gewünschte Kernel-Version wählen und e für „edit“ drücken.
Nach der Zeile beginnend mit
linux /vmlinuz...
,linux16 /vmlinuz...
oderlinuxefi /vmlinuz...
suchen.Zeile mit
rd.break
ergänzen.Unter manchen Umgebungen ist eine
console=...
-Option gesetzt. Wenn man nach dem Boot keinen Output sieht, muss diese aufconsole=tty0
geändert werden.Anschliessend per Ctrl+x booten.
System beschreibbar mounten:
mount -o remount,rw /sysroot
Arbeitsverzeichnis wechseln:
chroot /sysroot
Passwort ändern:
passwd
SELinux-Kontexte für die geänderten Dateien beim nächsten Start reparieren lassen:
touch /.autorelabel
2x
exit
oder Ctrl+d
Das Relabeling kann einige Zeit in Anspruch nehmen und darf auf keinen Fall abgebrochen werden.
EFI-Shell
Am Beispiel von BIOS-Updates für Supermicro-Server, per UEFI-Shell durchgeführt. Die EFI-Shell ist DOS-orientiert. Mit „fs0:“ wechselt man Laufwerke, der Backslash trennt Verzeichnisangaben.
Beim Hochfahren des Servers mit F11 in die „Boot Options > UEFI Shell“ wechseln.
map
zeigt alle verfügbaren Devices (HDD, SSD, USB-Sticks) an.fs0:
wechselt auf ein Laufwerk.cd bios
wechselt in das BIOS-Update-Verzeichnis, z.B. eines USB-Sticks.flash.nsh X11DPU7.218
als Beispiel für die Ausführung eines EFI-Shell-Programms.
Troubleshooting
- end_request: I/O error, dev fd0, sector 0
In einer VM, nachdem ein Diskettenlaufwerk entfernt wurde? Die Meldung sieht nicht nur unschön aus, sie verzögert auch noch den Boot-Vorgang.
Abhilfe: das entfernte Diskettenlaufwerk muss im BIOS der virtuellen Maschine deaktiviert werden. Unter VMware gelangt man beim Neustart mit F2 in das BIOS des Gastes.
- Warum dauert der Bootvorgang so lange? Welche Komponenten brauchen besonders lange beim Starten?
systemd-analyze blame
- Abhängigkeiten der Services anzeigen
systemctl list-dependencies
- Welche Daemons sind blockierend voneinander abhängig?
systemd-analyze critical-chain
- GRUB2-Config zerstört, Root-Partition wird nicht mehr gefunden?
Beim Boot ergänzen:
linux16 ... rd.shell
Built on 2024-11-18