Bewertung: 1


Die Kandidaten sollten in der Lage sein, einen Kernel für verschiedene Anforderungen einzurichten, durch patchen, compilieren oder dem Editieren von Konfigurationsdateien, je nach Notwendigkeit. Dieses Prüfungsziel beinhaltet auch, in der Lage zu sein, zwischen einer Neucompilation und einem Patch zu unterscheiden, sowie Kernel Module zu compilieren und konfigurieren.

Schlüsseldateien, Begriffe und Hilfsmittel beinhalten:

  • patch
  • make
  • /usr/src/linux
  • /proc/sys/kernel
  • modprobe
  • /etc/conf.modules /etc/modules.conf
  • insmod, lsmod
  • kmod
  • kerneld

Die notwendigen Fähigkeiten, einen Kernel zu compilieren und zu patchen sind in den beiden vorhergehenden Kapiteln genau durchgesprochen worden, müssen hier also nicht nocheinmal behandelt werden. Die etwas mißverständliche Formulierung dieses Prüfungsziels (Unterscheidung zwischen Compilation und Patch) soll hier aber nochmal etwas genauer dargestellt werden.

Natürlich muß nach dem Aufspielen eines Patches der Kernel neu compiliert werden, wir haben ja im letzten Kapitel gehört, dass ein Patch nur die Quellcode-Dateien verändert. Es gilt aber zu unterscheiden, wann tatsächlich ein Patch notwendig ist und wann eine einfache Neucompilation ausreicht.

Jeder Kernel kann ja – wie beschrieben – auf drei verschiedene Weisen (make config | menuconfig | xconfig) konfiguriert werden. Wenn also z.B. ein bereits installierter Kernel eine neue Fähigkeit benötigt, die er vorher nicht hatte (etwa die Unterstützung einer bestimmten neuen Soundkarte, Netzwerkkarte, eines neuen Dateisystems o.ä.), dann reicht in der Regel eine Neucompilation des Kernels bzw. oft auch schon die Compilation des entsprechenden Moduls. Wir müssen also nur die gewünschte Konfiguration erstellen und danach entweder nur die neuen Module (make modules; make modules_install) oder den Kernel compilieren.

Sollte tatsächlich eine Neucompilation des Kernels nötig sein, so ist danach selbstverständlich auch eine erneute Einrichtung dieses Kernels im Bootmanager lilo nötig. Auch dieser Vorgang wurde bereits genau beschrieben (siehe Compilieren eines Kernels).

Erst wenn der installierte Kernel eine bestimmte Fähigkeit gar nicht erst anbietet oder nur fehlerhaft unterstützt, dann ist ein Upgrade mittels Patch zu überdenken. Vorher sollte aber genau ermittelt werden, ob ein bestimmter Patch diese erwünschte Fähigkeit auch wirklich zur Verfügung stellt. Bei den offiziell vorgestellten Patches (unter http://www.kernel.org/pub/linux/kernel/ existieren für jeden Patch eine Datei mit Namen ChangeLog-x.xx.xx, die genau beschreibt, welche Veränderungen der jeweilige Patch tatsächlich bringt.

Module

In den meisten Fällen werden Veränderungen am Kernel nur dadurch notwendig, weil ein neues Stück Hardware angesteuert werden muß oder eine neue Fähigkeit erwünscht wird. In fast all diesen Fällen reicht es aus, statt dem ganzen Kernel nur das jeweilige Modul zu compilieren und zu installieren. Dabei ist dann auch keine Änderung am Bootmanager vorzunehmen, es reicht das jeweilige Modul zu laden.

Module compilieren und installieren

Wie schon im Kapitel Compilieren eines Kernels dargestellt, können die Fragen nach den gewünschten Fähigkeiten eines Kernels während der Konfiguration nicht nur mit Ja (y) oder Nein (n) beantwortet werden, sondern in vielen Fällen auch mit Modul (m). Das bedeutet, dass eine bestimmte Fähigkeit nicht fest in den Kernel eingebaut, sondern als ladbares Modul erstellt werden soll.

Manche Distributionen haben so schon alle denkbaren Module fertig compiliert beigefügt, andere verzichten auf diesen Service. In diesem zweiten Fall müssen die gewünschten Module also noch compiliert werden. Dazu werden mit der bevorzugten Konfigurationsmethode (config | menuconfig | xconfig) die gewünschten Fähigkeiten des Kernels auf m für Modul gesetzt und anschließend die Befehle

  make modules
  make modules_install

eingegeben. Der erste Befehl compiliert die Module, der zweite kopiert sie in die entsprechenden Verzeichnisse unter /lib/modules/Kernelversion/. Außerdem führt der zweite Befehl noch ein depmod aus, dass die Abhängigkeiten der Module untereinander klärt.

Module manuell laden

Um jetzt ein Modul zu laden, kann einfach der Befehl

  insmod Modulname

eingegeben werden, wobei darauf zu achten ist, den jeweiligen Modulnamen ohne die Endung .o anzugeben. Um also das Modul für eine NE2000 kompatible Netzwerkkarte zu laden, das ne.o heißt, geben wir nur den Befehl

  insmod ne

ein. Um zu sehen, ob das Modul geladen wurde, können wir den Befehl lsmod benutzen, der uns eine Liste aller geladenen Module ausgibt. Um das Modul schließlich wieder zu entfernen genügt ein

  rmmod ne

und das Modul wird aus dem Speicher entfernt (sofern es nicht gerade in Benutzung ist).

Viele Module sind heute aber sehr komplex und benötigen eventuell andere Module, um überhaupt arbeiten zu können. So entstehen also Abhängigkeiten, die ja – wie oben gesehen – durch den Befehl depmod ermittelt wurden. Damit diese Abhängigkeiten nicht zu unerwünschten Komplikationen führen, gibt es den Befehl modprobe, der wie insmod funktioniert, jedoch automatisch alle Module mitläd, die von dem gewünschten Modul benötigt werden. Aus diesem Grund wird heute der Befehl insmod praktisch kaum noch verwendet und stattdessen mit modprobe gearbeitet.

Module automatisch laden lassen

Noch eleganter ist es, den Kernel selbst die Module laden zu lassen, wenn er sie benötigt. Um diese Fähigkeit zu ermöglichen, gab es bei den Kernels der 2.0.x Serie einen eigenständigen Daemon, der sich um das Laden von Modulen kümmerte, den sogenannten kerneld. Wenn dieser Kerneldaemon geladen war, dann hat der Kernel selbst die Module geladen, die er gerade brauchte. Dazu bediente er sich einfach wiederum des modprobe Befehls.

Die neueren Kernel ab der Version 2.2 bieten statt des Kerneldaemons einen anderen Weg an, diese Fähigkeit zu realisieren. Es handelt sich dabei nicht um einen eigenständigen Daemon, sondern stattdessen um einen sogenannten Thread mit Namen kmod. Damit dieser Thread arbeitet, muß er in der Kernelkonfiguration aktiviert werden (unter Loadable Module Support – CONFIG_KMOD=y)

Auch dieser Thread benutzt wiederum einfach den modprobe Befehl um die notwendigen Module zu laden. Damit der Kernel auch weiß, wo der Befehl modprobe tatsächlich ist, kann ihm das mit

  echo "/sbin/modprobe" > /proc/sys/kernel/modprobe

mitgeteilt werden.

Module konfigurieren

Viele Module sind faktisch Gerätetreiber für bestimmte Hardware. Bei älterer Hardware (insbesondere ISA-Erweiterungskarten) war es notwendig, die verwendeten Ressourcen wie IRQs, DMA-Kanäle und I/O-Adressen genau zu kennen. Damit die entsprechenden Module für diese Erweiterungskarten beim Laden diese Information haben, können ihnen Parameter mitgegeben werden. Ein Modul wie das der NE2000 Netzwerkkarte aus dem Beispiel oben könnte also folgendermaßen geladen werden:

  modprobe ne io=0x320 irq=7

Diese Angaben erschweren aber das automatische Laden erheblich, der Kernel kann ja nicht wissen, welche Adressen und Ressourcen eine Karte benutzt. Genausowenig kann er wissen, welche Netzwerkkarte tatsächlich installiert ist und damit welches Modul er laden soll, wenn ein Zugriff auf eine Netzwerkkarte stattfindet.

Um dieses Problem zu lösen, können Informationen über die gewünschten Module in der Datei /etc/modules.conf abgelegt werden. Bei einigen älteren Linux-Distributionen heißt diese Datei stattdessen conf.modules. Die Datei enthält verschiedene Informationen, darunter fallen:

  • welches Modul wird geladen, wenn ein bestimmtes Gerät benutzt wird
  • welche Optionen benötigt ein bestimmtes Modul
  • welche Module müssen vor oder nach einem bestimmten Modul noch geladen werden.

Dazu stehen uns verschiedene Mechanismen zur Verfügung. Um die erste Frage zu klären benutzen wir den Alias-Mechanismus. Um etwa klarzustellen, dass unsere erste Netzwerkkarte eine NE2000 kompatible Karte ist und die zweite eine 3COM Karte könnten wir in diese Datei eintragen:

  alias eth0 ne
  alias eth1 3c503        

Die eigentlichen Optionen werden dann mit Hilfe der folgenden Anweisungen angegeben:

  options ne    io=0x320 irq=7
  options 3c503 io=0x280 irq=5 xcvr=0

Welche Optionen für welches Modul zur Verfügung stehen lässt sich entweder über die entsprechende Dokumentation herausbekommen, oder über den Befehl modinfo.