Aus Linux-Magazin 04/2011

Kernel- und Treiberprogrammierung mit dem Kernel 2.6 – Folge 56

Das Rahmenwerk DKMS ordnet für Anwender und Entwickler Module so, dass sie auch nach einem Kernupdate noch laufen. Als Bonus schnürt das Tool sogar Installationspakete für Distributionen.

Ein Update hat das System zerschossen: Plötzlich funktionieren Drucker, Scanner und andere Geräte nicht mehr, da sie eigene Treiber und Module benötigen. Bringt ein aktualisierter Kernel sie nicht von Haus aus mit, ist die betroffene Peripherie erst einmal nutzlos. Bei Linux sind der Kernel und die Module eins zu eins aufeinander abgestimmt. Passen sie nicht zueinander, lassen sich die Treiber nicht laden, geschweige denn verwenden.

Knigge für die Struktur von Modul-Quellcodes

Als Ausweg aus diesem Schlamassel hatte der PC-Hersteller Dell bereits 2003 für eigene Kunden und als Beitrag zur Linux-Entwicklung den Dynamic Kernel Module Support (DKMS) konzipiert [1]. Einmal installiert wird DKMS bei jedem Update des Kernels aktiv. Das Werkzeug kümmert sich um außerhalb des normalen Kernel-Quellcodes gepflegte Treiber: Sobald der Admin die Treiber angemeldet hat, übersetzt und installiert DKMS sie bei jeder Aktualisierung des Kerns.

Dazu müssen jedoch die Treiber- und Kernelmodul-Programmierer DKMS explizit unterstützen. Zum Glück fällt dies Entwicklern leicht, denn es nützt ihnen, dass die Software als Beigabe automatisch Deb- und RPM-Installationspakete baut.

Um den eigenen Quellcode DKMS anzuvertrauen, muss der Entwickler einige Konventionen einhalten und eine Konfigurationsdatei verfassen. So erwartet DKMS den Quellcode eines Moduls in einem Unterverzeichnis von »/usr/src/« . Sein Name setzt sich aus Paket und Versionsnummer zusammen.

DKMS organisiert Module nämlich in Paketen, die eine eindeutige Version haben. Ein Paket darf dabei auch mehrere Module beinhalten. Enthält ein Paket nur ein Modul, legt der Entwickler seinen Quellcode direkt in dem neuen Ordner ab. Ansonsten erhält jedes Modul ein eigenes Unterverzeichnis.

Prominentes Beispiel dafür ist die Virtualisierungslösung Virtual Box: Das Paket nennt sich »vboxhost« und seine Version von Anfang Februar ist »4.0.0« . Damit lautet das Paketverzeichnis »/usr/src/vboxhost-4.0.0/« . Da Virtual Box für den Betrieb den Basistreiber »vboxdrv« , den Treiber für die virtuelle Netzwerkkarte »vboxnetadp« sowie einen für den Netzfilter »vboxnetflt« mitbringt, befinden sich unterhalb des Paketverzeichnisses drei Ordner mit diesen Namen (siehe Abbildung  1).

"Abbildung

Pflegehinweise beachten

Auch wenn ein Paket mehrere Module hat, erwartet DKMS pro Paket genau eine Konfigurationsdatei. Sie trägt den Namen »dkms.conf« und befindet sich direkt im Paketverzeichnis. Einstellungen macht der Systemverwalter in Form von Variablenzuweisungen – das als Bash-Skript verfasste Tool verleibt sich die Datei per »source« ein. Die Modulverwaltung erfordert mindestens Angaben zum Paketnamen, zur Version und zu den Modulnamen (siehe Listing  1). Die durch »yes« aktivierte Variable »AUTOINSTALLER« sorgt letztlich dafür, dass DKMS beim nächsten Kernelupdate alle betroffenen Module passend übersetzt und installiert.

Listing 1

Demo-Modul für DKMS

01 /* Dummy-Modul erklärt Funktionsweise von DKMS: */
02 #include <linux/module.h>
03
04 static int __init lm_init(void)
05 {
06     printk("Linux-Magazin Modulinitialisierung\n");
07     return 0;
08 }
09
10 static void __exit lm_exit(void)
11 {
12     printk("Linux-Magazin Deinitialisierung\n");
13     return;
14 }
15
16 module_init(lm_init);
17 module_exit(lm_exit);
18 MODULE_LICENSE("GPL");

