Treiber Kernel und Module bauen Dr.-Ing. Matthias Sand Lehrstuhl für Informatik 3 (Rechnerarchitektur) Friedrich-Alexander-Universität Erlangen-Nürnberg WS 2010/2011 Treiber Kernel und Module bauen 1/17 2010-10-06
Übersicht Inhalt: Quellenstruktur des Kernels, Build-System, Module, API: Debug-Möglichkeiten. Treiber Kernel und Module bauen 2/17 2010-10-06
Quellenstruktur des Kernels Liegt typischerweise in /usr/src/linux- uname -r /, empfohlen: symbolischer Link von /lib/modules/ uname -r /build zur Kernel-Root, enthält Quellen für alle (offiziell) unterstützten Treiber und Plattformen inzwischen sehr groß (> 250 MB), Quellen für eigene Module müssen nicht in die Kernel-Struktur integriert werden. Treiber Kernel und Module bauen 3/17 2010-10-06
Quellenstruktur des Kernels (2) linux-2.6.32/ arch/ Architekturspezifischer Code block/ Block-Layer-Core crypto/ Verschlüsselungsalgorithmen Documentation/ Kernel-Doku (alt, schlecht, unvollständig...) drivers/ Gerätetreiber firmware/ Firmware-Images fs/ Dateisysteme include/ Header-Dateien init/ Kernel-Initialisierung ipc/ Interprozesskommunikation kernel/ Kern vom Kern lib/ Hilfsfunktionen mm/ Speicherverwaltung net/ Netzwerk-Core und Protokolle samples/ Beispielcode für Modulentwickler etc. scripts/ Build-Skripte security/ Sicherheitsmodule sound/ Audio-System tools/ Performance-Zähler-Subsystem usr/ User-Software des Init-Filesystems virt/ kvm-code Treiber Kernel und Module bauen 4/17 2010-10-06
Build-System Stellt Makefiles und Hilfsskripte zur Verfügung, muss für das aktuelle bzw. Zielsystem konfiguriert sein, um ladbare Module zu generieren, muss man (erstaunlich) wenig über seine Funktionsweise wissen! Konfigurieren, Bauen und Installieren $ cd / u s r / s r c / l i n u x uname r / $ make menuconfig $ make $ make m o d u l e s _ i n s t a l l $ Treiber Kernel und Module bauen 5/17 2010-10-06
Build-System für Module vorbereiten Für Module vorbereiten $ cd / l i b / modules / uname r / b u i l d / $ make d i s t c l e a n $ make o l d c o n f i g $ make modules_prepare Treiber Kernel und Module bauen 6/17 2010-10-06
Minimales Build-System Ziel Bauen von Modulen für aktuellen (bzw. einen bestimmten) Kernel, volle Kernel-Sourcen nicht nötig, trenne Build-Skripte und Kernel-Header von übrigen Sourcen, Viele Distributionen bieten dies als eigenes Paket an (z.b. Debian: linux-headers-2.6-amd64). Treiber Kernel und Module bauen 7/17 2010-10-06
Module Beschreibung Kernelerweiterungen (typischerweise Treiber), zur Laufzeit ladbar mit insmod(8) bzw. modprobe(8), entladen mit rmmod(8). Treiber Kernel und Module bauen 8/17 2010-10-06
Module (2) Minimalanforderungen an den Quelltext Im Modul müssen mindestens folgende Funktionen implementiert werden: int init_module(void) zur Initialisierung, void cleanup_module(void) zur Deinitialisierung, liefert die Initialisierungsfunktion einen von 0 verschiedenen Wert zurück, wird das Modul sofort wieder entladen und die Cleanup-Funktion dabei nicht aufgerufen. Treiber Kernel und Module bauen 9/17 2010-10-06
Module (3) Module vs. Built-In-Treiber Um denselben Quellcode einfach für Modul- und Built-In-Treiber zu verwenden werden Init- und Cleanup-Funktionalität in Funktionen anderen Namens implementiert, mittels der Makros module_init(name) und module_exit(name) dem Build-System die Namen der beiden Funktionen mitgeteilt. Treiber Kernel und Module bauen 10/17 2010-10-06
Module Template dhwk.c #i n c l u d e <l i n u x / v e r s i o n. h> #i n c l u d e <l i n u x / module. h> MODULE_LICENSE( "GPL" ) ; s t a t i c i n t i n i t dhwk_init ( void ) { p r i n t k (KERN_INFO "dhwk : dhwk_init c a l l e d \n " ) ; r e t u r n 0 ; } s t a t i c void exit dhwk_exit ( void ) { p r i n t k (KERN_INFO "dhwk : dhwk_exit c a l l e d \n" ) ; } m o d u l e _ i n i t ( dhwk_init ) ; module_exit ( dhwk_exit ) ; Treiber Kernel und Module bauen 11/17 2010-10-06
Module Makefile Makefile i f n e q ( $ (KERNELRELEASE ), ) obj m := dhwk. o e l s e KDIR := / l i b / modules /$ ( s h e l l PWD := $ ( s h e l l pwd ) uname r )/ b u i l d d e f a u l t : e n d i f $ (MAKE) C $ (KDIR) SUBDIRS=$ (PWD) modules Treiber Kernel und Module bauen 12/17 2010-10-06
Module Template bauen $ cd ~/ my_fancy_driver $ v i dhwk. c $ v i M a k e f i l e $ make <... > $ insmod. / dhwk. ko $ dmesg <... > dhwk : dhwk_init c a l l e d $ Treiber Kernel und Module bauen 13/17 2010-10-06
API: printk printk #include <l i n u x / k e r n e l. h> i n t p r i n t k ( const char fmt,... ) ; Zur Ausgabe von Kernel-/Treibermeldungen, Ausgabe erfolgt in den Kernel-Ringpuffer (vgl. dmesg(8)) und die Logs über den klogd/syslogd-mechanismus, abgespecktes printf(3), zusätzlich: Prioritäten, Makro pr_debug wird zu printk(kern_debug...) aufgelöst, wenn mit -DDEBUG übersetzt wird. Treiber Kernel und Module bauen 14/17 2010-10-06
API: printk Prioritäten Bezeichner Wert Bedeutung KERN_DEBUG "<7>" Debug-Meldung KERN_INFO "<6>" Information KERN_NOTICE "<5>" Wichtiger Hinweis, kein Fehler KERN_WARNING "<4>" Warnung KERN_ERR "<3>" Fehlerzustände aufgetreten KERN_CRIT "<2>" Systemzustand kritisch KERN_ALERT "<1>" Sofortige Maßnahmen nötig KERN_EMERG "<0>" System tot Treiber Kernel und Module bauen 15/17 2010-10-06
API: WARN_ON WARN_ON #include <asm/bug. h> void WARN_ON( c o n d i t i o n ) ; Ist condition erfüllt, wird eine Warnmeldung ausgegeben, Ausgabe umfasst: den Namen der aktuellen Funktion, den Dateinamen, die Zeilennummer, einen Call-Trace. Treiber Kernel und Module bauen 16/17 2010-10-06
API: BUG_ON BUG_ON #include <asm/bug. h> void BUG_ON( c o n d i t i o n ) ; Ist condition erfüllt, wird eine Meldung wie bei WARN_ON ausgegeben, zusätzlich wird die Bearbeitung des Treiber-Codes abgebrochen. Treiber Kernel und Module bauen 17/17 2010-10-06