# 1.102.2

# Installation eines Bootmanagers

Beschreibung: Prüfungskandidaten sollten in der Lage sein, einen Bootmanager auszuwählen, zu installieren und zu konfigurieren. Dieses Lernziel beinhaltet das Bereitstellen alternativer und Sicherungsbootmöglichkeiten (z.B. mittels Bootdiskette).

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

- `/etc/lilo.conf`
- `/boot/grub/grub.conf`
- lilo
- grub-install
- MBR
- Superblock
- Bootloader der ersten Stufe

### Prinzipielles zur Funktion von Bootmanagern

Auf der Hardware-Ebene von industriestandardkompatiblen Computern (und um die geht es hier) ist der Bootvorgang von Betriebssystemen klar vorgegeben. Das BIOS (Basic Input Output System) im ROM jedes Computers sucht auf der Platte, von der es booten soll/will nach dem äußersten Zylinder (Nr.0). Dieser Zylinder ist selbst nicht Teil von Partitionen, sondern er enthält z.B. die Partitionstabelle, die erstmal festlegt, wo denn überhaupt welche Partitionen beginnen und enden. Neben dieser Information befindet sich auf der Spur 0 jedes physikalischen Laufwerks der sogenannte Master Boot Record (MBR). Dieser MBR enthält gewöhnlich einfach einen Verweis auf die erste Partition der Platte und der dort abgelegten Bootinformation.

Jede Partition der Platte besitzt nämlich wiederum auf ihrem ersten Zylinder einen lokalen Bootsektor, der Informationen enthalten kann (bei DOS/Win-Systemen) wie das auf dieser Partition befindliche Betriebssystem gebootet werden soll. Diese Information besteht aus einem kleinen Programm, dem sogenannten Bootstrap-Loader.

Wenn auf einem System mehrere Betriebssysteme vorhanden sind, dann kann im Master Boot Record ein kleines Programm installiert werden, das den User entscheiden lässt, von welcher Partition welches System gebootet werden soll. Dieses Programm wird als Bootmanager bezeichnet.

Auf dem MBR ist aber nur sehr wenig Platz (weniger als 512 Byte). Das dort abgelegte Programm ist also zwangsläufig sehr klein. Meist wird das Programm nichts anderes tun, als ein zweites Programm zu laden, das das eigentliche Menü des Bootmanagers enthält. Dieses zweite Programm befindet sich zwangsläufig schon auf einer Festplattenpartition. Der Bootmanager muß also - unter Umgehung des Betriebssystems, das ja noch gar nicht geladen ist - Zugriff auf das Dateisystem dieser Partition haben und das gewünschte Programm dort laden. Dieser Vorgang wird als erste Stufe (Stage 1) des Bootloaders bezeichnet.

Das Programm, das das eigentliche Menü enthält, ist also die zweite Stufe (Stage 2) des Ladevorganges. Hier kann der/die BenutzerIn also aussuchen, welches Betriebssystem von welcher Partition gebootet werden soll. Erst nach dieser Auswahl wird das eigentliche System geladen (Stage 3).

Der klassische Bootmanager unter Linux war jahrelang das Programm lilo (Linux Loader). Neuerdings existiert eine zweite Möglichkeit, der GRand Unified Bootloader grub. Verschiedene Distributionen bedienen sich inzwischen dieser zweiten Methode, daher werden beide im weiteren Verlauf des Kapitels besprochen.

### Konfiguration von lilo

Wenn der Bootmanager lilo benutzt werden soll, so werden alle Konfigurationsinformationen in der Datei `/etc/lilo.conf` abgelegt. Das Programm lilo liesst diese Datei und führt die folgenden Schritte aus:

- Aus den Einträgen der Konfigurationsdateien werden Menüeinträge erstellt, die in eine Datei (standardmäßig `/boot/boot.b`) abgelegt werden. Weitere Menüelemente können - je nach Konfiguration - in den Dateien `/boot/boot-menu.b`, `/boot/message` und `/boot/boot-bmp.b` abgelegt werden.
- Die Adressen und Größen der zu ladenden Kernel-Dateien werden in die Datei `/boot/map` geschrieben. Damit ist lilo später in der Lage, auf diese Dateien zuzugreifen, ohne ein Betriebssystem zu benutzen.
- Ein kleines Programm wird in den Master Boot Record geschrieben, das die Adressen der oben genannten Dateien in `/boot` enthält und die Aufgabe hat diese zu laden.