Ubuntu kennt das praktische Subsystem in seinem Repository als Paket »dkms« , das ein gleichnamiges Tool installiert. Es beherrscht insgesamt 13 Kommandos, im Alltag benötigen Entwickler und Admins aber nur die acht Befehle aus Abbildung  2 (siehe Kasten “Hinter den Kulissen”). Getreu dem Grundprinzip, Linux möglichst unangetastet zu lassen und Änderungen rückgängig machen zu können, übernimmt DKMS seine zu verwaltenden Module in eine eigene Datenbasis, die es unterhalb von »/var/lib/dkms/« speichert.

Hinter den Kulissen

Ein 4000-Zeilen-Bash-Skript bildet das Rückgrat von DKMS. Es legt Kopien der Originaldateien an, überprüft, ob die Voraussetzungen zum Generieren eines Moduls erfüllt sind, übersetzt es für mehrere Kernelversionen, kopiert das Ergebnis in die zugehörigen Verzeichnisse und lädt das Modul – falls gewünscht – in den aktuell laufenden Betriebssystemkern. DKMS erzeugt auch initiale Ramdisks [2]. Es passt die Konfigurationsdateien für das Laden der Module in »/etc/modprobe.d/« an, falls sie Parameter benötigen oder Anwender sie per Alias ansprechen sollen.

Neben den modulspezifischen Konfigurationen findet DKMS im Ordner »/etc/dkms/« in der Datei »framework.conf« seine globale Konfiguration vor. Zu ihr gehören die Pfade zum Quellcode, wohin das Werkzeug die erzeugten Module speichern soll und wo temporäre Dateien residieren. Sämtliche Konfigurationen, sowohl die modulspezifischen als auch die globalen, bindet DKMS über Shellvariablen ein. Im Verzeichnis »/etc/dkms/« liegen außerdem Template-Dateien, die die Paketierung benötigt. Typischerweise muss der Entwickler sie jedoch nicht anfassen.

Automatisch in die Aktualisierung einbinden

Neben dem eigentlichen Tool »dkms« gehört noch das Skript »dkms_autoinstaller« zum Projekt. Ein Dreizeiler im Verzeichnis »/etc/kernel/postinst.d/« startet es auf einem Ubuntu-System. Das Skript wiederum durchsucht per »find« alle unter »/var/lib/dkms/« liegenden Konfigurationen mit dem Namen »dkms.conf« . Steht in einer der Konfigurationsdateien die Variable »AUTOINSTALL« auf »yes« , ruft der automatische Installateur die Kommandos »dkms build« und »dkms install« auf.

DKMS arbeitet die skizzierten Kommandos nicht plump ab, sondern passt sie je nach Distribution an und kennt dazu RPM-basierte Systeme wie Red Hat, Fedora oder Open Suse genauso wie Debian-Derivate. Ein dediziertes Fehlermanagement sorgt für den reibungslosen Betrieb: Dazu gehört, dass das Tool beispielsweise vorhandene Module gleichen Namens sichert und später bei Bedarf wieder zurückspielt.

"Abbildung

Der Aufruf von »dkms add« pflegt ein neues Modul in die Datenbasis ein. Dazu legt das Tool ein Directory für das neue Paket und anschließend ein Unterverzeichnis für die zugehörige Version an. Ein symbolischer Link verweist auf das Quellcode-Verzeichnis mit der Datei »dkms.conf« . Weil es Paketname und Version aufspaltet, verwaltet DKMS übersichtlich mehrere Releases der gleichen Komponente.

Eigene Module hinzufügen

Wer unterhalb des Ordners »/usr/src/« ein neues Verzeichnis mit beispielsweise dem Namen »linuxmagazin-20110113« anlegt und darin den Quellcode eines Moduls (Listing  1), ein passendes Makefile (Listing  2) sowie schließlich die DKMS-Konfiguration (siehe Listing  3 und Kasten “DKMS konfigurieren”) ablegt, kann die Wirkungsweise leicht verfolgen (Abbildung  3). Der Aufruf

Listing 3

Konfigurationsdatei dkms.conf

01 # dkms.conf
02 PACKAGE_NAME="linuxmagazin"
03 PACKAGE_VERSION=20110113
04 AUTOINSTALL=yes
05
06 BUILT_MODULE_NAME[0]="linuxmagazin"
07
08 # Distributionen werten die nachfolgende Variable
09 # in aktuellen Versionen nicht mehr aus. Ubuntu
10 # installiert das Modul unter
11 # /lib/modules/Kernelversion/updates/
11 DEST_MODULE_LOCATION[0]="/updates"

