Bootvorgang
Linux ist ja nun leider so stabil, dass es nie komplett abstürzt, und man kommt natürlich auch niemals in den Versuchung den Rechner einmal komplett auszuschalten, weil gar nichts mehr geht, bleibt jedoch immer noch das Risiko, die Mutter bleibt mit dem Staubsauger im Kabelgewirr hängen, der kleine Bruder drückt die Resettaste oder das Kraftwerk in Nachbarschaft hat mal wieder einen Störfall. Egal, Ergebnis ist jedenfalls, der Rechner ist aus, und beim booten bleibt der Rechner mit einer Fehlermeldung hängen.
- oder
Nachdem man sich monatelang an seinem Linux erfreut hat, und nach und nach immer mehr von Linux versteht, wird man irgendwann einmal etwas mutiger werden. Festplatten, der Bootloader, der Kernel, die Filesysteme, die Startscripte, nichts ist dann mehr heilig. Die logische Konsequenz, irgendwas war im Howto natürlich wieder nicht richtig beschrieben, man konnte die Warnung also gar nicht beachtet oder übersehen. Wenn man also mal kein Glück hat und das Pech auch gleich noch dazu kommt. Das Ergebnis jedenfalls, der Rechner fährt nicht mehr hoch, die automatische SuSE Reparatur hilft auch nicht weiter und das letzte Backup ist selbstverständlich auch noch unbrauchbar.
Jetzt ist es wichtig zu wissen, wie so ein Bootvorgang von Linux überhaupt abläuft, damit man erst einmal eine grobe Idee bekommt, wo und warum der Bootvorgang hängen könnte.
Inhaltsverzeichnis
Der Bootvorgang von Linux
BIOS
Beim Einschalten, erfolgt ein Reset, die CPU wird in den Real Modus geschalten und beginnt den Code in einem Flash-EEPROM dem so genannten BIOS ab der Speicheradresse 000F:FFF0 abzuarbeiten. Es folgt ein Peripheriecheck bei dem unter anderem die Grafikkarte gesucht wird. Anschließend erfolgt der POST (Power On SelfTest). Hierbei werden die sich auf dem Motherboard befindlichen Controller, sowie CPU und Speicher, auf Funktionstauglichkeit überprüft und nach Erweiterungssteckkarten gesucht, und diese entsprechend der BIOS Einstellungen zu konfigurieren. Diese gefundenen Controller werden meist noch mit ihren Einstellungen kurz angezeigt.
- Fehlermeldungen des BIOS
Sollte hier schon etwas nicht in Ordnung sein, zB fehlender oder defekter Grafikcontroller oder irgendwas anderes noch bevor der Grafikcontroller gefunden und in Betrieb genommen werden konnte, dann meldet das der BIOS über den internen Lautsprecher in Form von definierten Beep Tönen, spätere Fehlermeldungen werden über die Grafikkarte ausgegeben. Weiter Informationen über Funktionen und Fehler während dem POST können im BIOS Kompendium nachgelesen werden.
Nachdem der POST abgearbeitet ist, werden eventuell weitere BIOSe die sich auf eingesetzten Controllern zB. SCSI-Controllern befinden können, gestartet. So ein BIOS ist dafür zuständig, dass über die Geräte die an diesen Controllern angeschlossen sind, auch gebootet werden kann. (Der BIOS der Hauptplatine kann nicht selbst auf solche Geräte zugreifen)
Alles in Ordnung, dann muss jetzt das Betriebssystem irgendwie her
Bootloader
Entsprechend der im BIOS hinterlegten Boot-Reihenfolge durchsucht jetzt der BIOS die Wechselmedien und Festplatten nach einem Bootloader. Dabei wird der MBR (die ersten 512 Byte der Festplatte oder des Mediums) durchsucht. In diese 512 Byte kann ein winziges (bis 440 Byte großes) Programm als Bootloader hinterlegt werden. Ebenfalls in diesem MBR befindet sich die Partitionstabelle für die Partitionen 1 bis 4 und eine MBR-Signatur (0xAA55) die die Partitionstabelle und den Bootloader als gültigen MBR definiert.
die wichtigsten Bootloader die Linux mitbringt sind
Heute wird vor allem GRUB verwendet und ist dabei LILO in modernen Linux-Systemen zu verdrängen, Loadlin wird heute nur noch in einigen wenigen Spezialfällen eingesetzt.
Die wenigen Byte die dort im MBR Platz sind, können natürlich nicht der Kernel selbst sein. Auch ist es hier kaum möglich in diese paar Byte eine Unterstützung für Filesysteme und ähnliches einzubauen, um den Kernel von hier aus direkt zu laden.
Bei Grub nennt sich dieses kleine Programm im MBR stage1. Seine einzige Funktion besteht darin stage2 zu laden. Stage2 befindet sich innerhalb des Linuxsystems im Verzeichnis /boot/grub. Daneben befinden sich dort noch weiter Dateien e2fs_stage1_5 ffs_stage1_5 minix_stage1_5 vstafs_stage1_5 fat_stage1_5 jfs_stage1_5 reiserfs_stage1_5 xfs_stage1_5 diese beinhalten die Unterstützung für die unterschiedlichen Filesysteme auf denen sich das Verzeichnis /boot befinden kann. Bei der Installation von stage1 im MBR durch GRUB wird dort eine feste Adresse in der Form "Controller, Gerät, Partition, Block" hinterlegt, wo sich stage1_5 und stage2 befinden.
- Es wird also vom BIOS stage1 aus dem MBR in den Speicher geladen und gestartet
- stage1 läd jetzt die erforderliche Filesystemunterstützung stage1_5 und startet sie
- stage1_5 lad dann stage2 und startet damit Grub
Die Bedeutung der Fehlermeldungen in diesem Abschnitt.
Ab hier kann Grub auf dem Verzeichnis in dem sich /boot befindet, den Kernel und die Konfigurationsdateien über ihren Namen ansprechen. Grub wertet hier die Datei /boot/grub/menu.lst aus. In dieser Datei befinden sich Menüeinträge für das starten von verschiedenen Betriebssysteme oder verschiedenen Konfigurationen. Hilfe zur Konfiguration und als Einsprungspunkt für alles Geheimnisse gibt es hier
Starten des Kernel
Ist jetzt in Grub die Entscheidung gefallen welcher Kernel mit welchen Optionen geladen werden soll, dann sucht Grub diesen über seinen Namen und läd ihn in den Speicher, dort wird der Kernel dann gestartet und durchläuft folgende Schritte.
- Umschalten auf Protected Mode
- Sprung in den Code der Datei head.S ( im Kernelquellcode /usr/src/linux/arch/i368/kernel/head.S )
- dort werden jetzt Dinge initialisiert die man schon richtig zur Arbeit mit Linux braucht
- Initialisieren der Interrupt Beschreibungstabelle (IDT)
- Sichern der Bootparameter (werden später als Parameter für die Funktion main.c benötigt)
- Prüfung auf Prozessortype
- Initialisieren der Speicherbeschreibungstabelle
Nachdem die Initialisierung durchgeführt wurde kann jetzt die Vorbereitung für den Kernel angegangen werden
- dazu werden Funktionen der Datei ( /usr/src/linux/init/main.c ) gestartet. unter anderem
- Speicher initialisiert
- Einstellungen fpr Interrupts, Scheduler und Zeitgeber
- verarbeiten eventueller Kommandozeilenargumente
- dynamischen Speicherbereich des Kernels initialisieren
Es soll hier auch nicht näher in die einzelnen Vorgänge vorgedrungen werden, wer sich damit auseinander setzten will oder muss, dem sei auf den Quelltext und auf die Howtos zum Kernel verwiesen. Die einzelnen Module des Kernels die initialisiert werden erzeugen Ausgaben auf der Bootkonsole, die man im Fehlerfall genau nach Fehlern durchsuchen muss.
Starten der initrd
Da im Kernel meist nicht alle Module integriert sind, die der Kernel jetzt zum Boot wirklich benötigen würden, wird in der Grubkonfiguration oftmals noch eine initrd (Initial Ram Disk ) mit angegeben. Diese wird nach dem starten des Kernels geladen und abgearbeitet.
Eine initrd besteht entweder aus einem cpio-Archiv oder aus einem mittels gzip komprimierten ext2 Filesystems in einer Datei. Je nach Type der initrd wird diese entweder in einem loopdevide aus dem cpio-Archiv ausgepackt oder die nach dem entkomprimieren der initrd entstandene Datei als loop device gemountet. Diese RAM-Disk stellt somit ein Abbild eines Dateisystems im Speicher dar.
In der Initrd sind jetzt Treibermodule enthalten, die nicht im Kernel enthalten sind, jedoch vor dem Einhängen des Root filesystems benötigt werden. Also ZB. Unterstützung für RAID, wenn das Root filesystem ein RAID Device ist, Unterstützung und Programme (zB. fsck, mount, umount) zum Umgang von Reiserfs, wenn das Root filesystem ein reiserfs ist. Unterstützung für einen SCSI-Controller soweit dieser nicht im Kernel enthalten ist, das Root filesystem sich aber auf einer Platte an diesem Controller befindet. Module für die Unterstützung der Netzwerkkarte, wenn das Root filesystem über das Netz gebootet werden muss usw.
Die initrd oder Initial Ramdisk kann entweder ein mit gzip komprimiertes Abbild eines ext2-Dateisystems sein, oder aber auch ein mit gzip komprimiertes cpio-Archiv. Der Kernel erkennt im Normalfall beides an. In älteren Versionen von Suse war ehr das Dateisystemabbild zu finden, in den neuen Versionen wird das cpio-Achiv bevorzugt. Gelegentlich muss man bei Bootfehlern einmal in dieses initrd hinein, um dort etwas nachzuschauen oder selbst per Hand kleine Änderungen vornehmen. ( Vorsicht: ändern an dieser Stelle ist nur was für wirklich erfahrene User)
initrd ist ext2-Abbild
Folgender Konsolauszug zeigt, wie man eine initrd (ext2 Abbild) öffnen kann:
Das wieder Zusammensetzen eines hier geänderten Filesystems geht dann entsprechend wieder rückwärts zum Auspacken.
LINUX:/tmp # cp /boot/initrd /tmp LINUX:/tmp # file initrd initrd: gzip compressed data, was "initrd_small", from Unix, max compression LINUX:/tmp # mv initrd initrd.gz LINUX:/tmp # gunzip initrd.gz gunzip: initrd.gz: decompression OK, trailing garbage ignored LINUX:/tmp # file initrd initrd: Linux rev 1.0 ext2 filesystem data LINUX:/tmp # mount -t ext2 -o loop /tmp/initrd /mnt LINUX:/tmp # cd /mnt LINUX:/mnt # ls -l total 17 drwxr-xr-x 10 root root 1024 Jul 16 00:36 . drwxr-xr-x 24 root root 560 Nov 5 12:04 .. drwxr-xr-x 2 root root 1024 Jul 16 00:36 bin drwxr-xr-x 3 root root 1024 Jul 16 00:36 dev drwxr-xr-x 3 root root 1024 Jul 16 00:36 etc drwxr-xr-x 4 root root 1024 Oct 31 2004 lib -rwxr-xr-x 1 root root 6159 Jul 16 00:36 linuxrc drwxr-xr-x 2 root root 1024 Jul 16 00:36 mnt drwxr-xr-x 2 root root 1024 Jul 16 00:36 proc drwxr-xr-x 2 root root 1024 Jul 16 00:36 sbin drwxr-xr-x 2 root root 1024 Jul 16 00:36 sys LINUX:/mnt #
Abgearbeitet wird innerhalb dieser etwas älteren initrd die Datei linuxrc welche dann mit folgender Zeile endet.
"die 0"
initrd ist cpio-Archiv
LINUX:/boot # ls -l initrd* lrwxrwxrwx 1 root root 27 Feb 13 23:24 initrd -> initrd-2.6.18.8-0.9-default -rw-r--r-- 1 root root 3267755 Feb 13 23:24 initrd-2.6.18.8-0.9-default LINUX:/boot # cp initrd-2.6.18.8-0.9-default /tmp LINUX:/boot # cd /tmp LINUX:/tmp # file initrd-2.6.18.8-0.9-default initrd-2.6.18.8-0.9-default: gzip compressed data, from Unix, last modified: Wed Feb 13 23:23:59 2008, max compression LINUX:/tmp # mv initrd-2.6.18.8-0.9-default initrd.gz LINUX:/tmp # gunzip initrd.gz LINUX:/tmp # file initrd* initrd: ASCII cpio archive (SVR4 with no CRC) LINUX:/tmp # mkdir initrd-root LINUX:/tmp # cd initrd-root LINUX:/tmp/initrd-root # cpio -i < ../initrd 14440 blocks LINUX:/tmp/initrd-root # ls -l total 224 drwxr-xr-x 2 root root 4096 May 23 20:15 bin -rw-r--r-- 1 root root 167125 May 23 20:15 bootsplash drwxr-xr-x 2 root root 4096 May 23 20:15 dev drwxr-xr-x 4 root root 4096 May 23 20:15 etc -rwxr-xr-x 1 root root 15105 May 23 20:15 init drwxr-xr-x 5 root root 4096 May 23 20:15 lib drwxr-xr-x 2 root root 4096 May 23 20:15 proc drwxr-xr-x 2 root root 4096 May 23 20:15 root drwxr-xr-x 2 root root 4096 May 23 20:15 sbin drwxr-xr-x 2 root root 4096 May 23 20:15 sys drwsrwxrwx 2 root root 4096 May 23 20:15 tmp drwxr-xr-x 3 root root 4096 May 23 20:15 var
Zusammengesetzt wird wieder in umgekehrter Reihenfolge. Abgearbeitet wird in dieser neuartigen initrd die Datei init welche wiederum mit "die 0" endet
Achtung: da es zur Zeit hier sehr viele Veränderungen bei der prinzipellen Hardware-Handhabung gibt, gibt es auch sehr viele Änderungen an den Scripten von mkinitrd und selbstverständich dem inneren Aufbau und deren Funktion der initrd selbst. Distributionsabhängig sollte man sich desshalb unbedingt vor manuellen Änderungen vorher noch einmal mit den Manpages und eventuell den mit der aktuellen Distribution installierten Dokumenten befassen.
Sollten Fehler innerhalb der Abarbeitung der initrd auftreten, dann sind diese an der Bootkonsolausgabe ersichtlich. Meist sind es fehlende oder falsche Module, fehlende oder veraltete Konfigurationsinformationen oder die falsche initrd zu diesem Kernel. Ist das System über eine Boot- oder Install-CD komplett startbar dann dort mittels des Befehls
mkinitrd
die initrd neu erzeugen. Sollte es nicht möglich sein, das System mittels einer solchen CD zu booten, so kann statt dessen ein System von CD gebootet werden und die initrd innerhalb einer chroot-Umgebung neu erstellt werden. Dazu ist es jedoch erforderlich entweder eine ganze Menge Optionen an den Befehl mkinitrd zu übergeben, oder was sehr viel einfach und fehlerfreier läuft, der chroot-Umgebung die Informationen zur Verfügung zu stellen, die sie zum erkennen aller Gegebenheiten benötigt.
mount /dev/...... /mnt #Rootfilesystem mount /dev/...... /mnt/..... #falls /boot /usr /var eigene Verzeichnisse darstellen diese unterhalb von /mnt einhängen chroot /mnt mount /proc mount /sys mkinitrd
Einhängen des Rootfilesystems
nachdem die initrd abgearbeitet ist, erfolgt das Laden des Rootfilesystems entsprechend den Angaben in der Grubkonfiguration. Das Filesystem wird per default erst einmal "readonly" gemountet. Hier werden die meisten Fehler jetzt aufschlagen, und sich bemerkbar machen mit dem Fehler "kein Rootdevice gefunden" oder "Filesystem nicht bekannt" die schon zu einem früheren Zeitpunkt des Bootprozesses ihre Ursache haben.
mögliche Ursachen:
- falsche Konfiguration oder Eingabe über das Rootdevice bei Grub
- defekte Partitionstabelle, oder zerschossenes Filesystem
- fehlender Treiber für Filesystem, oder Controller
- fehlender Treiber für RAID oder LVM
Sollte der Fehler hier auftreten, hilft nur Studium der Bootlogausgaben.
Starten der /etc/inittab
wenn das Root filesystem eingehängt ist, wird die Datei /etc/inittab gestartet. Dabei handelt es sich nicht um ein Script im herkömmlichen Sinne, siehe dazu die ManPage der Datei /etc/inittab
Das erste Script das innerhalb der inittab gestartet wird, ist bei SuSE normalerweise /etc/init.d/boot . Dieses Script startet dann zuerst die Startscripte in /etc/init.d/boot.d
Dort kommt es besonders nach Systemcrash öfter einmal zu einem Bootabbruch innerhalb des Scripte S03boot.rootfsck. Das Root filesystem ist so defekt, dass eine automatisierte Reparatur mit fsck nicht funktioniert hat und dieses Programm interaktiv vom User gestartet werden soll. Hier hilft schon ein genaues lesen der Fehlermeldung, die schon fast genau sagt, was gemacht werden muss. Etwas knifflig kann es mit Reiserfs werden, hier hilft Reiser-Dateisystem reparieren eventuell weiter.
Starten der Runlevel
sind die Bootscripte durchlaufen, werden die zu den einzelnen Runlevel konfigurierten Scripte gestartet. Die Fehler die hier auftreten können sind sehr vielfältig, wirklich tödliche Fehler hier aber eher selten. Es läßt sich jedoch in aller Regel sehr schnell feststellen, in welchem Script ein solcher tödlicher Fehler aufgetreten ist. Hier hilft dann ein Starten des Runlevel 1 und das manuelle Starten jeden einzelnen Scripts, das zum Runlevel gehört, um das Entstehen des Fehlers näher eingrenzen zu können. Es können also zB dadurch ausgelöst werden, dass die Scripte nicht in der richtigen notwendigen Reihenfolge gestartet werden, oder man sonstige Fehler eingebaut hat.
Häufiges Problem bei Runlevel 5 ist das Problem mit dem nichtstarten der Grafischen Oberfläche, meist ausgelöst durch fehlerhafte Konfiguration des Xservers.
weiter Links zum Thema booten von Linux
- Booten (Wikipedia)
- Schnelles Booten mit Upstart, einem Ersatz für das betagte Sys-V-Init (Artikel Linux Magazin)
- PXE Bootablauf (schematische Darstellung)