Next: Laufzeitmodule für den Kernel
Up: Systemverwaltung
Previous: Systemverwaltung
Die erste umfangreiche Aufgabe der Systemverwaltung besteht darin, das System zu starten und in einen Anfangszustand zu bringen, der es auf die eigentlichen Anwendungen optimal vorbereitet. Der Vorgang des Systemstarts läßt sich in vier Phasen gliedern:
Diese vier aufeinander aufbauenden Phasen bestimmen, wie das Laufzeitsystem aussieht. Als Systemverwalterin müssen Sie dafür sorgen, daß alle Voraussetzungen für den produktiven Betrieb des Linux-Systems erfüllt sind.
Im Moment des Einschaltens ist der Arbeitsspeicher des Rechners vollständig leer. Das Betriebssystem ist nicht in irgendwelchen Chips fest auf der Hauptplatine gespeichert, sondern es befindet sich zum Beispiel auf einer Diskette und muß erst von dort geladen werden.Von wo und auf welche Weise das Betriebssystem geladen wird, ist von der Rechnerarchitektur abhängig. Linux für Intel-PC wird normalerweise von Diskette oder Festplatte gebootet. Manchmal wird der PC auch als ``Diskless Workstation'' eingesetzt, die das Betriebssystem über eine Netzwerkverbindung bootet und das Rootfilesystem per NFS importiert.
Die Intel-PC sind mit einem Basic Input Output System (BIOS) ausgestattet, das beim Einschalten oder nach einem Reset automatisch versucht, den Bootvorgang zu starten. Das BIOS überläßt die Einzelheiten des Ladevorgangs dem Betriebssystem selbst, stellt aber einfache Funktionen zum Lesen von Diskette oder Festplatte und zum Schreiben in den Speicher oder auf den Bildschirm zur Verfügung.
Das Betriebssystem wird nicht gleich als ganzes in den Speicher geladen. Stattdessen wird vom BIOS ein sehr kleines Programm, ein sogenannter ``Bootloader'', in den Arbeitsspeicher geladen und die Kontrolle für den weiteren Bootvorgang an dieses Programm abgegeben.
Im einfachsten Fall lädt das BIOS einen Linux-spezifischen Bootloader vom ersten Sektor einer Diskette im Bootlaufwerk. Der Loader zieht den Kernel hinterher, schiebt ihn an die richtige Stelle im Arbeitsspeicher und übergibt schließlich die Kontrolle über den Rechner an das Betriebssystem.
Der erste Block einer Kerneldatei enthält sinnvollerweise genau das passende Programm zum Laden des Kernels. Wenn der Kernel mit dd oder cp auf eine formatierte, rohe Diskette ohne Dateisystem geschrieben wird, befindet sich der Bootblock genau an der richtigen Stelle, um vom BIOS gelesen zu werden. Sie erhalten also eine einfache Linux-Bootdiskette, indem Sie eine Kerneldatei auf eine Diskette kopieren.
Bei dieser Methode haben Sie keine Möglichkeit, dem Kernel zusätzliche Bootparameter zu übergeben. Bis auf die wenigen Parameter, die sich mit dem Programm rdev an der Kerneldatei verändern lassen, müssen alle einkompilierten Kerneleinstellungen zu Ihrem System passen, damit diese Bootmethode erfolgreich ist.
Wenn Sie Ihr Linux-System selbst installiert haben, ist Ihnen bereits eine andere Methode zum Booten von Diskette begegnet. Bei den Installationsdisketten für die Linux-Distributionen wird meistens der LILO Bootloader verwendet, der später noch genauer beschrieben wird.Diese Methode, von einer Diskette zu booten, hat zwei Vorteile:
Wenn Sie sich solch eine Rettungsinsel herstellen wollen, können Sie mit einem der vorgefertigten Images beginnen, die bei einigen Linux-Distributionen enthalten sind. Suchen Sie in dem Verzeichnis auf der Distributions-CD oder auf dem FTP-Server, wo Sie die Daten für die Root-Disk zur Installation gefunden haben, nach einer Datei mit dem Namen rescue. Stellen Sie aus dieser Datei eine Root-Disk her, so wie Sie es für die Installationsdisketten getan haben. Zusammen mit der originalen Bootdiskette von der Installation haben Sie dann ein arbeitsfähiges Minimalsystem auf Diskette.
Wenn Sie eigene Bootdisketten für spezielle Aufgaben herstellen möchten, finden Sie weitere Informationen und Anregungen im Bootdisk-HOWTO.
Normalerweise wird Linux dauerhaft auf der Festplatte installiert und soll auch von dort gebootet werden. Das bringt einen kleinen Zeitgewinn beim Lesen der Kerneldatei und es vermindert die Anzahl der auf dem Schreitisch herumliegenden Disketten.
Linux ist häufig nicht das erste oder einzige Betriebssystem für einen PC. Deshalb wurden für Linux mehrere unterschiedliche Methoden und Programme entwickelt, mit denen die Anpassung des Bootkonzepts an die Vielfalt unterschiedlicher Konfigurationen und Einsatzgebiete für Intel-PC möglich ist. Welcher Weg der Richtige für Sie ist, hängt vor allem davon ab, wie Sie Ihre Festplatte eingeteilt haben.
Anders als Disketten werden Festplatten in Verwaltungsbereiche, sogenannte Partitionen unterteilt. Dieses Konzept wird von allen Betriebssystemen für PC unterstützt. Eine Festplatte kann in maximal vier primäre Partitionen eingeteilt werden, eine dieser Partitionen läßt sich als ``erweiterte Partition'' zusätzlich in ``logische'' Partitionen (Laufwerke) unterteilen. Jede Partition kann ein eigenes Dateisystem tragen und von einem anderen Betriebssystem besiedelt werden.
Zu Anfang unterscheidet sich der Vorgang beim Booten von Festplatte nicht wesentlich von dem beim Booten von Diskette: wenn das BIOS keine Bootdiskette im Laufwerk A: findet, lädt es automatisch den ersten Sektor der ersten Festplatte (den Master Boot Record, MBR) und führt den darin enthaltenen Bootloader aus. Der Bootloader im Master Boot Record einer Festplatte ist ebenso austauschbar wie der einer Bootdiskette, er wird zusammen mit dem ersten Betriebssystem installiert. Im Prinzip ist also auch hier der MBR ein Teil des Betriebssystems und das Betriebssystem damit selbst dafür verantwortlich, sich in den Arbeitsspeicher zu laden.Offensichtlich birgt dieses Verfahren ein gewisses Konfliktpotential, wenn ein zweites oder drittes Betriebssystem auf der gleichen Festplatte installiert wird. Um die friedliche Koexistenz zu ermöglichen, wird ein zusätzlicher Zwischenschritt vor dem Laden des eigentlichen Betriebssystems eingeführt: beispielsweise holt der bei einer DOS- oder Windows-Installation im Master Boot Record installierte Bootloader aus dem ersten Sektor der als aktiv markierten (DOS-)Partition einen zweiten Bootloader in den Speicher und überläßt diesem Secondary Bootloader das Laden des Betriebssystems.
Für Linux stehen mehrere Bootkonzepte zur Auswahl, mit denen Sie sehr flexibel auf die Gegebenheiten und Anforderungen eines geteilten Systems reagieren können.Als allgemeiner Bootloader für Linux, der sowohl als Bootmanager im Master Boot Record als auch als Secondary Bootloader eingesetzt werden kann, hat sich LILO von Werner Almesberger bewährt.
Zum Booten von Linux aus einem laufenden DOS-System heraus gibt es das Programm loadlin.exe von Hans Lermen.
Mit dem generischen Bootloader für Linux, kurz Linux Loader oder LILO, können Sie Linux und eine ganze Reihe anderer Betriebssysteme für Intel-PC von Festplatte booten. Als ``Bootmanager'' kann er bis zu 16 verschiene Systeme oder Konfigurationen starten, er kann Linux von der zweiten oder dritten Festplatte laden, er übergibt dem Kernel eine Kommandozeile und er unterstützt die Init-Ramdisk.
Die Vielseitigkeit von LILO beruht vor allem darauf, daß er mit einer als map bezeichneten Tabelle alle Daten, die er zum Laden des Betriebssystems benötigt, von (fast) beliebigen Plattenblöcken holen kann. Vorausgesetzt wird lediglich, daß der Bootsektor von LILO auf einer primären Partition der ersten Festplatte installiert ist und daß sich die Daten in einem vom BIOS sichtbaren Teil der Festplatte befinden.
Die Installationsprogramme der Linux-Distributionen versuchen mit mehr oder weniger hilfreicher Benutzerführung, die Konfigurationsdatei für LILO zu erstellen und damit das Linux-System von Festplatte bootfähig zu machen. Wenn Sie LILO auf diese Weise installieren und dabei auf Probleme oder Unklarheiten stoßen, kann Ihnen dieses Kapitel in den meisten Fällen weiterhelfen. Wenn Sie unsicher sind, sollten Sie auf die Installation von LILO auf der Festplatte ``im ersten Anlauf'' verzichten und sich in Ruhe die gesamte Dokumentation zu LILO durchlesen, bevor Sie die Installation zu einem passenden Zeitpunkt durchführen.
Bei allen bekannten Linux-Distributionen finden Sie wenigstens einen Teil der Hilfstexte zu LILO in einem Unterverzeichnis von /usr/doc. Die vollständige Dokumentation finden Sie jedenfalls bei den Sourcen, die bei den auf CD vertriebenen Linux-Distributionen mitgeliefert werden. Wenn Sie Zugang zum Internet haben, finden Sie eine Online-Version auf http://www.lunetix.de.
Wenn er im Master Boot Record installiert wird, überschreibt LILO jeden dort eventuell von einem anderen Betriebssystem installierten Primary Bootloader. LILO kann in der Regel die Funktion des verdrängten Bootloaders mit übernehmen, wenn die entsprechenden Einstellungen in der Konfigurationsdatei /etc/lilo.conf vorgenommen wurden.
Als sekundärer Bootloader kann LILO nur auf der ersten Festplatte und dort nur auf einer primären Linux-Partition mit einem beliebigen Linux-Dateisystem oder im Bootsektor der erweiterten Partition installiert werden. LILO kann nicht auf einer Swap-Partition oder im Bootsektor einer von einem anderen Betriebssystem belegten Partition installiert werden.
Damit LILO als sekundärer Bootloader arbeiten kann, muß im Master Boot Record ein primärer Bootloader enthalten sein, der den Linux Loader als sekundären Bootloader ausführt. Zu diesem Zweck eignet sich beispielsweise der mit DOS installierte Primay Bootloader. Damit der DOS-Loader den LILO ausführt, muß die Partition, auf der LILO installiert wurde, die einzige aktive Partition der ersten Festplatte sein. Die primären Partitionen können mit dem Programm fdisk (sowohl unter DOS als auch unter Linux) aktiviert werden. Die erweiterte Partition läßt sich nur mit dem fdisk von Linux aktivieren.
Unabhängig davon, ob LILO als primärer oder sekundärer Bootloader auf der ersten Festplatte oder im Bootsektor einer Diskette installiert wurde, kann der Linux Loader als Bootmanager verschiedene Linux-Systeme und andere Betriebssysteme booten. Beispielsweise kann der Linux Loader DOS booten, indem er den sekundären Bootloader von der DOS-Partition ausführt.
Die Lokalisierung eines geeigneten Platzes für den Linux-Kernel selbst ist weitgehend unabhängig von dem Ort, an dem sich der Linux Loader oder die Partition mit dem Linux-Dateisystem befindet.
Der Linux Loader lädt den Kernel von der Festplatte, indem er die durch ihre Zylinder/Kopf/Sektor-Koordinaten identifizierten Datenblöcke einzeln einliest und in der richtigen Reihenfolge in den Arbeitsspeicher kopiert. Dabei benötigt der Loader keine Information über Partitionen, Dateisysteme, Verzeichnisse oder Dateinamen.
Diese Methode ermöglicht maximale Flexibilität bei der Unterbringung der Kerneldatei: LILO kann Linux von jeder Stelle des Systems laden, die er lesen kann. Leider hat LILO zum Zeitpunkt seiner Arbeit nicht die Gerätetreiber und Dienste von Linux zur Verfügung. Stattdessen muß der Loader mit den Funktionen auskommen, die ihm vom BIOS angeboten werden. Deshalb müssen sich der Kernel und alle sonstigen für das Booten notwendigen Daten in dem für das BIOS sichtbaren Systembereich befinden.
Wie dieser Bereich konkret aussieht, hängt von der verwendeten Hardware ab. In jedem Fall erkennt das BIOS die beiden im CMOS eingetragenen IDE-Festplatten, von denen es aber nur jeweils die ersten 1024 Zylinder lesen kann. Dieser ``Sehfehler'' führt zu der auch bei DOS zu beobachtenden Einschränkung des BIOS-Horizonts auf 504 MB Festplattenplatz.
Die BIOS-Versionen neuerer Motherboards sind manchmal in der Lage, vier IDE-Platten zu erkennen, und sie akzeptieren größere Zylinder. Auf diese Weise können sich zusätzliche Möglichkeiten für die Unterbringung des Linux-Kernels ergeben. Weitere Informationen zu großen IDE-Festplatten finden Sie bei der Kernel-Dokumentation in der Datei /usr/src/linux/Documentation/ide.txt.
SCSI-Hostadapter installieren beim Einschalten des Rechners in der Regel eine BIOS-Erweiterung, die das Booten von SCSI-Festplatten ermöglicht. Ob mehr als zwei dieser Festplatten von der BIOS-Erweiterung angesprochen werden können und wie groß der vom BIOS lesbare Plattenbereich ist, hängt vom Hostadapter ab.
Wenn Sie innerhalb des BIOS-Horizonts keine Linux-Partition anlegen können, bleibt Ihnen noch die Möglichkeit, die Kerneldatei und die zum Booten notwendigen Dateien auf der primären DOS-Partition (Laufwerk C:\) unterzubringen. Dazu müssen Sie die DOS-Partition in das Dateisystem Ihres laufenden Linux-Systems einbinden, das Verzeichnis /boot samt Inhalt an eine geeignete Stelle auf der DOS-Partition verschieben, einen symbolischen Link von /boot zu dem neuen Verzeichnis anlegen und natürlich noch den Kernel auf die DOS-Partition kopieren. Vor dem Aufruf des Map-Installers müssen Sie noch den Eintrag für die Kerneldatei entsprechend ändern.Bitte beachten Sie, daß die Linux-Dateien beim Defragmentieren der DOS-Partition verschoben werden können und danach das Mapping nicht mehr stimmt. Durch Setzen des ``System''-Attributes unter DOS können Sie die Dateien vor dem Verschieben schützen.
Wenn Sie die Konfiguration und Installation von LILO nicht der halbautomatischen Installationsprozedur Ihrer Linux-Distribution überlassen können/wollen, müssen Sie die Konfigurationsdatei /etc/lilo.conf ``von Hand'' erzeugen und anschließend den Map-Installer lilo aufrufen.
Das folgende Beispiel zeigt eine solche Konfigurationsdatei für ein System, bei dem auf der ersten Partition einer IDE-Festplatte (/dev/hda1) MS-DOS und auf der zweiten (primären) Partition (dev/hda2) Linux installiert ist.
boot=/dev/hda1 install=/boot/boot.b map=/boot/map vga=normal prompt timeout=50 image=/vmlinuz label=linux root=/dev/hda2 read-only append="" other=/dev/hda1 label=msdoof table=/dev/hdaIn der Regel sollte es ausreichen, die Bezeichnungen der Partitionen (/dev/hda2, /dev/hda1) sowie den Namen des Kernel-Images dem konkreten System anzupassen.
In dem Beispiel wird LILO als sekundärer Bootloader auf die zweite Partition geschrieben. Diese Partition enthält das Root-Filesystem und ist deshalb zur Aufnahme des Bootloaders geeignet. Voraussetzung für die einwandfreie Funktion dieser Konfiguration ist, daß sich die Partition /dev/hda2 vollständig in dem vom BIOS sichtbaren Bereich bis zum Zylinder Nummer 1024 befindet, daß der Master Boot Record einen primären DOS-Loader enthält und daß die Partition /dev/hda2 die einzige aktive Partition ist.
Eine minimale Änderung der Konfigurationsdatei verwandelt das darin festgelegte Bootkonzept grundlegend: wenn die erste Zeile von boot=/dev/hda2 in boot=/dev/hda verändert wird, wird LILO als primärer Bootloader im Master Boot Record installiert und ersetzt dort den primären DOS-Loader. In dem Beispiel hat diese Änderung keine praktische Konsequenz, trotzdem sollten Sie sich den Unterschied klar machen, damit Sie nicht aus Versehen etwas überschreiben, was Sie eigentlich lieber erhalten wollten.
Um den neuen Bootsektor zu schreiben, müssen Sie den Map-Installer lilo aufrufen:# /sbin/lilo Added linux * Added msdoof # _
Auf diese Weise muß lilo immer aufgerufen werden, wenn ein neues Kernel-Image installiert werden soll oder wenn eine der Dateien aus dem Verzeichnis /boot verändert worden ist. Allein das Überschreiben der alten Kerneldatei durch die neue reicht nicht aus, weil damit nicht sichergestellt ist, daß die neue Kerneldatei exakt die gleichen Datenblöcke auf der Festplatte belegt.
Wenn Sie LILO im Master Boot Record installieren und dabei den primären Bootloader eines anderen Betriebssystems überschreiben, möchten Sie möglicherweise eine Sicherheitskopie des alten Bootsektors behalten. LILO erzeugt automatisch eine solche Kopie unter dem Namen /boot/boot.0300 und kann damit den alten Zustand wieder herstellen.Sie können sich auch eine Sicherungskopie auf Diskette ziehen, mit der Sie einen indirekten Festplattenstart mit dem alten Bootloader durchführen können. Wie Sie so eine ``Bootdiskette'' erzeugen, zeigt das folgende Beispiel:
# dd if=/dev/hda of=/dev/fd0 bs=512 count=1 1+0 records in 1+0 records out # _
Wenn der Eintrag für den VGA-Modus in der Konfigurationsdatei weggelassen wird, startet der Kernel mit dem in der Kerneldatei festgelegten Videomodus. Diese Einstellung läßt sich mit dem Systemprogramm rdev-Kommando verändern.
Da der Treiber für die RAM-Disk nicht obligatorischer Bestandteil des Kernels ist, geht dieser Eintrag ins Leere, wenn der Treiber nicht vorhanden ist.
Sie können mit LILO auch ein anderes Betriebssystem, beispielsweise MS-DOS, booten. Dazu dienen die folgenden zusätzlichen Variablen:
Normalerweise legt lilo vor dem Überschreiben des
Bootsektors eine Sicherheitskopie unter dem Namen
/boot/boot.HHUU an, wobei HH die Hauptgerätenummer,
UU die Untergerätenummer der Festplattenpartition ist, deren
Bootsektor überschrieben wird.
Wenn die Linux-Partition noch funktionsfähig ist, können Sie
den Map-Installer lilo auch zum Entfernen des Bootloaders benutzen,
indem Sie ihn einfach mit der Option `uninstall' (-u) aufrufen und
damit den gesicherten alten Bootsektor zurückschreiben. Wenn Sie
beispielsweise LILO vom Master Boot Record der ersten
IDE-Platte löschen wollen, sieht das Kommando so aus:
# /sbin/lilo -s /boot/boot.0300 -u /dev/hda
LILO version 0.16, Copyright 1992-1995 Werner Almesberger
Reading boot sector from /dev/hda
Reading old boot sector.
Restoring old boot sector.
# _
Die Angabe von -s /boot/boot.0300 kann entfallen, wenn die
Sicherheitskopie wie in dem Beispiel unter dem von lilo
selbst erzeugten Namen abgelegt ist.
lilo restauriert den Bootsektor nicht, wenn die Sicherheitskopie älter ist als der aktuelle Bootloader. Das ist zum Beispiel der Fall, wenn lilo wiederholt aufgerufen wird, um veraltete Kernelversionen durch aktuelle zu ersetzen. Bei diesen Updates wird eine existierende Sicherheitskopie nicht überschrieben. Das ist auch sinnvoll, denn mit der Kopie eines alten Linux Bootloaders können Sie den ``ursprünglichen'' Zustand des Bootsektors nicht wiederherstellen. Wenn Sie die Partitionierung der Festplatte seit der ersten Installation von LILO nicht verändert haben, sollte es keine Probleme mit der Verwendung der ältesten Sicherheitskopie geben. Sie können dann mit der Option -U anstelle von -u die Überprüfung der Zeitmarke verhindern.
Wenn Sie
eine Sicherheitskopie des Bootsektors auf Diskette angelegt haben,
können Sie einfach diese Sicherheitskopie wieder zurückschreiben.
Die Umkehrung des in dem früheren Beispiel gezeigten Sicherungsprozesses sieht
folgendermaßen aus:
# dd if=/dev/fd0 of=/dev/hda bs=512 count=1
1+0 records in
1+0 records out
# _
Vergewissern Sie sich, daß der auf Diskette gespeicherte Bootsektor
tatsächlich noch funktioniert, indem Sie das System mit dieser Bootdiskette
starten.
A:\ >fdisk /mbr A:\ >Das Programm mkboot aus dem XIAFS-Paket bietet eine ähnliche Option.
Linux ist in der Lage, vom Bootloader eine Art Kommandozeile zu übernehmen und diese während des Kernelstarts auszuwerten. Mit den Argumenten auf dieser Kommandozeile können Gerätetreiber eingestellt und verschiedene Kerneloptionen geändert werden. Dieser Mechanismus zur Laufzeitkonfigurierung des Linux-Kernels ist vor allem bei den generischen Kernels auf den Bootdisketten der Linux-Distributionen höchst wertvoll, um einen Rechner mit einer problematischen Hardwarekonfiguration zum Laufen zu bringen.
Mit LILO erhalten Sie die Möglichkeit zur Eingabe einer solchen Kommandozeile, wenn in der LILO-Konfigurationsdatei das Schlüsselwort prompt eingetragen ist oder wenn Sie beim Booten eine der Tasten ALT, CONTROL oder SHIFT gedrückt halten.
Vor dem Laden des Kernels erscheint dann der typische LILO Bootprompt und signalisiert, daß der Loader auf die Kommandozeile wartet.
boot: _
Da LILO auch als Bootmanager arbeitet, erwartet er als erstes Argument auf der Kommandozeile das Label des Betriebssystems, das geladen werden soll. Eine Liste mit allen Labeln erhalten Sie, nachdem Sie die Tabulatortaste TAB gedrückt haben. In der oben besprochenen Beispielkonfiguration für LILO sind das linux und msdoof.
Im Anschluß an das Label können Sie beliebig viele Argumente für den Kernel übergeben, die Sie jeweils durch Leerzeichen voneinander trennen müssen. Diese Argumente werden unverändert an den Kernel weitergegeben, der seinerseits einige Parameter an die Programme des Laufzeitsystems übergeben kann.
Eine erste Gruppe von Argumenten überlagert die im Kernel-Makefile bzw. mit dem Systemprogramm rdev eingestellten Parameter.
Eine andere Gruppe von Argumenten dient der Konfiguration bestimmter Gerätetreiber. Wenn eines dieser Argumente auf der Kommandozeile auftaucht, wird die Setup-Funktion für den entsprechenden Gerätetreiber mit den hier angegebenen Parametern anstelle der in den Kernelsourcen festgelegten Vorgaben aufgerufen. Bei sehr vielen Treibern von Hardware-Controllern können die Werte für den Interrupt (IRQ) und die Speicheradresse für den Anfang des IO-Ports angegeben werden. Auf diese Weise lassen sich vom Standard abweichende Einstellungen konfigurieren und Hardwarekonflikte umgehen. Die Speicheradressen müssen immer als Hexadezimalzahlen mit dem Präfix 0x angegeben werden.
Bei vielen Distributionen werden zur Installation des Betriebssystems generische Kernel benutzt, die in der Regel überflüssige Treiber enthalten. Wenn es beim Laden eines solchen Kernels zu Problemen mit einem Treiber für ein nicht vorhandenes Gerät kommt, können Sie diesen Treiber meistens abschalten, indem Sie als Argument für den entsprechenden Bootparameter einfach nur die Zahl 0 angeben.
Diese Reservierung ist beispielsweise für den IO-Bereich der NE2000-Ethernet-Karten sinnvoll, die nach einem unkontrollierten Zugriff durch einen wilden Gerätetreiber den Rechner blockieren können. Wenn Sie einen 32 Byte großen Adressbereich von hexadezimal 0x280 bis 0x29f für die Netzwerkkarte (hier mit IRQ 10) reservieren wollen, lautet das Kommandozeilenargument reserve=0x280,32 ether=10,0x280,0,0,eth0.
Die Angabe der Speichergröße kann in Bytes, Kilobytes und Megabytes erfolgen. Die Einheiten müssen gegebenenfalls durch den nachgestellten Buchstaben k bzw. M gekennzeichnet werden.
Die folgenden Kommandozeilenargumente schalten bestimmte Kernelfunktionen an bzw. ab:
Anstelle des Tripels Zylinder,Kopf,Sektoren kann auch eines der Schlüsselwörter none, noprobe, nowerr, cdrom, autotune oder noautotune angegeben werden. Mit none und noprobe können einzelne Laufwerke vom Autoprobing ausgeschlossen werden. Mit cdrom wird ein ATAPI-CD-Laufwerk angezeigt. Durch die Schlüsselwörter autotune und noautotune kann der Treiber dazu veranlaßt werden, zusätzliche oder auch weniger Anstrengungen zur Performanceoptimierung zu unternehmen.
Andere SCSI-Controller können mit weiteren Kommandozeilenargumenten konfiguriert werden:
Die Option extended schaltet die ``Übersetzung'' der Geometriedaten von Platten mit mehr als 1024 Zylindern ein. Mit no_reset wird das einige Sekunden dauernde Zurücksetzen des SCSI-Bus beim Booten unterdrückt.
Bitte beachten Sie, daß der Parallelport, an dem das ZIP-Drive angeschlossen wird, nicht gleichzeitig als Druckerport konfiguriert werden darf. Um den Druckertreiber auszuschalten, können Sie zusätzlich folgenden Bootparameter angeben: lp=0
Bei allen Treibern für eigenständige CD-ROM-Laufwerke kann mindestens der IO-Port durch ein Kommandozeilenargument auf dem Bootprompt eingestellt werden, bei weiteren Laufwerken ist zusätzlich noch der IRQ einstellbar. Die Form des Arguments laufwerk=IO-Port[,IRQ]. Treiber der einfachsten Form (nur IO-Port) sind: Sanyo (sjcd), Optics Storage (optcd) und GoldStar (gscd). Die zweite Form (mit IRQ) verstehen: Mitsumi (neu) (mcdx), Phillips CM206 (cm206) und Sony CDU535 (sonycd535).
Die anderen CD-Treiber verstehen zusätzliche Bootparameter:
Wenn Sie kein CD-Laufwerk dieses Typs eingebaut haben, können Sie die sehr zeitaufwendigen Initialisierungsversuche des Treibers umgehen, indem Sie als Bootargument sbpcd=off angeben.
Den Treibern für die Logitech-Busmaus und die Microsoft-Busmaus kann mit den Schlüsselwörtern bmouse (Logitech) und msmouse (Microsoft) jeweils der passene Hardware-Interrupt mitgeteilt werden.
Die Bezeichnung für das Device wird im Normalfall ``eth0'' sein. Da der Kernel nach erfolgreicher Inititalisierung einer Netzwerkkarte die Suche nach weitern Karten aufgibt, kann nur durch explizite Beschreibung auf dem Bootprompt eine weiter Netzwerkkarte aktiviert werden.
Außer den hier aufgeführten Argumenten können noch weitere Optionen (Schalter) angegeben werden, die der Kernel an das init-Programm weiterreicht. Beispielsweise verstehen alle init Programme das Argument single als Befehl, das System im Einbenutzermodus zu starten.Darüberhinaus können Gleichungen zur Definition von Umgebungsvariablen angegeben werden, die automatisch in der Prozeßumgebung aller laufenden Programme auftauchen.
Die Möglichkeiten für die Systemverwalterin, in dieser Phase in das Geschehen einzugreifen, sind minimal. Trotzdem werden die einzelnen Schritte hier einmal vorgestellt, damit Sie bei eventuell auftretenden Problemen den Fehler etwas besser eingrenzen können.
Zuerst werden einige interne Funktionen und Tabellen des Kernels initialisiert. Dazu gehören die Tabelle zur Speicherseitenverwaltung, die Belegung der Fehlerinterrupts und der IRQ, die Einrichtung der Prozeßtabelle und der Start der Schedulers. In dieser Phase wird auch die CMOS-Uhr ausgelesen und die Systemzeit entsprechend gesetzt. Wenn der Arbeitsspeicher Ihres Rechners ohne Fehler ist, sollte es hierbei keine Probleme geben. Es findet noch keine Bildschirmausgabe statt.Dann wird die Kommandozeile des Kernels ausgewertet und die für den Kernel bestimmten Kommandozeilenargumente an die entsprechenden Setup-Funktionen übergeben. Später werden die in Kernel-Variablen gespeicherten Argumente bei der Initialisierung der Gerätetreiber verwendet. Die von der aktuellen Linux-Version unterstützten Kommandozeilenargumente sind im Abschnitt über den Bootprompt erklärt.
Damit alle weiteren Schritte auf dem Bildschirm verfolgt werden können, wird als nächstes die Systemconsole eingerichtet. Wenn für den Textbildschirm kein fester Video-Modus eingestellt wurde, wird an dieser Stelle eine Liste aller von der Grafikkarte unterstützten Modi ausgegeben und auf eine Auswahl gewartet.Bei Geräten mit PCI-Bus wird als nächstes das PCI-Subsystem initialisiert. Dabei wird das PCI-BIOS aktiviert und der Bus nach Geräten abgesucht.
Danach wird die Geschwindigkeit des Rechners ermittelt und der Timer calibriert. Die angezeigten BogoMIPS sind kein Benchmark und zum Vergleich der Rechnerleistung wenig geeignet.
Die Initialisierung des virtuellen Filesystems im Kernel findet normalerweise ``im Stillen'' statt, so daß die nächste Bildschirmausgabe das Resultat der Speicherinitialisierung ist. Der Kernel zeigt hier normalerweise an, wieviel Arbeitsspeicher installiert ist und wieviel davon bereits vom Kernel belegt wurde.
Nach dem Speicher werden die geräteunabhängigen Netzwerkschichten initialisiert. Unter anderem werden auf dem Bildschirm die unterstützten IP-Protokolle angezeigt.
Im nächsten Schritt wird der Prozessor auf bekannte Fehler geprüft. Je nach Rechnerarchitektur und Prozessortyp können hier die Ergebnisse verschiedener Tests auf dem Bildschirm erscheinen.
Intel x86 | TLB | Wenn ein Kernel, der für Intel-Prozessoren 486 und höher übersetzt wurde, auf einem 386er Prozessor gestartet wird, kommt es zu einer Fehlermeldung und der Systemstart wird abgebrochen. Das Problem wird beseitigt, indem ein für den 386er Prozessor geeigneter Kernel geladen wird. |
HLT | Bei fehlerhaften Prozessoren kann es durch einen ``Halt''-Befehl zum Einfrieren des Systems kommen. Wenn es bei diesem Test zu Systemstillstand kommt, hat Ihr Prozessor diesen Fehler. Das Problem wird umgangen, indem der Kernel mit der Kommandozeilenoption no-hlt neu gestartet wird. | |
FPU | Wenn der Rechner keinen mathematischen Koprozessor hat und der Kernel ohne FPU-Emulation übersetzt wurde, kommt es zu einer Fehlermeldung und der Systemstart wird abgebrochen. Das Problem wird beseitigt, indem ein anderer Kernel mit FPU-Emulation geladen wird. Bei älteren 386/387 Kombinationen teilt die FPU der CPU einen Fehler über den IRQ13 mit. Linux kann diesen Spezialfall erkennen und sich darauf einstellen. Im Normalfall löst ein Fehler die ``exception 16'' aus. Bei Pentium-Prozessoren hat die Entdeckung eines Fehlers in der FPU für einiges Aufsehen gesorgt. Linux kann diesen Fehler (FDIV Bug) erkennen und umgehen. | |
MIPS | WAIT | Bei diesem Test wird festgestellt, ob der Prozessor die Instruktion ``wait'' versteht. |
ALPHA | -- | Zur Zeit sind keine Bugs des ALPHA-Prozessors bekannt. |
68k | -- | Es gibt keine Fehlerbehandlung für Prozessoren dieses Typs. |
SPARC | -- | Es gibt keine Fehlerbehandlung für Prozessoren dieses Typs. |
PowerPC | -- | Es gibt keine Fehlerbehandlung für Prozessoren dieses Typs. |
Nach dem Prozessortest wird als letzter Schritt in der zweiten Phase der Systemininitialisierung der ``Linux-Banner'' ausgegeben, in dem die Versionsnummer und das Übersetzungsdatum des Kernels angezeigt werden.
Die dritte Phase der Initialisierung beginnt, indem der Kernel einen ``Kernel-Thread'' mit dem Namen init erzeugt. Ein Kernel-Thread ist eine Kernelfunktion, die bereits vom Scheduler verwaltet wird wie ein Prozeß, sich aber den Speicherbereich mit den anderen Kernelfunktionen teilt.init erzeugt zunächst zwei weitere Kernel-Threads, bdflush und kswapd, die den Kernel bei der Verwaltung des virtuellen Speichers und des Buffer-Cache unterstützen. Danach wird der Systemcall setup ausgeführt, der für die Initialisierung der Gerätetreiber, des Programmladers und der Dateisysteme verantwortlich ist.
Die Kernelfunktion setup ruft einen Gerätetreiber nach dem anderen auf und veranlaßt ihn, nach ``seinem'' Gerät zu suchen, es zu initialisieren und sich nach einer erfolgreichen Initialisierung im Kernel zu registrieren. Manche Gerätetreiber geben genaue Statusinformationen und schreiben eine Erfolgsmeldung auf den Bildschirm. In der Tabelle 5.2 sind diese Gerätetreiber mit dem Buchstaben E wie ``Erfolg'' gekennzeichnet. Die meisten Gerätetreiber geben wenigstens eine Fehlermeldung aus, wenn etwas bei der Initialisierung schiefgegangen ist. Diese Treiber sind mit einem F wie ``Fehler'' gekennzeichnet. Treiber, die weder mit E noch mit F gekennzeichnet sind, arbeiten völlig stumm.Es sind nicht in jedem Kernel alle möglichen Gerätetreiber enthalten. Viele Treiber werden nur benötigt, wenn die entsprechende Hardware installiert ist. Solche Treiber sind ``optional'', sie werden bei der Konfigurierung des Kernels vor dem Übersetzen der Sourcen angeboten und können ausgewählt oder auch weggelassen werden. Die meisten dieser optionalen Treiber können auch zu einem Modul gemacht werden, das nicht dauerhafter Bestandteil des Kernels ist, sondern bei Bedarf zum laufenden Betriebssystem hinzugeladen werden kann. Optionale Treiber, die zu einem Kernelmodul gemacht werden können, sind in der Tabelle mit einem M gekennzeichnet, die anderen mit einem O wie ``Option''.
Die Tabelle listet alle in den Sourcen enthaltenen Treiber in der Reihenfolge ihrer Initialisierung auf. Wenn es beim Starten des Systems zu Fehlern kommt oder wenn Ihre Hardware nicht korrekt erkannt wird, kann Ihnen diese Information bei der Eingrenzung des Problems helfen.
Um das Problem zu beheben, können Sie häufig durch Kommandozeilenoptionen, die dem Kernel vor dem Laden mit dem Bootprompt übergeben werden, Einfluß auf den oder die problematischen Treiber nehmen. In der dritten Spalte der Tabelle ist zu allen Gerätetreibern, die mit einem Bootparameter von der Kernelkommandozeile beeinflußt werden können, das Kommandozeilenargument in Kurzform dargestellt. Sie finden eine ausführliche Beschreibung im Abschnitt über die Bootparameter.
3|c|Zeichenorientierte Geräte | ||
Zufallszahlengenerator | -- | |
Tastatur | F | |
Serielle Schnittstellen | EFM | |
Z8530 basierte HDLC Karte (SCC) | EFM | |
Cyclades Multiport | EFM | |
Stallion Multiport | EFM | |
Stallion ``intelligenter'' Multiport | EFM | |
DigiBoard PC/Xe Multiport | EFO | digi= |
RISCom/8 Multiport | EFM | riscom8=IO-Port |
Baycom Funkmodems | EFM | baycom=Modem,IO-Port,IRQ,DCD |
Pseudoterminals | F | |
Virtuelle Console Screen | F | |
Drucker | EFM | lp=IO-Port,IRQ |
Logitech Busmaus | EM | bmouse=IRQ |
PS/2 Busmaus | EFM | |
Microsoft BusMouse | EM | msmouse=IRQ |
ATI Busmaus | EM | |
Watchdog Timer | EFM | |
Advanced Power Management | EFO | |
Echtzeituhr | EFO | |
Soundkarte | EFM | sound=0xTaaaId |
QIC-02 Tape | EFO | |
ISDN Subsystem | EFM | |
ICN ISDN Karte | EFM | icn=IO-Port,SharedMem |
Teles ISDN Karte | EFM | teles=IO-Port,IRQ,SharedMem,Prot |
PCBIT ISDN Karte | EFM | pcbit=IO-Port,IRQ |
Ftape | EFM | |
3|c|Blockorientierte Geräte | ||
Ram-Disk | EFM | ramdisk_size=Größe |
Loop Filesystem Driver | EFM | |
ISP-16 CD | EFM | isp16=IO-Port,IRQ,DMA,Typ |
IDE-Interface | EFO | idex=Optionen |
IDE-Geräte | EFO | hdx=Optionen |
IDE/MFM/RLL Festplatten | FO | hd=Cyl,Head,Sec |
XT-Festplatten | FM | xd=Typ,IRQ,IO-Port,DMA |
Diskettenlaufwerke | EFM | floppy=Optionen |
Sony CDU-31A | EFM | cdu31a=IO-Port,IRQ[,Typ] |
Mitsumi CD | EFM | mcd=IO-Port,IRQ,Wait |
Mitsumi Multisession | EFM | mcdx=IO-Port,IRQ |
SBP CD | EFM | sbpcd=IO-Port,Typ |
Aztech CD | EFM | aztcd=IO-Port,Maggi |
Sony CDU-535 | EFM | sonycd535=IO-Port,IRQ |
GoldStar | EFM | gscd=IO-Port |
Phillips CM206 | EFM | cm206=IO-Port,IRQ |
Optics Storage | EFM | optcd=IO-Port |
Sanyo CD | EFM | sjcd=IO-Port |
Multiple Device | EFM | |
3|c|SCSI Komponenten | ||
Amiga 3000 | EFM | |
Commodore A2091 | EFM | |
GVP Serie II | EFM | |
Atari Native | EFO | |
AdvanSys | EFM | advansys=IO-Port |
BusLogic | EFM | BusLogic=Optionen |
UltraStor 14F/34F | EFM | |
UltraStor 14F | EFM | |
Adaptec AHA152x | EFM | aha152x=Port,IRQ,ID,Recon,Par |
Adaptec AHA1542 | EFM | aha1542=Port,BusOn,BusOff,Rate |
Adaptec AHA1740 | EFM | |
Adaptec AIC7xxx | EFM | aic7xxx=extended,no_reset |
Future Domain 16x0 | fdomain=IO-Port,IRQ,Adapter-ID | |
Always IN2000 | EFM | in2000=Optionen |
NCR5380 Generic | EFM | ncr5380=IO-Port,IRQ,DMA |
NCR53c400 | EFM | ncr53c400=IO-Port,IRQ |
NCR53c406a | EFM | ncr53c406a=IO-Port,IRQ,Fast-PIO |
Qlogic FAS408 | EFM | |
Pro Audio Spectrum | EFM | pas16=IO-Port,IRQ |
Seagate ST0x | EFM | st0x=IO-Port,IRQ |
Future Domain TMC-885, TMC-950 | EFM | tmc8xx=IO-Port,IRQ |
Trantor T128 | EFM | t128=Memory,IRQ |
DTC 3180/3280 | EFM | (dtc=Memory,IRQ) |
NCR 53C700/53C700-66 | EFM | |
NCR 53C810 | EFM | |
EATA HBA | EFM | |
EATA PIO | EFM | |
Western Digital WD-7000 | EFM | wd7000=IRQ,DMA |
EATA/DMA 2.0x | EFM | |
AM53C974 | EFM | AM53C974=Host,Targ,Rate,Offset |
QLogic ISP1020 | EFM | |
Iomega ZIP (Parallel Port) | EFM | ppa=IO-Port,High,Low,N1,N2 |
Gerätescan | max_scsi_luns=Anzahl | |
SCSI Tape | EFM | st=Buffer,Schwelle,MaxBuf |
3|c|Netzwerk | ||
Ethernetkarten | EFM | ether=IRQ,IO-Port,MemStart,MemEnd |
Nachdem alle erkannten Geräte beim Kernel angemeldet sind, werden die Partitionen und die Größe der Festplatten geprüft, eventuell vorgesehene RAM-Disks in den Speicher gelesen, die Kernelfunktionen zum Laden der verschiedenen Binärformate vorbereitet und schließlich die unterstützten Dateisysteme registriert und das Rootfilesystem gemountet.
An dieser Stelle ist die dritte Phase der Systeminitialisierung abgeschlossen. Das Betriebssystem hat die Kontrolle über die Komponenten und Geräte des Systems und ist bereit, Arbeitsprozesse in einem jeweils eigenen ``Userspace'' zu starten.Wenn der Kernel den Treiber für die RAM-Disks enthält, werden bei der Initialisierung der Blockgeräte die Verwaltungsstrukturen für 16 dieser ``Geräte'' angelegt. Wenn mit dem Bootprompt keine andere Größe eingestellt wurde, kann jede dieser RAM-Disks bis zu 4MB groß werden. Der Arbeitsspeicher wird nicht bei der Initialisierung, sondern erst beim Beschreiben der RAM-Disk belegt.
Wenn eine RAM-Disk nach Abschluß der dritten Phase des Bootvorgangs von einer Floppy in den Speicher geladen werden soll, müssen dem Kernel die Details der RAM-Disk über Kommandozeilenargumente auf dem Bootprompt mitgeteilt werden.
Die Werte für load_ramdisk, prompt_ramdisk und ramdisk_start können durch das Systemprogramm rdev auch fest in das Kernelimage eingetragen werden.
Ein kurzes Beispiel soll die Erzeugung einer RAM-Disk und einer Bootdiskette zum Laden derselben zeigen:
[01] # dd if=/dev/zero of=/dev/ram bs=1k count=2048 [02] # mke2fs -m0 /dev/ram 2048 [03] # mount /dev/ram /mnt/ramdisk [04] # cp -a /tmp/myramdisk/* /mnt/ramdisk [05] # umount /mnt/ramdisk [06] # dd if=/dev/ram bs=1k count=2048 | gzip -v9 > /tmp/ram_image.gz [07] # dd if=/vmlinuz of=/dev/fd0 bs=1k [08] # dd if=/tmp/ram_image.gz of=/dev/fd0 bs=1k seek=500 [09] # rdev /dev/fd0 /dev/fd0 [10] # rdev -r /dev/fd0 16884 [11] # _
Durch das erste Kommando werden 2048 Nullbytes in die RAM-Disk geschrieben und dadurch 2MB aus dem Buffercache belegt. Dieser Speicherbereich gehört von nun an der RAM-Disk. Im zweiten Kommando wird in der neuen RAM-Disk ein Dateisystem angelegt. Die Kommandos 3-5 dienen dazu, die RAM-Disk mit sinnvollen Daten zu füllen. Im 6. Kommando wird das Image der RAM-Disk auf Festplatte geschrieben und gleichzeitig komprimiert. Dann wird der Kernel auf die Diskette kopiert und anschließend das komprimierte Image der RAM-Disk dahinter geschrieben. Die letzten beiden Kommandos veranlassen den Kernel, die RAM-Disk aus dem Block 500 zu laden und als Rootfilesystem zu mounten. Natürlich darf der Kernel nicht größer als 500kB und das Image der RAM-Disk maximal 940kB groß sein, damit dieses Beispiel funktioniert.
Speziell für die Konstrukteure der mehr oder weniger genialen Installationsprozeduren der verschiedenen Linux-Distributionen gibt es die Möglichkeit, eine sogenannte Init-RAM-Disk (initrd) zu laden. Die wird gegebenenfalls nach erfolgreichem Setup noch vor dem eigentlichen Root-Filesystem gemountet und ein darauf befindliches Programm oder Shellscript ``linuxrc'' abgearbeitet. Dieses Programm läuft im Userspace und kann zum Beispiel dafür sorgen, daß die passenden Kernelmodule für bestimmte Komponenten wie CD-ROM oder SCSI-Host nachgeladen werden.Wenn das Programm auf der Initrd beendet ist, wird das ``richtige'' Root-Filesystem gemountet und die Init-RAM-Disk auf das Verzeichnis /initrd verschoben.
Genauere Informationen zur Verwendung der Initrd finden Sie bei den Kernelsourcen in der Datei ./linux/Documentation/initrd.txt.
Wenn die Setup-Phase der Systeminitialisierung abgeschlossen ist und eventuell notwendige Treiber von der Initrd nachgeladen wurden, hat der Kernel schließlich eine feste Verbindung zu einem Dateisystem (Rootfilesystem) und kann von dort Programmdateien laden und ausführen.
Die vierte und letzte Phase der Systeminitialisierung beginnt, wenn der zunächst im Kernelspeicher gebliebene init-Thread die Programmdatei /sbin/init in den Arbeitsspeicher lädt und ausführt. Durch diesen Vorgang wird der erste Prozeß im Userspace erzeugt. Der Prozeß unterscheidet sich vom Thread dadurch, daß er einen eigenen virtuellen Adressraum benutzt, der einen vom Kernelspeicher verschiedenen Bereich des Arbeitsspeichers belegt. Der Prozeß init ist verantwortlich für die Entstehung aller weiteren Prozesse. Außerdem sorgt init für eine gewisse Minimalausstattung der Arbeitsumgebung.
Typischerweise führt init zu Beginn seiner Laufzeit ein oder mehrere Shellprogramme (Batchdateien) aus. Dadurch werden, ähnlich wie mit autoexec.bat bei DOS, bestimmte Einstellungen automatisch vorgenommen. Die Multitaskingfähigkeit von Linux ermöglicht auch den Start von parallel laufenden Serviceprogrammen, sogenannten Dämonen, die dem Systembenutzer jederzeit ihre Dienste anbieten.
Es ist charakteristisch für den Prozeß init, daß er nicht beendet wird. Auf diese Weise sorgt init dafür, daß bestimmte Prozeduren, vor allem das Login auf den virtuellen oder realen Terminals, in immer neuen Zyklen gestartet werden.
Für Linux sind zwei sehr verschiedene Versionen von init verbreitet:Das einfache init (simpleinit) von Peter Orbaek mit Erweiterung von Werner Almesberger beschränkt sich auf die wesentlichen Aufgaben: es wird ein einziges Shellscript, die Datei /etc/rc, der Standardshell zur Interpretation übergeben, und es werden die in der Datei /etc/inittab bestimmten virtuellen Terminals und seriellen Schnittstellen mit einem getty-Prozeß belegt. Für spezielle Situationen kann das simpleinit im Einbenutzermodus (single user mode) gestartet werden. In diesem Modus wird das Initialisierungsscript nicht interpretiert, und es wird nur eine einzige Shell mit Root-Rechten gestartet.
Immer häufiger wird das vielseitigere System-V-kompatible sysvinit von Mike Jagdis und Miquel van Smoorenburg installiert. Mit sysvinit können zu den beiden Systemzuständen ``Singleuser'' und ``Multiuser'' noch feinere Unterteilungen in sogenannte Runlevel vorgenommen werden. Wie beim simpleinit werden auch vom sysvinit die in der inittab bestimmten Login-Prozeduren gestartet und zusätzlich verschiedene Programme oder Shellcripts zur Initialisierung der Runlevel abgearbeitet.
Wenn Sie nicht sicher sind, welches init bei Ihrem Linux-System installiert ist, können Sie die Textdatei /etc/inittab mit den Beispielen aus dem nächsten Abschnitt vergleichen und damit Ihr init einer der beiden Versionen zuordnen.
Ein grober Fehler in der inittab kann dazu führen, daß die Systeminitalisierung hängen bleibt und kein Login möglich ist. In solch einem Fall können Sie sich helfen, indem Sie beim LILO-Bootprompt die Kommandozeilenoption init=/bin/sh angeben. Auf diese Weise wird die Shell anstelle von init geladen und Sie haben die Möglichkeit, das System zu reparieren.
Beim simpleinit wird in der inittab nur festgelegt, auf welchen Terminals und mit welchen Parametern ein getty gestartet wird, um dort ein Login zu ermöglichen. Die Einträge in der inittab für simpleinit bestehen aus drei Feldern, die durch Doppelpunkte getrennt werden:Terminal:Termcapeintrag:Gettykommando
Der erste Eintrag bezeichnet das Terminal (tty1, tty2, ttyS1 ...), wie es in die /var/run/utmp Datenbank eingetragen und wie es vom who Kommando angezeigt wird. Der zweite Eintrag wird automatisch in die TERM Umgebungsvariable der auf dem entsprechenden Terminal gestarteten Shell geschrieben und sollte deshalb mit einem Eintrag in der /etc/termcap Datei übereinstimmen.
Der dritte Eintrag schließlich ist die Kommandozeile, mit der das getty-Kommando für das Terminal aufgerufen werden muß. Da es auch vom getty-Programm verschiedene Versionen gibt, sollte das entsprechende Format am besten der Beschreibung dieses getty entnommen werden.
# Beispiel einer inittab fuer simpleinit. # Format: tty-Port:termcap-Eintrag:getty-Kommando # # Die ersten fuenf Zeilen sind fuer die virtuellen Terminals... # tty1:linux:/sbin/getty 9600 tty1 tty2:console:/sbin/getty 9600 tty2 tty3:console:/sbin/getty 9600 tty3 tty4:console:/sbin/getty 9600 tty4 #tty5:con100x40:/sbin/getty 9600 tty5 # # ...die letzte Zeile ist fuer den Modem-Port. # ttyS1:vt102:/sbin/getty 9600 ttyS1
Das Verfahren, mit dem simpleinit die Kommandos aus der inittab bearbeitet, entspricht ungefähr der Methode respawn vom sysvinit.
Das System-V-kompatible init (sysvinit) hat auch vor allem die Aufgabe, die gettys für die Login-Prozeduren zu erzeugen und immer neu zu starten. Die Verwaltung zusätzlicher Runlevel erfordert zusätzliche Einträge mit einer anderen Syntax in der inittab. Jede Zeile, die nicht mit einem `#' (Kommentar) beginnt, ist ein Datensatz mit vier durch Doppelpunkt voneinander getrennten Einträgen:ID:Runlevel:Aktion:Prozeß
Der erste Eintrag ist eine vierstellige Zeichenkette als Bezeichner für die Zeile. Die ID wird bei Einträgen in Logfiles und bei Fehlermeldungen ausgegeben.
Für die Einträge, mit denen Login-Prozeduren auf den Terminals gestartet werden sollen, sollte die ID mit der charakteristischen Namensendung der entsprechenden Gerätedatei übereinstimmen, damit beim Accounting die Daten korrekt ausgewertet werden können. Beispielsweise soll die ID S1 für ein getty auf ttyS1 verwendet werden.
Im zweiten Eintrag werden die Runlevel festgelegt, in denen die entsprechende Zeile ausgewertet werden soll. Die Runlevel werden mit Ziffern von 0 bis 9 und mit den Buchstaben A, B, C, Q oder S (ohne Unterscheidung zwischen Groß und Kleinschreibung) bezeichnet. Einer Zeile können bis zu 11 Runlevel zugeordnet werden. Bei den Buchstabenkennungen für die Level steht S für den Einbenutzermodus, Q für Quit zum Neueinlesen der inittab. Die anderen Buchstaben werden für ondemand Aufrufe verwendet, bei denen ein Kommando beim Moduswechsel nicht mehr abgebrochen wird.Wenn das Feld für den Runlevel leer ist, wird die Aktion bei jedem Moduswechsel ausgeführt.
Im dritten Eintrag wird bestimmt, welche Aktion von init ausgeführt wird:
# Beispiel einer inittab fuer sysvinit # Format: ID:Runlevel:Aktion:Kommando # Einmalige Systeminitialisierung noch vor dem Einbenutzermodus: si::sysinit:/etc/rc.d/rc.sysinit # Der Eintrag fuer den Einbenutzermodus: ~~:S:wait:/sbin/sulogin # Der Default-Runlevel: id:2:initdefault: # Einmalige Vorbereitung des Mehrbenutzermodus durch eine Batchdatei: bo::bootwait:/etc/rc.d/rc.boot # Bei jedem Wechsel in einen Runlevel 2 bis 5 wird das Shellscript # /etc/rc.d/rc aufgerufen, um die weitere Arbeit zu erledigen: l2:2:wait:/etc/rc.d/rc 2 l3:3:wait:/etc/rc.d/rc 3 l4:4:wait:/etc/rc.d/rc 4 l5:5:wait:/etc/rc.d/rc 5 # Der "Affengriff" fuer den Warmstart: ca:12345:ctrlaltdel:/sbin/shutdown -t1 -r now # Schließlich die Login-Prozeduren: 1:2345:respawn:/sbin/getty 9600 tty1 2:23:respawn:/sbin/getty 9600 tty2 3:23:respawn:/sbin/getty 9600 tty3 4:23:respawn:/sbin/getty 9600 tty4
Bei der Verarbeitung der inittab geht sysvinit folgendermaßen vor:
Wenn das letzte Kommando im Einbenutzermodus beendet ist, fährt sysvinit mit dem Booten eines Mehrbenutzermodus fort.
Das Script wird von init in der folgenden Form aufgerufen:
/etc/initscript ID Runlevel Aktion Kommando
Auf die Argumente kann in dem Shellscript über die Positionsparameter zugegriffen werden.
Ein kurzes Beispiel zeigt, wie das eigentliche Kommando aus dem initscript gestartet wird:
# Beispiel fuer /etc/initscript # Zuerst werden die gewuenschten Einstellungen vorgenommen,... umask 022 ulimit -S -m 2048 -c 4096 # ...danach wird das eigentliche Kommando ausgefuehrt. eval exec "$4"
Um sich die gleiche Arbeit beim nächsten Systemstart zu sparen, können Sie die Kommandos, die Sie zur Herstellung Ihrer Arbeitsumgebung eingeben müssen, in eine Datei schreiben. Indem Sie diese Datei zu Beginn jeder Session als Shellscript ausführen, erzeugen Sie nach jedem Systemstart das gewohnte Anfangsbild.
simpleinit führt genau ein solches Shellscript automatisch beim Start in den Mehrbenutzermodus aus: die Datei /etc/rc. Der Name rc kommt von run command (runcom). Die Rolle dieser Datei ist vergleichbar mit der AUTOEXEC.BAT bei DOS.# Beispiel einer /etc/rc fuer simpleinit # Das Root-Filesystem ist Read-Only gemountet. # Zuerst werden die Dateisysteme getestet... /sbin/fsck -A -a if [ $? -gt 1 ] ; then echo "Fehler im Dateisystem gefunden. Bitte neu booten!" /bin/sh fi # ...dann wird das Root-Filesystem mit Schreiberlaubnis remountet. /sbin/mount -n -o rw,remount / # Hier werden zur Sicherheit ein paar Dateien entfernt. /bin/rm -f /etc/mtab* /var/lock/LCK* /var/run/* /bin/cat /dev/null > /etc/utmp # Hier wird der Rest des Dateisystems ohne das NFS gemountet # und die Swappartition aktiviert. /sbin/mount -avt nonfs /sbin/swapon -a # Einige Daemonen werden gestartet. /usr/sbin/crond /usr/sbin/lpd # Der update Daemon muss unbedingt im rc-Script gestartet werden. /sbin/update & # Die Tastaturtabelle wird geladen. /sbin/loadkeys /etc/keytables/de-latin1.map # Schliesslich wird noch das lokale Initialisierungscript aufgerufen. /bin/sh /etc/rc.local
Das Beispiel zeigt nur ein paar wichtige Kommandos, die typischerweise nach jedem Systemstart ausgeführt werden. Wie in der letzten Zeile gezeigt, können weitere Initialisierungsscripts aus der /etc/rc heraus aufgerufen werden. Charakteristisch für den Ablauf der Systeminitialisierung mit simpleinit ist der lineare Ablauf: die Scriptdateien werden jedesmal beim Start des Mehrbenutzermodus von Anfang bis Ende durchgearbeitet.
Beim sysvinit gibt es wegen der Unterstützung mehrerer Runlevel wesentlich mehr Möglichkeiten für die Systeminitialisierung. Jeder Runlevel zeichnet sich durch eine bestimmte Laufzeitumgebung aus. Beim Wechsel zwischen den Levels müssen einige Komponenten neu hinzugefügt, andere wieder aus der Umgebung gelöscht werden.Die Programme oder Shellscripte, die dieses vielschichtige System zur Initialisierung der Runlevel realisieren, werden von der inittab aus aufgerufen, wie es in dem Beispiel oben dargestellt wurde.
Bei den Aktionen sysinit und boot werden einfache Scriptdateien ausgeführt, die eine gemeinsame Systemgrundlage für alle Multiuser-Runlevel schaffen. Diese Shellscripts unterscheiden sich im Prinzip nicht von der oben vorgestellten Datei /etc/rc für simpleinit.
Die weitere Initialisierung der einzelnen Runlevel erfordert mehr Flexibilität. Die mit den Sourcen vom sysvinit ausgelieferten Initialisierungsscripts für die Multiuserlevel arbeiten mit einem Satz hochspezialisierter kleiner Shellscripts, die jeweils für das Hinzufügen oder Löschen einer einzelnen Komponente der Laufzeitumgebung verantwortlich sind. Diese Miniscripts werden nach Bedarf beim Wechsel der Runlevel vom Shellscript /etc/rc.d/rc aus mit den Argumenten start oder stop aufgerufen.
Für jeden Runlevel wird eine bestimmte Teilmenge der Miniscripts zum Starten einer Komponente genutzt, alle anderen werden mit dem Argument stop ausgeführt. Auf diese Weise hat jeder Runlevel seine charakteristische Ausstattung, egal von welchem Level aus dorthin gewechselt wurde.
Um die Komponenten den Runlevels zuzuordnen, benutzt das Shellscript /etc/rc.d/rc von sysvinit eine Verzeichnishierarchie unter /etc/rc.d mit einem eigenen Unterverzeichnis für jeden Runlevel. Zu Runlevel 1 gehört das Verzeichnis /etc/rc.d/rc1.d, zu Level 2 das Verzeichnis /etc/rc.d/rc2.d und so weiter.
Ein rekursives Listing von /etc/rc.d kann beispielsweise so aussehen:
[root@atlantis /root]# ls -RF /etc/rc.d/ init.d/ rc.local* rc.sysinit* rc1.d/ rc* rc.modules* rc0.d/ rc2.d/ /etc/rc.d/init.d: funktionen rc.ibcs* rc.local* rc.nfsfs* rc.cfsfs* rc.inet* rc.lpd* rc.pcmcia* rc.cron* rc.isdn* rc.network* rc.sendmail* rc.down* rc.keytable* rc.nfs* rc.syslog* /etc/rc.d/rc0.d: K02local@ K30nfsfs@ K48isdn@ K70syslog@ K90network@ K10lpd@ K32cfsfs@ K50inet@ K86pcmcia@ S00down@ K20sendmail@ K40nfs@ K60cron@ K88ibcs@ /etc/rc.d/rc1.d: K30nfsfs@ S10network@ S30syslog@ S54isdn@ S96keytable@ K32cfsfs@ S20pcmcia@ S40cron@ S80sendmail@ S98local@ K40nfs@ S22ibcs@ S50inet@ S90lpd@ /etc/rc.d/rc2.d: S10network@ S30syslog@ S54isdn@ S72cfsfs@ S96keytable@ S20pcmcia@ S40cron@ S60nfs@ S80sendmail@ S98local@ S22ibcs@ S50inet@ S70nfsfs@ S90lpd@ [root@atlantis /root]# _
Beim Wechsel in einen von dem rc-Script kontrollierten Runlevel werden die Miniscripts aus dem korrespondierenden Verzeichnis aufgerufen. Die Miniscripts, deren Dateinamen mit K beginnt, werden mit dem Argument stop aufgerufen, die mit Dateinamen auf S mit dem Argument start.
Wegen möglicher Abhängigkeiten der Miniscripts voneinander ist die Reihenfolge ihrer Bearbeitung von Bedeutung. Deshalb wird durch die zweistellige Zahl im Dateinamen die Reihenfolge ihrer Verarbeitung bestimmt.
Weil in jedem der Runlevel-Verzeichnisse die gleichen Miniscripts nur unter anderen Namen aufgerufen werden, sind die Dateinamen nur symbolische Links auf die echten Dateien in dem Verzeichnis /etc/rc.d/init.d. Auf diese Weise müssen nicht mehrere Kopien der gleichen Datei verwaltet werden.
#!/bin/sh # Beispiel eines Initialisierungsscripts fuer den Druckerdaemon. # Zuerst wird ein weiteres Shellscript eingefuegt, in dem die # Hilfsfunktionen starte() und beende() definiert sind: source /etc/rc.d/init.d/funktionen # Hier wird getestet, ob die erforderlichen Komponenten existieren: [ -f /usr/sbin/lpd ] || exit 0 [ -f /etc/printcap ] || exit 0 # Schliesslich werden die Komponenten hinzugefuegt oder geloescht: case "$1" in start) # Start des Druckerdaemons starte lpd touch /var/lock/subsys/lpd ;; stop) # Stop des Druckerdaemons beende lpd rm -f /var/lock/subsys/lpd ;; *) echo "Usage: rc.lpd {start|stop}" exit 1 esac exit 0
Die zu Beginn des Beispiels eingefügte Datei enthält die Definitionen von Hilfsfunktionen, die von allen Initscripts benutzt werden können. Die beiden im Beispiel verwendeten Funktionen starte() und beende() sehen folgendermaßen aus:
# Definition von Funktionen fuer die Initscripts. export PATH="/sbin:/usr/sbin:/bin:/usr/bin" # Die Funktion starte() sorgt dafür, daß kein Aufruf doppelt erfolgt. starte() { # Hier wird getestet, ob das Programm bereits laeuft: [ "`pidof ${1##*/}`" != "" ] && return # Wenn das nicht der Fall ist, wird der Name ausgegeben... echo -n "$1 " # ...und das Programm gestartet: $* } # Die Funktion beende() hält einen Systemservice an. beende() { # Zuerst wird die Prozess-ID der Komponente gesucht: pid=`pidof ${1##*/}` # Wenn die Komponente laeuft, wird sie beendet: if [ "$pid" != "" ] ; then echo -n "$1 " kill -9 $pid fi }
Sie finden die Erklärung aller in dem Beispiel verwendeten Symbole und Funktionen zur Shellprogrammierung in dem Abschnitt über die bash.
Das zusammen mit dem sysvinit installierte Programm runlevel gibt den letzten und den aktuellen Runlevel aus. Diese Information kann in den Initialisierungsscripts ausgewertet werden.Beim simpleinit gibt es nur zwei Runlevel:
Wenn das System läuft, kann der Runlevel auf verschiedene Weisen beeinflußt werden. Eine direkte Veränderung kann durch das Programm telinit herbeigeführt werden. telinit muß mit Rootprivilegien aufgerufen werden und erwartet den Runlevel, in den gewechselt werden soll, als Argument auf der Kommandozeile.
Neben den im Abschnitt über die inittab bereits beschriebenen Möglichkeiten, den Runlevel durch Signale vom Powermanagement oder von der Tastatur zu verändern, bietet sysvinit noch zwei allgemeinere Mechanismen zur Kommunikation mit anderen Prozessen an.
Bei einem Mehrbenutzersystem sind vor dem Abschalten des Rechners noch ein paar Schritte notwendig, die bei weniger leistungsfähigen Betriebssystemen nicht erforderlich sind.
Bei einem vernetzten Rechner, der möglicherweise von mehreren natürlichen Personen gleichzeitig benutzt wird, muß vor dem Abschalten selbstverständlich darauf geachtet werden, daß alle Benutzer ihre Arbeit rechtzeitig sichern und ihre Sessions beenden können.
Wegen der im Hintergrund arbeitenden Dämonen besteht aber auch bei einem System, daß nur von einer einzigen Person benutzt wird, die Gefahr, daß ein Dämonprozeß im Moment des Abschaltens gerade dabei ist, in eine Datei zu schreiben. Wenn dieser Schreibvorgang nicht abgeschlossen werden kann, befinden sich die Daten in einem inkonsistenten Zustand, was zu unvorhersehbaren und wahrscheinlich unerwünschten Ergebnissen führen kann.
Weil Linux einen Teil des Arbeitsspeichers als Cache zur Beschleunigung der Festplattenzugriffe nutzt, ist die Gefahr, beim unkontrollierten Ausschalten des Rechners Fehler in den Daten auf der Festplatte zu erzeugen, um so größer.
Um diese Probleme zu vermeiden, muß das Betriebssystem heruntergefahren werden, bevor der Rechner ausgeschaltet werden kann. Im einzelnen werden hierzu alle Benutzerprozesse und Dämonen beendet, der Buffercache mit der Festplatte synchronisiert und schließlich alle Dateisysteme demontiert.
Um der Systemverwalterin das Herunterfahren des Systems zu erleichtern, gibt es das Programm shutdown. Es sorgt dafür, daß alle eingeloggten Benutzer von dem bevorstehenden Systemhalt informiert werden, es verhindert neue Logins und es führt schließlich die erforderlichen Aktionen für das geordnete Anhalten des Systems aus.
Das mit dem simpleinit installierte shutdown führt alle Aktionen zum Herunterfahren des Systems selbst aus. Es senden allen laufenden Prozessen zuerst ein SIGTERM und zwei Sekunden später ein SIGKILL, dann wird der Swapbereich deaktiviert und die Dateisysteme abgebaut.
Das sysvinit kann wesentliche Teile des Shutdown selbst ausführen. Insbesondere werden bei geeigneter Konfiguration der Miniscripts durch einen Wechsel in den Runlevel 0 alle Komponenten aus der Laufzeitumgebung entfernt, die im Mehrbenutzermodus gestartet wurden.Das Programm shutdown, das mit dem sysvinit installiert wird, übernimmt das Timing und die Koordination beim Herunterfahren des Systems. Es benachrichtigt die aktiven User und übergibt normalerweise die Kontrolle für das eigentliche Shutdown wieder zurück an init. Die letzte Phase des Anhaltens wird dann an das Programm halt abgegeben, das alle Aktivitäten des Systems beendet und den Warmstart auslöst.
Das sysvinit kann ein Shutdown als Reaktion auf die Tastankombination ALT-CTRL-DEL ausführen. Damit nicht jede Person, die Zugang zur Tastatur der Console hat, das System einfach anhalten kann, hat die Systemverwalterin die Möglichkeit, in der Datei /etc/shutdown.allow die Namen der User anzugeben, die zum Herunterfahren des Systems berechtigt sind.
Wenn aus irgendwelchen Gründen das System nicht mit shutdown angehalten werden kann, ist es auch möglich, das System ,,per Hand`` herunterzufahren. Voraussetzung dafür ist natürlich, daß Sie Root-Privilegien haben.Für ein geordnetes Herunterfahren des Rechners müssen alle Benutzerprozesse angehalten werden. Nachdem Sie alle aktiven natürlichen Systembenutzer mit einer wall-Message gewarnt haben, können Sie (nach einer angemessenen Zeit) die Dämonen, Anwenderprogramme und Loginshells durch die Programme kill und killall mit SIGTERM, später mit SIGKILL beenden. Dabei müssen Sie darauf achten, daß Sie nicht aus Versehen auch die Shell beenden, mit der Sie gerade arbeiten. Um das Einloggen weiterer Systembenutzer zu verhindern, können Sie die Datei /etc/nologin anlegen. Außerdem kann init veranlaßt werden, keine neuen Prozesse zu starten, indem ihm mit dem Programm kill das Signal SIGSTP gesendet wird.
Wenn alle Prozesse außer init und der letzten Shell beendet sind, können die Dateisysteme mit dem Kommando umount -a demontiert werden. Schließlich wird das Schreibrecht für das Rootfilesystem durch den Befehl ``mount -n -o ro,remount /'' weggenommen. In diesem Zustand ist das System vollständig heruntergefahren und der Rechner kann gefahrlos abgeschaltet werden.
Das Linux Anwenderhandbuch