DKMS konfigurieren

Um ihre Module besser zu ordnen, konfigurieren Systemverwalter DKMS-Pakete durch das Zuweisen von Shellvariablen. Die Datei »dkms.conf« im Hauptverzeichnis des betroffenen Pakets nimmt dank Variablenfeldern auf Wunsch auch Angaben für mehrere Module auf einmal auf, wenn sie alle zu einem Paket gehören. Dann versehen Admins die vorbestimmten Variablen – beginnend bei 0 – mit einer laufenden Nummer. Tabelle  1 stellt die wichtigsten Attribute vor.

Listing 2

Zugehöriges Makefile

01 ifneq ($(KERNELRELEASE),)
02 obj-m    := linuxmagazin.o
03 else
04 KDIR    := /lib/modules/$(shell uname -r)/build
05 PWD     := $(shell pwd)
06
07 default:
08         $(MAKE) -C $(KDIR)       M=$(PWD) modules
09 endif
10
11 clean:
12         rm -f *.o *.ko  .*.d .*.cmd *.mod.c
13         rm -f modules.order Module.symvers
14         rm -rf .tmp_versions

"Abbildung

dkms add -m linuxmagazin -v 20110113

erzeugt den neuen Ordner »/var/lib/dkms/linuxmagazin/« mit dem Namen des Pakets und der Version als Unterverzeichnis »20110113« .

Um das Modul zu erzeugen, ruft der Entwickler das Werkzeug mit »dkms build« und den Optionen »-m« für Modulname sowie »-v« für Version auf:

dkms build -m linuxmagazin -v 20110113

Das Skript kopiert den unter »/usr/src/linuxmagazin-20110113/« liegenden Quellcode ins Verzeichnis »/var/lib/dkms/linuxmagazin/20110113/build/« und ruft dort »make« auf, um die Module zu übersetzen. Der ursprüngliche Quellcode bleibt dabei unverändert. DKMS protokolliert alle Ausgaben des Buildvorgangs in »make.log« , sodass ein Admin später die Ursache von Fehlern erkunden kann. Das fertige Produkt legt DKMS in

/var/lib/dkms/linuxmagazin/20110113/Kernelversion/Kernelarchitektur/module/

ab – repräsentiert durch die Variable »BUILT_MODULE_NAME« in der Konfigurationsdatei »dkms.conf« . Die Installation an die üblichen Stellen für den Produktivbetrieb gibt der Systemverantwortliche durch den Befehl

dkms install -m linuxmagazin -v 20110113

in Auftrag. Das Werkzeug prüft zunächst, ob es bereits ein Modul mit gleichem Namen gibt. Ist das der Fall, überschreibt es das gleichnamige Modul nicht einfach, sondern sichert es zuvor. Entfernt der Systemverwalter ein Modul wieder, kopiert »dkms« den Originalcode zurück. Die Software legt die generierten Module übrigens im Verzeichnis »/lib/modules/Kernelversion/updates/« ab.

Hat er das Modul erfolgreich installiert, lädt es der Anwender mit

modprobe linuxmagazin

in den Kernel. Entwickler freut, dass sie auch Module für einen anderen als den gerade laufenden Kernel erzeugen dürfen. Dazu reicht es, mit der Option »-k« die gewünschte Kernelversion anzugeben – die zugehörigen Header und Konfigurationen müssen auf dem System unter »/usr/src/linux-2.6.x« und »/usr/src/linux-headers-2.6.x-y« installiert sein.

Nach dem erstmaligen Einpflegen übernimmt das Skript »dkms_autoinstaller« die Kontrolle über DKMS. Der distributionsspezifische Updatemechanismus ruft es auf. Der Auto-Installer führt fortan die Subkommandos »build« und »install« in der beschriebenen Weise mit jedem neuen Kernelupdate automatisiert und ohne Benutzerinteraktion aus.

Änderungsschneiderei

Das klappt natürlich nur, solange es keine großen Modifikationen an den verwendeten Kernelschnittstellen gibt. Überarbeitet Linus Torvalds sie jedoch, benötigen Anwender zwangsläufig eine im Quellcode angepasste Version des Moduls. Diese automatisiert im Internet zu suchen und einzuspielen, beherrscht DKMS zurzeit allerdings nicht.