Das bedeutet, daß jedesmal, wenn eine Veränderung an den zu bootenden Kerneldateien gemacht wird, das Programm lilo neu aufgerufen werden muß. Selbst wenn alle Dateinamen gleich bleiben, so verändern sich eben doch die Adressen und Größen auf der Platte und die Informationen in `/boot/map` würden nicht mehr stimmen.

Normalerweise genügt der Aufruf von lilo ohne weitere Parameter.

Wird lilo mit der Option `-u` oder `-U` aufgerufen, so löscht es die Einträge auf dem entsprechenden Bootsektor und stellt ihn wieder so her, wie er war, bevor lilo installiert wurde. Damit kann eine Platte also wieder vom Bootmanager befreit werden.

Wenn beim Booten mit lilo ein Fehler auftritt, so kann dieser Fehler anhand des Bootprompts eingekreist werden. Der Bootprompt ist standardmäßig einfach das Wort:

      LILO boot:

Das Wort LILO wird Zeichen für Zeichen auf den Schirm geschrieben. Falls es zu einem Fehler während des Bootmanager-Vorgangs kommt, so kann dieser Fehler anhand der Tatsache eingekreist werden, wieviele Buchstaben schon geschrieben wurden. Die folgenden Schritte werden jeweils durchgeführt, wenn ein Buchstabe geschrieben wurde:

nichts
  Kein Teil von Lilo wurde geladen. Entweder ist lilo nicht installiert oder er sitzt auf einem Bootsektor einer Partition, die nicht aktiviert ist.
LFehlernummer
  Der erste Teil des Bootloaders wurde lokalisiert und geladen, aber er kann den zweiten Teil nicht laden. Die zweistellige Fehlernummer gibt genauere Hinweise auf den Grund an. In der Regel deutet dieser Fehler auf ein Problem mit der Plattenoberfläche oder falschen Plattenparametern im BIOS hin.
LI
  Der erste Teil des Bootloaders hat den zweiten Teil geladen, kann ihn aber nicht ausführen. Das kann daran liegen, daß es entweder eine Inkompatibilität mit der Plattengeometrie gibt, oder die Datei /boot/boot.b wurde von der Stelle bewegt, an der sie lag, als lilo installiert (aufgerufen) wurde.
LIL
  Der zweite Teil des Bootloaders wurde gestartet, kann aber die Beschreibungstabelle des map-files nicht laden. Typischerweise ein Medien-Fehler (Oberflächenbeschädigung) oder unpassende Plattengeometrie.
LIL?
  Der zweite Teil des Bootloaders wurde an eine falsche Adresse geladen. Auch hier ist die wahrscheinlichste Ursache, daß die Datei /boot/boot.b verändert oder bewegt wurde.
LIL-
  Die Beschreibngstabelle ist beschädigt. Entweder ein Oberflächenfehler, oder die Datei /boot/map wurde verändert oder bewegt.
LILO
  Alle Teile von lilo wurden ordnungsgemäß geladen.

In jedem Fall ist bei einem Fehler immer der erste Versuch, lilo nochmal aufzurufen, nachdem das System über eine andere Technik (Bootdiskette, BootCD) gebootet wurde. War es der erste Versuch, der gescheitert ist, also hat lilo noch nie vorher funktioniert, so sollte davor aber nochmal die Datei /etc/lilo.conf überprüft werden.

### Die Datei /etc/lilo.conf

Die Datei /etc/lilo.conf enthält die Angaben, die lilo braucht um den Bootloader in einen Bootsektor zu schreiben. Sie besteht im Wesentlichen aus zwei Teilen. Der erste Teil beschreibt globale Einstellungen, der zweite beschreibt für jedes zu bootende System separate Einstellungen.

Ein typischer erster Teil einer lilo.conf-Datei könnte folgendermaßen aussehen:

      append="reboot=warm"
      boot=/dev/hda
      lba32
      message=/boot/message
      prompt
      timeout=300

Die Zeile `append=...` ermöglicht es, jedem zu bootenden Kernel bestimmte Parameter mitzugeben. Hier ist es der Parameter `reboot=warm`, der dazu führt, daß beim Reboot nicht ein Kaltstart (mit Speicherprüfung) sondern ein Warmstart ausgeführt wird.

Die Zeile `boot=...` gibt den Ort an, auf den lilo den Bootloader schreiben soll. Wird hier eine ganze physikalische Platte angegeben, also eine Gerätedatei ohne Partitionsnummer wie /dev/hda, so wird der Master-Boot-Record dieser Platte beschrieben. Stünde hier die Angabe einer Partition, also etwa /dev/hda2, so würde der Bootsektor der Partition beschrieben.

Die Angabe von `lba32` versetzt lilo in die Lage, auch mit Platten mit mehr als 1024 Zylindern umzugehen, wenn im BIOS der LBA-Modus eingestellt wurde.

Die Zeile `message=...` gibt an, aus welcher Datei die Bildschirmmeldung des Bootloaders stammen soll. Ohne diese Zeile wird keine Bildschirmmeldung benutzt. Der Inhalt der angegebenen Datei wird mit auf den Bootsektor geschrieben, wenn lilo aufgerufen wird. Sollten also Veränderungen vorgenommen werden sollen, so reicht es nicht, diese in die angegebene Datei zu schreiben. Es muß das Programm lilo nochmal aufgerufen werden, damit diese Veränderungen auch tatsächlich auf den Bootsektor kommen.

Die Angabe `prompt` veranlasst lilo, auf eine Benutzereingabe zu warten. Das ist insbesondere dann nötig, wenn mehr als ein Betriebssystem bootbar sein soll.

Die Zeile `timeout=...` gibt schließlich die Zehntelsekunden an, die auf Benutzereingaben gewartet werden soll, bevor das voreingestellte System gebootet wird. Die Angabe 300 steht also für 30 Sekunden.

Die Handbuchseite über lilo.conf(5) zeigt alle möglichen globalen Parameter auf.

Als zweiter Teil der Datei `/etc/lilo.conf` stehen die Einstellungen für die zu bootenden Systeme. Jede dieser Angaben beginnt mit einem `image=...` für Linux-Systeme oder einem `other=...` für alles andere und enthält dann noch mindestens die Angabe, auf welcher Partition sich die Wurzel des zu bootenden Systems befindet und welches label sie hat, mit dem lilo dann mitgeteilt werden kann, daß diese Partition gebootet werden soll. Ein Beispiel:

      image = /boot/zImage
        root = /dev/hda2
        initrd = /boot/initrd
        label = linux

      image = /boot/vmlinuz
        root = /dev/hda2
        label = linuxalt

      other = /dev/hda1
        label = windows
        alias = win

Der erste Block ist der voreingestellte. Dieses System wird also gebootet, wenn das Timeout erreicht ist oder LILO einfach mit der Enter-Taste beantwortet wird.

Dieser erste Block beschreibt also, daß der Kernel, der in /boot/zImage abgelegt wurde, gebootet werden soll. Das Wurzeldateisystem ist /dev/hda2. Die Zeile `initrd = /boot/initrd` bezeichnet die zu ladende initiale Ramdisk.

Der zweite Block beschreibt eine andere Kerneldatei (/boot/vmlinuz), die aber auch die Partition /dev/hda2 als Wurzelverzeichnis nützt. Um diesen Kernel zu booten muß auf dem Bootprompt das Wort "linuxalt" eingegeben werden.

Der dritte Block bezieht sich auf ein Nicht-Linux System (other). Statt der Kerneldatei wird hier einfach die Angabe der Partition gemacht, auf der dieses andere System liegt. Lilo kann ja davon ausgehen, daß jedes andere System auf dem Bootsektor seiner Partition seinen Bootstrap-Loader selbst abgespeichert hat. Das einzige, was wir noch an Information brauchen ist das Label, also das Wort, was wir auf dem Bootprompt angeben müssen, um dieses System zu laden. In unserem Beispiel ist es "windows". Weil das sehr lang ist, kann dazu noch ein Alias vergeben werden, in unserem Fall das Wort "win".

### Konfiguration von grub

Im Gegensatz zu lilo schreibt grub kein statisches Menü in eine der Dateien unter `/boot`. grub schreibt einfach nur einen Eintrag in den Master Boot Record der seinerseits wieder ein Programm unter `/boot/grub` läd. Dieses Programm ließt dann die Konfigurationsdatei `/boot/grub/grub.conf` und erstellt aus der darin gefundenen Information das Bootmenü.

Um mit grub zu arbeiten genügt es also einmal den Befehl

      /sbin/grub-install /dev/hda

einzugeben, wobei die angegebene Gerätedatei `/dev/hda` den Master Boot Record der ersten IDE-Platte meint. Soll von einer SCSI-Platte gebootet werden (in einem System ganz ohne IDE-Platten), so muß diese Angabe entsprechend modifiziert werden. Diese Angabe bezieht sich nicht auf die Partitionen der zu bootenden Systeme sondern auf den Ort, wohin der Bootmanager geschrieben werden soll. Das BIOS der PCs sucht den Bootmanager immer zuerst auf dem Master Boot Record der ersten IDE-Platte, also ist `/dev/hda` in der Regel richtig.

Durch diese Architektur muß grub jetzt nicht mehr jedesmal aufgerufen werden, wenn sich an seiner Konfiguration etwas ändert. Da die zweite Stufe des Bootmanagers selbst die Konfigurationsdatei liesst, entfällt diese Notwendigkeit. Das ist natürlich auch der Grund, warum die Konfigurationsdatei von grub nicht im Verzeichnis `/etc` liegt, sondern auf dem `/boot` Dateisystem.

### Die Datei /boot/grub/grub.conf

Diese Datei enthält die eigentliche Information über die zur Verfügung stehenden Bootmöglichkeiten. Damit geht grub einen anderen Weg als lilo. Diese Datei kann jederzeit auch im Nachhinein verändert werden und grub muß deshalb nicht erneut aufgerufen werden. Die Datei hat ein ähnliches Format wie die Konfigurationsdatei von lilo, aber sie unterscheidet sich im Detail erheblich.

Ein Beispiel für eine `grub.conf` Datei erfordert es, daß wir uns ein imaginäres Linux-System aufbauen. Nehmen wir folgendes Partitionsaufteilung:

      /dev/hda1         /boot-Partition von Linux
      /dev/hda2         Windows98-Partition
      /dev/hda3         Wurzelpartition von Linux

Eine einfache Konfigurationsdatei von grub könnte dann folgendermaßen aussehen:

      default=0
      timeout=10
      splashimage=(hd0,0)/grub/splash.xpm.gz

      title Linux (2.4.18)
    	root (hd0,0)
    	kernel /bzImage-2.4.18 ro root=/dev/hda3
    	initrd /initrd-2.4.18.img

      title Linuxalt (2.2.14)
    	root (hd0,0)
    	kernel /bzImage-2.2.14 ro root=/dev/hda3
    	initrd /initrd-2.2.14.img

      title Windows 98
    	map (hd0,0) (hd0,1)
    	map (hd0,1) (hd0,0)
    	rootnoverify (hd0,1)
    	chainloader +1

Die ersten drei Zeilen sind - ähnlich wie bei `lilo.conf` die globalen Einstellungen. `default=0` bedeutet, daß der erste Eintrag gewählt wird, wenn der Timeout überschritten wurde. Die zweite Zeile definiert diesen Timeout Wert in Sekunden. Die dritte Zeile definiert das verwendete Hintergrundbild. Hier finden wir bereits die erste Anwendung der grub-spezifischen Adressierung, die gleich näher erläutert wird.

Die folgenden Einträge definieren jeweils die zu bootenden Systeme. Die einzelnen Zeilen bedeuten jeweils folgendes:

title Titelzeile
  Diese Zeile leitet einen Abschnitt eines zu bootenden Systems ein. Der unter Titelzeile gemachte Eintrag erscheint später im Menü.
root hdn,m
  Dieser Eintrag ist nicht das Wurzelverzeichnis des Linuxsystems. Er bezeichnet die Partition, auf der die Kerneldateien und die grub-Konfigurationsdateien liegen. In unserem Beispiel ist das `/dev/hda1`, also die `/boot`-Partition von Linux. Die angegebenen Zahlen bezeichnen folgendes:
  - n - Nummer der Platte (0 ist die erste Platte, 1 die zweite, ...)
  - m - Nummer der Partition auf der Platte (0 ist die erste Partition, 1 die zweite, ...)
  Unser Beispiel bezeichnet also mit `(hd0,0)` die erste Partition der ersten Platte also im Linux-Jagon `/dev/hda1`.

  Alle weiteren Angaben beziehen sich auf diese Platte.

kernel Kerneldatei Parameter
  Mit dieser Angabe wird die Kerneldatei angegeben und mit Aufrufparametern versehen. Der Pfad der Kerneldatei bezieht sich hier nicht auf die Wurzel des Linux-Systems sondern auf die Wurzel des Systems, das wir im letzten Punkt (root) angegeben hatten. In unserem Beispiel liegt die Kerneldatei also unter `/boot/bzImage-2.4.18`.

  Die eigentliche Wurzel des zu bootenden Linux-Systems wird als Kernelparameter angegeben (hier also `/dev/hda3`.

initrd Ramdiskimage
  Hier wird der Name der Ramdiskdatei angegeben, die als initiale Ramdisk geladen werden soll. Benutzt der Kernel keine initiale Ramdisk, so wird diese Zeile komplett weggelassen. Auch hier bezieht sich der Pfad auf die Wurzel des unter `root` angegebenen Devices.

Der zweite Eintrag definiert einen zweite Kernel auf der selben Partition. Die Angaben entsprechen denen des ersten Eintrags.

Im dritten Eintrag wird eine Windows-Partition definiert, die Win98 booten soll. Dieser Eintrag enthält einige Besonderheiten, die hier noch kurz dargestellt werden sollen.

map (Partition1) (Partition2)
  Windows98 bootet normalerweise nur von der ersten Partition der ersten Festplatte. Durch den Befehl `map (hd0,0) (hd0,1)` erklären wir die Partition `hd0,0` zur zweiten Partition (`hd0,1`) und mit der nächsten Zeile wird entsprechend die zweite Partition zur ersten. Aus der Sicht des Windows-Systems ist also die zweite Partition jetzt die erste und umgekehrt. Damit ist für Windows die Welt wieder in Ordnung und es glaubt, von der ersten Partition zu booten.
rootnoverify (Partition)
  Diese Angabe entspricht der Angabe `root` bei Linux-Einträgen, nur das diesesmal die entsprechende Partition nicht gemountet wird. (Das ist unter Windows nicht nötig, da ja nicht eine bestimmte Datei geladen werden soll, sondern der Bootsektor der Partition)
chainloader +1
  Diese Angabe ist für Windows erforderlich. Windows wird über einen chainloader gebootet, der auf einem betimmten Sektor der Windows-Partition liegt. Die Angabe +1 bezeichnet hier die Sektornummer 1, also den Bootsektor der Windows-Partition (die unter `rootnoverify` angegeben wurde).

Es existieren natürlich noch viele weitere Möglichkeiten für die Konfigurationsdatei, aber die hier genannten sollten einen ausreichenden Überblick über den Einsatz von grub als Bootmanager geben.

### Sicherheitsbootmöglichkeiten

Wenn aus irgendeinem Grund der Master Boot Record zerstört wurde, dann wird weder lilo noch grub ein Bootmenü anbieten. In einem solchen Fall ist es notwendig, über eine alternative Möglichkeit booten zu können um dann mit den entsprechenden Befehlen lilo (`lilo`) oder grub (`grub-install`) erneut in den MBR zu installieren.

Praktisch jedes Installationsmedium von Linux (Boot-CDs, Bootdisketten) bietet die Möglichkeit, ein bereits installiertes Linux-System zu booten. Dazu muß nur eine Angabe bekannt sein, nämlich die Partition, die für dieses zu bootende System die Wurzelpartition ist. Das kann einfach dadurch geschehen, daß beim Booten des Installationsmediums der Kernelparameter

      root=Partition

angegeben wird. Die Partition wird hier in einer für Linux verständlichen Form angegeben, also beispielsweise `/dev/hda3`. Damit wird dann der auf dem Installationsmedium befindliche Kernel gebootet, seine Wurzelpartition ist aber dann die angegebene Partition. Das heißt, wir können dann entsprechend auf dem System arbeiten, um den richtigen Bootmanager wieder zu installieren.