# 1.105.1

# Verwalten/Abfragen von Kernel und Kernelmodulen zur Laufzeit

Beschreibung: Prüfungskandidaten sollten in der Lage sein, Kernel und ladbare Kernelmodule zu verwalten und/oder abzufragen. Dieses Lernziel beinhaltet die Verwendung von Kommandozeilen-Utilites, um Informationen über den gerade laufenden Kernel und die Kernelmodule zu erhalten. Ebenfalls enthalten ist das manuelle Laden und Entladen von Modulen nach Bedarf. Dies beinhaltet auch die Bestimmung, wann Module entladen werden können und welche Parameter ein Modul akzeptiert. Prüfungskandidaten sollten in der Lage sein, das System so zu konfigurieren, daß Module auch durch andere als ihre Dateinamen geladen werden können.

Die wichtigsten Dateien, Bezeichnungen und Anwendungen:

- `/lib/modules/kernel-version/modules.dep`
- `/etc/modules.conf & /etc/conf.modules`
- depmod
- insmod
- lsmod
- rmmod
- modinfo
- modprobe
- uname

### Kernelmodule

Der Linux-Kernel war anfangs (in der Version 1.x.x) ein rein monolithisches Gebilde. Das hatte zur Folge, daß jede Hardware-Unterstützung fest in den Kernel eingebunden werden musste. So entstanden entweder sogenannte Allround-Kernel, die riesengroß waren und Unterstützung für die abenteuerlichste Hardware zur Verügung stellten, oder es musste für jede neue Hardware, die in einen Rechner eingebaut wurde, ein neuer Kernel erstellt werden. Beides war keine praxistaugliche Lösung.

Aus diesem Grund wurde der Kernel modularisiert. Das heißt, daß bestimmte Teile des Kernels nicht mehr beim Compilieren fest eingebunden werden müssen, sondern später, während der Laufzeit, ge- und auf Wunsch auch wieder entladen werden können. Diese Fähigkeit ermöglicht es, daß Gerätetreiber eben nicht immer fest eingebunden werden müssen, sondern je nach Bedarf nachgeladen werden können. Distributoren können so schlanke Kernel ausliefern, die trotzdem alle Fähigkeiten von Linux unterstützen, weil die jeweiligen Fähigkeiten bei Bedarf geladen werden können. Die Teile des compilierten Kernels, die nicht fest eingebunden sind, sondern ge- und entladen werden können, werden Kernelmodule genannt.

Die Kernelmodule des Linux-Kernels werden im Dateisystem unter `/lib/modules/Kernelversion` abgespeichert, wobei Kernelversion für die Versionsnummer des Kernels steht, für den die Module passen. Die Module bestehen aus Objektdateien (Endung `.o`), die in diesem Verzeichnis in diverse Unterverzeichnisse sortiert sind.

Kernelmodule sind Teile des Kernels, zwar ausgelagert, aber doch Teile des Ganzen. Wenn solche Module ein- und ausgehängt werden, so spielen bestimmte Abhängigkeiten (dependencies) eine Rolle. Beispielsweise kann der Kernel nichts mit einem Modul anfangen, das ihm die Fähigkeit verleihen soll, mit SCSI-CDROMs umzugehen, wenn er gar nicht weiß, was SCSI ist. Das Modul für die SCSI-CDROMs ist also abhängig vom generellen Modul für SCSI. Diese Abhängigkeiten müssen den Programmen bekannt sein, die die Module laden und entladen. Aus diesem Grund existiert das Programm depmod, das die Abhängigkeiten aller Module untersucht und die Ergebnisse in die Datei `/lib/modules/Kernelversion/modules.dep` schreibt. In dieser Datei stehen dann - in klar lesbarer Form - die entsprechenden Abhängigkeiten jedes einzelnen Moduls. Jedesmal, wenn neue Module ins Modulverzeichnis kopiert werden, muß anschließend dieses Programm aufgerufen werden.

### Programme zum Umgang mit den Modulen

Es gibt jetzt eine Reihe von Befehlen, die es ermöglichen mit Kernelmodulen umzugehen. Diese Befehle werden jetzt der Reihe nach kurz beschrieben.

#### Auflistung der geladenen Module

Um herauszufinden, welche Module bereits geladen sind, existiert der Befehl lsmod. Er zeigt alle geladenen Module im Format Name, Größe, Wie-oft-gebraucht und Liste der Module, die das Modul benötigen. Dieser Befehl dient also hauptsächlich dazu, zu überprüfen, ob ein bestimmtes Modul geladen ist oder nicht. lsmod wird ohne Parameter aufgerufen.

#### Laden von einzelnen Modulen

Um ein einzelnes Modul zu laden, kann der Befehl insmod verwendet werden. Als Parameter erwartet insmod den Namen des zu ladenden Moduls. Der Name wird ohne die Endung `.o` angegeben. Auch Pfade werden keine benötigt. Das Programm weiß ja selbst, in welchem Verzeichnis die ladbaren Module des aktuellen Kernels zu finden sind. Um also beispielsweise das Modul `/lib/modules/Kernelversion/kernel/drivers/usb/printer.o` zu laden genügt die Angabe

      insmod printer

Anhand der aktuellen Kernelversionsnummer ermittelt insmod das notwendige Basisverzeichnis für die Module und kann dort über die Datei `modules.dep` den genauen Pfad zum gewünschten Modul ermitteln.

Wenn ein Modul selbst noch Parameter erwartet, z.B. die I/O-Adresse einer ISA-Netzwerkkarte, so werden sie nach dem Modulnamen angegeben. Diese Parameter haben immer die Form

Symbolname=Wert

Für die ISA-Netzwerkkarte könnte das z.B. der Befehl

      insmod ne io=0x300 irq=5

sein. Damit wird das Modul `ne` geladen (ein Modul für eine NE2000 Netzwerkkarte) und bekommt als Parameter die Werte für IO-Adresse und IRQ übergeben.

Das Programm insmod läd nur das angegebene Modul. Wenn dieses Modul andere Module benötigt, so werden sie nicht mitgeladen.

#### Laden eines Moduls mit allen nötigen Zusatzmodulen

Damit man auch Module laden kann, und automatisch alle notwendigen Zusatzmodule mitgeladen werden, existiert der Befehl modprobe. Er hat heute den Befehl insmod völlig verdrängt, denn er ist wesentlich intelligenter. Die Anwendung entspricht der von insmod. Als Parameter wird das zu ladenden Modul, wiederum ohne Pfad und ohne der Endung `.o` angegeben. Auch eventuell notwendige Parameter werden wie bei insmod angegeben.

Im Gegensatz zu insmod überprüft modprobe die Abhängigkeiten der Module untereinander (über die Informationen aus `modules.dep` und läd alle Module, die das angegebene Modul benötigt, um richtig zu funktionieren. Ein Beispiel:

Wenn wir das Modul für ein am Parallelport angeschlossenes Zip-Laufwerk (ppa) laden wollen, so benötigt dieses Modul, das generellen Zugriff auf Parallelports ermöglicht (parport). es reicht zu schreiben

      modprobe ppa

und modprobe erkennt, daß eine nicht erfüllte Abhängigkeit vorliegt, läd zuerst das Modul `parport` und erst danach das Modul `ppa`.

Anstatt Parameter für bestimmte Module direkt anzugeben, unterstützt modprobe (nicht insmod) eine Datei, die die notwendigen Modulparameter enthält. Diese Datei heißt entweder `/etc/conf.modules` (alt) oder `modules.conf` (aktuell) und wird weiter unten noch genauer beschrieben.

Um genau zu sein, benutzt modprobe das Programm insmod um die notwendigen Module zu laden. modprobe ist also eine Art High-Level Programm zum Laden der Module oder ein Frontend für insmod.

#### Entfernen von geladenen Modulen

Wenn ein Modul nicht mehr benötigt wird, so kann es mit dem Befehl rmmod wieder aus dem Kernel entfernt werden. rmmod kann keine Module entfernen, die gerade in Gebrauch sind oder die von anderen geladenen Modulen benötigt werden. Allerdings ist es möglich, mit dem Kommandozeilenparameter `-r` dafür zu sorgen, daß rmmod so funktioniert, wie ein umgekehrtes modprobe, also nicht nur das angegebene Modul entfernt, sondern alle, die nur deshalb geladen sind, damit das zu entfernende Modul funktioniert.

Auch dieses Programm erwartet den Namen des zu entfernenden Moduls ohne Endung und Pfad.

Auch das Programm modprobe kann verwendet werden, um Module wieder zu entfernen. Mit dem Parameter `-r` werden Module entfernt, die auf der Kommandozeile angegeben wurden.

### Modulparameter erkennen und einstellen

Module sind häufig Gerätetreiber für bestimmte Hardware. In vielen Fällen ist es notwendig, für die Ansteuerung der Hardware bestimmte Parameter wie IO-Port, IRQ usw. anzugeben, wenn ein Modul geladen werden soll. Wie oben gesehen, werden Parameter für Module immer in der Form

Symbolname=Wert

angegeben. Dazu muß aber klar sein, welche Symbolnamen das jeweilige Modul kennt, also welche Parameter es versteht. Um das herauszufinden gibt es das Programm modinfo. Dieses Programm gibt Informationen über ein Modul aus, unter anderem welche Parameter angegeben werden können. Auch modinfo arbeitet mit den Modulnamen ohne Endung und Pfad. Über Kommandozeilenparameter kann angegeben werden, welche Informationen ausgegeben werden sollen, ohne solche Schalter werden die Informationen über

- Dateiname und Pfad der Moduldatei (-n)
- Beschreibung (-d)
- Author (-a)
- Lizenz (-l)
- Parameter (-p)

ausgegeben. Um z.B herauszufinden, welche Parameter das Modul 3c509 (ein Gerätetreiber für eine 3Com Netzwerkkarte) benötigt, können wir schreiben

      modinfo -p 3c509

Die entsprechende Ausgabe des Programms wäre:

      debug int, description "EtherLink III debug level (0-6)"
      irq int array (min = 1, max = 8), description "EtherLink III
         IRQ number(s) (assigned)"
      xcvr int array (min = 1, max = 8), description "EtherLink III
         tranceiver(s) (0=internal, 1=external)"
      max_interrupt_work int, description "EtherLink III maximum events
         handled per interrupt"
      nopnp int, description "EtherLink III disable ISA PnP support (0-1)"

Daraus können wir entnehmen, daß dieses Modul die Parameter `debug, irq, xcvr, max_interrupt_work` und `nopnp` versteht. Alle diese Parameter erwarten ganzzahlige (int) Werte. Wenn hier die Angabe `array` steht, so ist gemeint, daß wenn mehrere gleichartige Karten existieren, die alle dieses Modul benötigen, dann an Stelle der normalen Angabe einer Zahl, eine durch Komma getrennte Liste von Zahlen verwendet wird. Bei drei solcher Netzwerkkarten hieße der Parameter, der den IRQ einstellt also `irq=3,5,7`. Die erste Karte benutzt IRQ3, die zweite 5 und die dritte 7.

#### Die Datei /etc/modules.conf

Um den Kernelmodulen ihre Parameter an einer festen Stelle angeben zu können, wurde modprobe so programmiert, daß es die Datei `/etc/modules.conf` (oder `/etc/conf.modules`) abarbeitet und dort entsprechende Parameter für die Module entnimmt.

Die Datei kann auch noch mehr, als nur Parameter für Module zur Verfügung stellen. Insbesondere können damit

- Parameter für Module festgelegt werden,
- Aliasnamen für Module vergeben werden,
- Module angegeben werden, die vor oder nach dem eigentlichen Modul geladen werden sollen,
- Module, die vor oder nach dem Laden des eigentlichen Moduls entfernt werden sollen

Die Datei hat ein einfaches Format. Jede Zeile, die nicht mit einem Kommentarzeichen (#) beginnt oder leer ist, wird als Anweisung interpretiert. Um einem Modul bestimmte Parameter zu setzen, wird der Befehl options benutzt. Er hat die folgende Syntax:

options Modulname Optionen

Ein Eintrag für unsere NE2000 Netzwerkkarte, könnte also so aussehen:

      options ne io=0x320 irq=7

Jedesmal, wenn jetzt mit modprobe das Modul `ne` geladen wird, werden automatisch diese Optionen mitgeladen.

Um ein Modul auch mit anderem Namen anzusprechen, können wir Aliasnamen vergeben. Das bedeutet, daß mit modprobe auch Module geladen werden, die es gar nicht gibt, sondern die nur Aliasnamen sind. Die Syntax ist

alias Aliasname Modulname

Diese Methode wird gerne benutzt um bestimmte Hardware an einen Begriff zu binden, der mehr aussagt und allgemeiner handhabbar ist als der Modulname. So kann z.B. der Aliasname `eth0` an die tatsächliche Netzwerkkarte gebunden werden. Der Eintrag

      alias eth0 ne
      alias eth1 off

      options ne io=0x320 irq=7

würde es also ermöglichen, daß wir (oder ein init-script) den Befehl

      modprobe eth0

eingeben und so automatisch das Modul `ne` mit den angegebenen Parametern geladen wird. Versucht aber jemand mit modprobe das Modul `eth1` zu laden, dann weigert sich modprobe irgendein Modul zu laden, da der Wert des Aliases off ist.

Mit pre-install können Befehle angegeben werden, die vor dem Laden des Moduls ausgeführt werden sollen. Diese Befehle können (müssen aber nicht) andere Module laden. Die Syntax lautet:

pre-install Modul Kommando

Bevor das Modul geladen wird, wird erst das Kommando ausgeführt. Analog dazu gibt es die Befehle

post-install Modul Kommando
pre-remove Modul Kommando
post-remove Modul Kommando

die entsprechend nach dem Laden, vor dem Entfernen und nach dem Entfernen bestimmter Module bestimmte Kommandos ausführen. Alle vier Kommandos können auch auf Aliasnamen angewandt werden.

### Der Befehl uname

Der Befehl uname gibt Informationen über den Kernel und das System aus. Um z.B. die aktuelle Kernelversion zu erfragen, genügt ein Aufruf von

      uname -r

Das ist z.B. die Methode, mit der erfragt werden kann, in welchem Verzeichnis die Module des Kernels liegen. Es ist tatsächlich möglich zu schreiben

      cd /lib/modules/`uname -r`/kernel

Durch die Kommandosubstitution wird das Konstrukt ``uname -r`` durch die Ausgabe des Befehls ersetzt und die entspricht genau dem, was als Verzeichnisnamen vorliegt.

Alle Informationen können mit `uname -a` ausgegeben werden, die restlichen Parameter entnehmen Sie der Handbuchseite.