Wer in Handarbeit die aktualisierte und zum neuen Kernel passende Version besorgt hat, deinstalliert oder entfernt zunächst die bisher verwendete Variante. Dazu bietet »dkms« die Kommandos »uninstall« und »remove« an. Remove ist das Gegenstück zu »add« . DKMS löscht damit den kompletten Dateibaum für das Modul unterhalb von »/var/lib/dkms/« , der Code unter »/usr/src/« bleibt erhalten:

dkms remove -m linuxmagazin -v 20110113-k 2.6.32-26-generic

Danach gibt der Admin per »add« die neue Version in die Obhut von DKMS. Die folgenden »build« und »install« generieren und installieren das Modul.

DKMS ist ziemlich flexibel und beherrscht noch deutlich mehr als die dargestellten Basisfunktionen: So lassen sich Modulparameter in den Konfigurationsdateien unterhalb von »/etc/modprobe.d/« ebenso einrichten wie Aliase. Das Werkzeug generiert Module für ganz bestimmte Kernelversionen und legt auf Wunsch eine initiale Ramdisk an. Sind Patches in der Konfiguration aufgeführt, wendet DKMS sie auf den Quellcode an. An wichtigen Stellen im Buildprozess lassen sich außerdem externe Kommandos ausführen.

Alles einpacken

Die Unterkommandos »mkdeb« , »mkdsc« und »mkrpm« erleichtern dem Entwickler die Arbeit erheblich, denn sie schnüren Installationspakete für Debian- und Red-Hat-basierte Linux-Varianten. Dazu braucht der Entwickler im Idealfall nicht einmal etwas zu konfigurieren. Auf dem Rechner benötigt er natürlich die notwendige Software für das Paketebauen, bei Ubuntu beispielsweise das Paket »deb-helper« . Der Aufruf

dkms mkdeb -m linuxmagazin -v 20110113--source-only

erzeugt ein Debian-Paket mit dem Namen »linuxmagazin-dkms_20110113_all.deb« und legt es im Verzeichnis »/var/lib/dkms/linuxmagazin/20110113/deb/« ab (siehe Abbildung  4). Das »all« im Namen bedeutet, dass alle Kernelversionen das Paket akzeptieren. Die Option »source-only« ist nicht unbedingt notwendig, stellt aber sicher, dass nur der Modul-Quellcode, nicht aber das bereits generierte Modul in das Debian-Paket kommt. Dadurch generiert DKMS das Modul auf jeder Plattform neu. Natürlich muss auf jedem Zielsystem ebenfalls das Paket »dkms« installiert sein. Glücklicherweise ist jedes erzeugte Paket bereits von »dkms« abhängig, sodass der Paketmanager automatisch alles Notwendige auf dem Zielsystem installiert.

Abbildung 4: DKMS reicht ein einziges Kommando aus, um beispielsweise ein Debian-Paket zu schnüren. Eine weitere Funktion baut auch RPM-Pakete – praktisch für Modulanbieter, um viele Anwender anzusprechen.

Abbildung 4: DKMS reicht ein einziges Kommando aus, um beispielsweise ein Debian-Paket zu schnüren. Eine weitere Funktion baut auch RPM-Pakete – praktisch für Modulanbieter, um viele Anwender anzusprechen.

Module ordentlich im Griff

Der Dynamic Kernel Module Support löst das Problem, den Kernel und extern gepflegte Module auf gleichem Stand zu halten. Modul-Anbieter für Nvidia, Virtualbox oder Batman, das Routingprotokoll der Freifunk-Szene, nutzen das Verfahren bereits. Trotzdem ist es bei vielen Entwicklern noch unbekannt. Admins, Anwender und Entwickler profitieren davon, wenn sich das ändert. (mg)

Infos

  1. Dynamic Kernel Module Support (DKMS): http://linux.dell.com/dkms/
  2. Eva-Katharina Kunst, Jürgen Quade, “Kern-Technik: Initramfs”, Folge 39: Linux-Magazin 05/08, S. 98

Der Autor

Eva-Katharina Kunst, Journalistin, und Jürgen Quade, Professor an der Hochschule Niederrhein, sind seit den Anfängen von Linux Fans von Open Source. Demnächst erscheint die dritte Auflage ihres Buches “Linux Treiber entwickeln”.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben