Stein auf Stein

Wo sich Windows als monolithischer Klotz präsentiert, besticht Linux durch gnadenlose Offenheit: Der Anwender kann das System bis in die letzten Winkel erforschen und beeinflussen. Aber dazu muß man erst mal verstehen, wie die einzelnen Bestandteile zusammenspielen.

In Pocket speichern vorlesen Druckansicht
Lesezeit: 13 Min.
Von
  • Dr. Oliver Diedrich
Inhaltsverzeichnis

Linux - das ist strenggenommen nur der Kernel, also das, was als Quelltext in /usr/src/linux/ liegt und und als komprimiertes Kompilat in der Datei vmlinuz in / oder /boot landet. Der Kernel ist für die Hardware zuständig: Er verteilt begehrte Ressourcen wie CPU-Zeit und Speicher an die Prozesse, spricht über Treiber mit den verschiedenen `Geräten´ - vom Chipsatz des Boards bis zur Soundkarte - und stellt grundlegende Netzwerkprotokolle wie TCP/IP oder IPX bereit. Außerdem gehören Dateisysteme wie FAT oder ext2 bei Linux zum Kernel.

Duch Kompilieren eines eigenen Kernel kann der Linux-User dafür sorgen, daß lediglich die benötigten Gerätetreiber, Dateisysteme und Kernel-Funktionen eingebunden werden. So entsteht ein Kernel, der optimal an die eigene Hardware angepaßt ist. Dateisysteme und Treiber, die man nur ab und zu braucht, lassen sich als Kernel-Module kompilieren und im laufenden Betrieb nach Bedarf zum Kernel hinzulinken und wieder entfernen.

Module [1] sind auch ein bequemer Weg, neue Hardwaretreiber zu testen, ohne jedesmal einen neuen Kernel kompilieren und booten zu müssen - wahrscheinlich der eigentliche Grund, warum die Kernel-Entwickler diese Möglichkeit eingebaut haben. Mit den Kommandos insmod und modprobe lassen sich Module laden, mit rmmod wird man sie wieder los, und lsmod zeigt die aktuell geladenen Module an.

Viele Treiber für Peripheriegeräte wie Drucker, Maus, Modem oder Grafikkarte gehören unter Linux nicht zum Kernel. Um diese Geräte kümmern sich Anwendungsprogramme, die als voreinander geschützte Prozesse laufen. Das hat den großen Vorteil, daß beispielsweise ein fehlerhafter `Grafiktreiber´ das System nicht zum Absturz bringen kann - selbst wenn die grafische Oberfläche eingefroren ist, kann man sich in aller Regel noch übers Netz (oder über ein Terminal an der seriellen Schnittstelle) einloggen, den amoklaufenden Prozeß killen und das System weiterbenutzen.

Das Booten eines Linux-Systems beginnt damit, daß ein Bootloader geladen wird - auf Intel-Systemen meist der Linux-Loader Lilo, der als Bootmanager auch andere Betriebssysteme starten kann. Seine Aufgabe besteht darin, den Linux-Kernel in der Speicher zu bringen. Der Artikel ab Seite 166 in c't 12/99 zeigt, was mit lilo sonst noch möglich ist. Alternativ läßt sich Linux mit dem Programm loadlin.exe auch aus DOS heraus starten.

Nach dem Laden dekomprimiert eine spezielle Routine den Kernel, der nun die Hardware initialisiert und dabei seine Aktivitäten auf der Systemkonsole ausgibt. Mit der Tastenkombination Shift-PageUp kann man auf der Konsole zurückblättern, um sich die Meldungen, die beim Booten recht schnell über den Bildschirm flitzen, in aller Ruhe anzusehen. Das Kommando dmesg zeigt die Kernelmeldungen auch nach dem Start des Systems an. Schließlich mountet der Kernel das Root-Filesystem; ab jetzt kann das System auf die Festplatte zugreifen.

Als letzte Aktion ruft der Kernel /sbin/init auf. Dieses Programm arbeitet zunächst die Init-Skripte zur Systemkonfiguration ab. Über diese Skripte kann der Systemverwalter sehr detailliert festlegen, welche Aktionen der Rechner beim Booten ausführen soll; ab Seite 174 in c't 12/99 erfahren Sie, wie das geht.

Die Aufgaben der Init-Skripte reichen vom Mounten der Laufwerke über das Laden von Kernelmodulen und die Konfiguration von Hardware und Netzwerk bis zum Start von Daemons. Letztlich versetzen die Init-Skripte das System überhaupt erst in einen benutzbaren Zustand.

Die Daemons spielen eine besonders wichtige Rolle auf Unix-artigen Systemen. Diese dienstbaren Geister erfüllen als Hintergrundprozesse ohne Benutzerinteraktion vielfältige Arbeiten - von klassischen Serverdiensten wie httpd über das regelmäßige Ausführen von Wartungsaufgaben (cron) bis zu grundlegenden Systemtätigkeiten.

Zu den wichtigsten System-Daemons gehört der Update-Daemon. update kümmert sich darum, daß der Inhalt der Schreibpuffer regelmäßig auf die Platte geschrieben wird - im Falle eines Systemcrashs halten sich so die Inkonsistenzen im Dateisystem in Grenzen.

klogd und syslogd sorgen dafür, daß Kernel- und Systemmeldungen in Protokolldateien landen. syslogd kann Systemmeldungen dienstespezifisch (Login-Information, Mailserver, Printserver und so weiter) und nach Wichtigkeit (Information, Warnung, Fehler) in verschiedene Protokolldateien umleiten; seine Konfiguration erfolgt über die Datei /etc/syslog.conf.

Der Kernel-Daemon kerneld [2] schließlich vereinfacht den Umgang mit Kernel-Modulen, indem er das Laden und Entladen von Modulen automatisiert. Erfolgt ein Zugriff auf eine Gerätedatei, für die noch kein Treiber im Kernel registriert ist, fordert der Kernel den kerneld dazu auf, das passende Modul zu laden. Die Identifikation des Gerätes erfolgt dabei über die major number der Datei in /dev/, die das Kommando ls -l bei Device-Files in der fünften Spalte anstelle der Dateigröße ausgibt.

Bei vielen Geräten weiß der Kernel-Daemon selbst, welcher Treiber zu ihrem Betrieb erforderlich ist; bei anderen wie Netzwerk-Devices, die je nach installierter Netzkarte über unterschiedliche Treiber angesprochen werden, sieht er in der Datei /etc/conf.modules nach. Hier lassen sich auch erforderliche Parameter einzelner Treiber wie IRQ oder I/O-Adresse konfigurieren.

Nach Abarbeitung der Init-Skripte sorgt /sbin/init schließlich dafür, daß Benutzer überhaupt mit dem System reden können. Der Linux-Kernel besteht nämlich lediglich aus einer Ansammlung von Funktionen, die im Speicher gehalten werden - der Anwender kann gar nicht direkt mit dem Kernel interagieren. /sbin/init startet daher als letztes einen getty-Prozeß, der den bekannten login-Prompt an der Konsole bereitstellt und nach dem Einloggen eine Shell startet.

Auch hier kann der Systemverwalter festlegen, auf welchen Konsolen welches Login-Programm startet - Linux bietet mehrere virtuelle Konsolen, die sich über die Kombination von Alttaste und Funktionstasten erreichen lassen.

Ebenso läßt sich einstellen, in welcher Shell ein User nach dem Einloggen landet; Linux bietet mit den Klassikern Bourne- und C-Shell sowie diversen Derivaten wie tcsh oder der Linux-Standardshell bash reichlich Auswahl. Ebensogut kann der Systemverwalter als Login-Shell ein ganz anderes Programm auswählen, das beispielsweise über ein Menü nur das Starten bestimmter Anwendungen zuläßt.

Die Shell ist der Dreh- und Angelpunkt der Interaktion zwischen Anwender und System - selbst bei Einsatz eines grafischen Desktop wie KDE oder Gnome wird man meist ein Terminalfenster auf dem Schirm haben. Die Shell dient in erster Linie zum Starten von Programmen; `bessere´ Shells wie bash bieten darüber hinaus eine mächtige Skriptsprache und zahllose Komfortfunktionen, die wir ab Seite 170 in c't 12/99 näher beleuchten.

Dennoch läßt sich mit der Shell allein noch nicht viel anfangen: Für fast jeden Anwenderwunsch muß sie externe Programme aufrufen - bereits zum Kopieren einer Datei benötigt man ein entsprechendes Hilfsprogramm. Tatsächlich ist cd so ziemlich das einzige Kommando, das der `normale´ Anwender häufiger am Kommandoprompt eingibt und das nicht zum Aufruf eines externen Programms führt.

Für die zahllosen Systemprogramme von ls über man bis grep, die ein Linux-System überhaupt erst benutzbar machen, gilt dasselbe wie für die Shell: Sie sind kein Bestandteil von Linux, sondern prinzipiell austauschbare Utilities, die größtenteils aus dem GNU-Projekt der Free Software Foundation [3] stammen. Wer möchte, kann sich durchaus sein eigenes rm programmieren.

Letztlich greifen all diese Systemprogramme auf Kernelroutinen zurück - ###italic[cat]italiczu### beispielsweise öffnet eine Datei, liest ihren Inhalt und schreibt die Daten auf die Standardausgabe. Um eine Kernelroutine wie das Öffnen einer Datei aufzurufen, müssen Linux-Programme gegen eine Systembibliothek gelinkt werden, die ihnen die Kernelschnittstellen in Form von C-Funktionen zugänglich macht. Die wichtigste Bibliothek, die ausnahmslos jedes Linux-Programm benötigt, ist die C-library (/lib/libc.*).

Damit nicht jedes kleine Progrämmchen die umfangreiche libc mit sich rumschleppen muß, kennt Linux dynamisch ladbare `shared libraries´, erkennbar an der Extension .so - das Pendant zu den Windows-DLLs. Der `dynamic linker/loader´ /lib/ld-linux.so linkt beim Start eines Programmes die benötigten shared libraries dazu. Alle dynamischen Bibliotheken existieren auch in einer statischen Version (erkennbar an der Extension .a), die man beim Kompilieren eines Programms statisch hinzulinken kann. Über die Systembibliotheken (und eventuelle weitere Bibliotheken zum Zugriff auf Treiberfunktionen) stellt der Linux-Kernel seine Funktionen für Anwendungen bereit.

Erst aus dem Zusammenspiel von Bootloader, Kernel, Init-Prozeß, Systembibliotheken, Shell und den grundlegenden Systemprogrammen entsteht ein benutzbares Betriebssystem. Dessen Fähigkeiten sind allerdings - verglichen mit einer vollständigen Linux-Distribution - noch recht beschränkt: Zusammen mit dem auf einem Unix-artigen Betriebssystem obligatorischen C-Compiler kann der Anwender nicht viel mehr tun als sein System zu verwalten, Textdateien zu bearbeiten, am Kernel zu basteln und eigene Programme zu erstellen.

Richtig Spaß macht Linux aber erst mit einer Netzwerkverbindung. Die Grundlagen dazu - die Fähigkeit zum Umgang mit TCP/IP-Paketen - bringt der Kernel schon mit; Server und Clients für die verschiedenen TCP-Protokolle sind einfach normale Anwendungen. Das reicht von grundlegenden Diensten wie ftp oder telnet bis hin zu Webserver und Browser. Serverseitig ist der Internet-Daemon inetd die zentrale Instanz, die die verschiedenen TCP-Ports überwacht und bei Anfragen aus dem Netz den entsprechenden Server (in Form eines Daemons wie ftpd oder telnetd) startet.

Für jeden Internet-Dienst, den man in Anspruch nehmen möchte, benötigt man die passende Client-Anwendung. Dazu kommen die Programme, die das Netzwerk konfigurieren: ifconfig erledigt die Grundkonfiguration eines Netzwerk-Devices (etwa eth0 für die erste Ethernetkarte oder ippp0 für eine PPP-Verbindung über die ISDN-Karte); route weist den Netzpaketen ihren Weg ins Internet.

Der verwöhnte Anwender möchte natürlich auch seine Peripheriegeräte nutzen und unter Linux drucken und scannen. Drucken unter Linux [4] bedeutet den Einsatz zweier Software-Pakete: Der Printserver lpd mit seinen Hilfsprogrammen sorgt dafür, daß sich ein lokal angeschlossener oder übers Netz erreichbarer Drucker überhaupt ansprechen läßt; und wer nicht stolzer Besitzer eines PostScript-Druckers ist, benötigt das Ghostscript-Paket.

Ghostscript [5] setzt PostScript - universelles Druckformat unter Unix und Verwandten - in Anweisungen um, die der jeweilige Drucker versteht. Druckertreiber sind daher unter Linux Bestandteil von Ghostscript. Was Ghostscript fürs Drucken, ist SANE [6] fürs Scannen: Unter Linux funktioniert jeder Scanner, den SANE unterstützt; das sind zur Zeit allerdings fast nur SCSI-Geräte.

Entsprechend der Linux-Philosophie ist der Anwender auf keines dieser Pakete festgelegt: Statt des BSD-Drucksystems mit seinem lpd kann man beispielsweise auch den Public Line Printer plp [7] einsetzen; und Anwendungen wie WordPerfect oder StarOffice bringen gleich ihre eigenen Druckertreiber mit, so daß sie auch ohne Ghostscript drucken können.

Trotz komfortabler Shell, virtueller Konsolen und ausgefuchster Programme für den Kommandoprompt: Ein modernes Betriebssystem braucht natürlich eine grafische Oberfläche mit Fenstern und Menüs. Auch die ist bei Linux modular gestaltet: Mindestens zwei Komponenten sind erforderlich, um mit dem X Window System zu einem GUI zu kommen, das auch nur entfernte Ähnlichkeit mit den Oberflächen anderer Betriebssysteme hat.

Um den `technischen Kram´, also das Ansprechen der Grafikkarte, kümmert sich der X-Server; für das freundliche Aussehen ist ein Fenstermanager zuständig. Der Artikel ab Seite 178 in c't 12/99 beleuchtet das Zusammenspiel der beiden. Wenn Sie wissen möchten, wie ein nacktes X11 aussieht, versuchen Sie es mal mit `xinit /usr/X11R6/bin/xterm - /usr/X11R6/bin/X´.

Lediglich der X-Server ist hardwareabhängig: Nahezu alle Grafikkarten laufen mit dem VGA-Server, der allerdings nur auf bescheidene 640 x 480 Pixel bei 16 Farben und flimmrigen 60 Hz Bildwiederholfrequenz kommt. Wer seiner Karte eine höhere Auflösung, mehr Farben und mehr Tempo entlocken will, braucht einen passenden X-Server. Alle Distributionen bringen hier eine reiche Auswahl mit; fehlt der Server für die eigene Karte, kann ein Blick auf die Homepage von XFree86 [8] oder die X-Server-Ecke von SuSE [9] helfen.

Ein gutes Dutzend anwendungsreife Fenstermanager machen es dem Anwender leicht, seinem System ein persönliches Look and Feel zu verleihen. Mit Gnome und KDE stehen zwei Desktops zur Auswahl, deren Funktionsumfang weit über einen einfachen Fenstermanager hinausgeht und die Windows in nichts nachstehen. Selbst an Alternativen zu X11 arbeitet die Freeware-Gemeinde. (odi)

[1] Modules-Mini-Howto: http://howto.linuxberg.com/ptHOWTO/mini/Modules

[2] Kerneld-Mini-Howto: http://howto.linuxberg.com/ptHOWTO/mini/Kerneld

[3] FSF: www.fsf.org

[4] Henning Emmrich und Albert Lotter, Mit Nachdruck, Drucken unter Linux. c't 17/98, S. 190

[5] Ghostscript: www.cs.wisc.edu/~ghost/

[6] SANE: www.mostang.com/sane/

[7] PLP: ftp://ftp.iona.ie/pub/plp

[8] XFree86: www.xfree86.org

[9] www.suse.de/XSuSE/ (odi)