"Out-of-tree" kernel module

Hallo

Ich versuche ein externes linux kernel module zu kompilieren.
Da ich es nicht hinbekommen habe, bin ich diesem Tutorial gefolgt:
Compiling Kernel Modules
(und auch Linux/Documentation/kbuild/modules.txt - Linux Cross Reference - Free Electrons sowie einigen Distributionsspezifischen Tutorials)

Ich habe das HelloWorld der vorherigen Seite copy-pasted. Es funktioniert leider immer noch nicht:

Als test.c (wie gesagt copy-pasted):
Code:
/*  
 *  hello-1.c - The simplest kernel module.
 */
#include <linux/module.h>    /* Needed by all modules */
#include <linux/kernel.h>    /* Needed for KERN_INFO */
int init_module(void)
{
    printk(KERN_INFO "Hello world 1.\n");
    /* 
     * A non 0 return means init_module failed; module can't be loaded. 
     */
    return 0;
}
void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world 1.\n");
}
Dann ein Makefile erstellt:
Makefile:
Code:
obj-m += test.o
Und dann versucht:

$ make

Wie es in angegebenem Link heisst, leider gibt er dann:
$ make *** Keine Targets. Schluss.
aus. Nach einigen weiteren Versuchen mit derselben Ausgabe habe ich versucht:

make -C . M=$PWD test.o

Dann gibt er:

make: Entering directory '/home/ktest'
cc -c -o test.o test.c
test.c:4:54: fatal error: linux/module.h: Datei oder Verzeichnis nicht gefunden
#include <linux/module.h> /* Needed by all modules */
^
compilation terminated.
<builtin>: recipe for target 'test.o' failed
make: *** [test.o] Error 1
make: Leaving directory '/home/fabi/Downloads/kmaketest'

aus. Ich habe noch ein paar abwandlungen dieses Befehles versucht. Ich habe es auch mit einem Kbuild statt einem Makefile versucht. Nichts hat geholfen.
Kann es sein das mir irgendein Paket fehlt? Ja linux/kernel.h laut der Fehlermeldung, ich dachte aber, dass die "Magic" hinter "obj-m" dies genau erledigen soll. Die Doku ist leider ungenügend. Zum Beispiel heisst der Befehl in einigen Tutorials:
obj-m := <filename>.o
in anderen:
obj-m += <filename>.o
(ich habe natürlich beides vergeblich versucht).

Wäre natürlich toll, wenn mir jemand einen Hinweis oder mögliche Fehlerquellen nennen könnte.

Ich mache das auf Debian in Virtualbox mit Kernelversion 3.16.0

Grüsse
 
Zuletzt bearbeitet:
Hast du das kernel-headers-Paket installiert? Das Fehlen der modules.h deutet darauf hin, dass dem nicht so ist.
 
Hi bitmuncher

Danke für die schnelle Antwort!
Ich habe das zwar in einem Tutorial gesehen, dort hiess es aber dass sei erst für das laden in den Kernel nötig, daher bin ich das übergangen.

Leider kann er gerade das in module.h offenbar aliased Symbol 'g_VBoxGuestPciId' nicht auflösen. Ich versuche das Problem zu lösen und melde mich dann wieder.

Danke nochmals und Grüsse
 
Ich habe das zwar in einem Tutorial gesehen, dort hiess es aber dass sei erst für das laden in den Kernel nötig, daher bin ich das übergangen.
In dem Fall sind die Tutorials falsch oder du hast da was falsch verstanden. Header-Files sind prinzipiell nur zum Kompilieren notwendig. In der Runtime spielen sie keine Rolle mehr. Somit sind sie auch zum Laden der Module irrelevant.

Leider kann er gerade das in module.h offenbar aliased Symbol 'g_VBoxGuestPciId' nicht auflösen. Ich versuche das Problem zu lösen und melde mich dann wieder.

Dieses Symbol sollte in den VBox-Guest-Additions enthalten sein. Ggf. müssen also noch Header von Virtualbox eingebunden werden.
 
Hi bitmuncher

Danke für den Hinweis bzgl. dem include, ja das ist wohl meine Schuld. Je länger ich dran war, desto schneller habe ich Webpages gelesen/überflogen. Hätte ich eigenltlich auch selber wissen sollen :rolleyes:.

Mit dem v_BoxGuestPciId bin ich nicht recht klargekommen und habe dann naiverweise einfach nochmal den Download versucht. Es hat dann auch ohne diese Fehlermeldung geklappt.

Leider bereitet mir das installieren der linux header trotzdem mehr Probleme als gedacht. Ich habe folgendes gemacht:

Code:
$ apt-get update
$ apt-cache search linux-headers-$(uname -r)
Paket gefunden und dann:

Code:
$ apt-get install linux-headers-$(uname -r)
Ausgabe:

Code:
Paketlisten werden gelesen... Fertig
Abhängigkeitsbaum wird aufgebaut.       
Statusinformationen werden eingelesen.... Fertig
linux-headers-3.16.0-4-amd64 ist schon die neueste Version.
0 aktualisiert, 0 neu installiert, 0 zu entfernen und 157 nicht aktualisiert.
Ok, offenbar sind sie installiert. Dann:

Code:
dpgk -l linux-headers
Hier gibt er mir aber...

Code:
||/ Name                                         Version                     Architektur                 Beschreibung
+++-============================================-===========================-===========================-=============================================================================================
un  linux-headers                                <keine>                     <keine>                     (keine Beschreibung vorhanden)
...aus. Wie ich gesehen habe, sollten hier die Linux-headers mit der entsprechenden Versionsnummer angezeigt werden. Sind sie also doch nicht installiert? Ich habe dann danach gesucht:

Code:
$ find / -name headers.h
Er findet sie dann auch tatsächlich in:
/usr/src/linux-headers-3.16.0-4-amd64/include/config/core/dump/default/elf/headers.h
/usr/src/linux-headers-3.2.0-4-amd64/include/config/core/dump/default/elf/headers.h

Dass zwei verschiedene Versionen gefunden wurden hängt vielleicht damit zusammen, dass ich von Debian 6 auf 7 upgradet habe, vermute ich mal ("uname -r" gibt mir die neuere 3.16 Version an). Aber offenbar sind sie vorhanden. Nachdem das compilieren nach wie vor fehlschlug habe ich zusätzlich noch das .deb Paket manuell heruntergeladen und installiert, was ohne Fehlermeldung geklappt hat (Allerdings blieb die Ausgabe von "dkpg -l linux-headers" die gleiche). Dann habe ich versuchsweise den absoluten Pfad der module.h in der test.c eingebunden:

in test.c:
Code:
#include </usr/src/linux-headers-3.16.0-4-common/include/linux/module.h>
Dann nochmals "make test.o" ausgeführt. Jetzt gibt er interessanterweise...:

Code:
/usr/src/linux-headers-3.16.0-4-common/include/linux/module.h:9:24: fatal error: linux/list.h: Datei oder Verzeichnis nicht gefunden
 #include <linux/list.h>
                        ^
compilation terminated.
<builtin>: recipe for target 'test.o' failed
make: *** [test.o] Error 1
...aus. Findet also das offenbar in module.h inkludierte list.h nicht.

Ich habe das ganze auch noch auf einem zweiten, alten Rechner versucht, auf dem Debian 6 als Host läuft mit Kernelversion 3.2. Es verhält sich interessanterweise exakt gleich (gleiche Ausgaben, abgesehen natürlich von Versionsnummern). Daher vermute ich, dass ich irgendwo einen elementaren Fehler mache, vielleicht etwas mit den Umgebungsvariablen o.ä.?

Grüsse
 
Verlinke deine Header in einen der Include-Pfade deines Systems oder gib den Include-Pfad beim Kompilieren mittels '-I' direkt an.
 
Hi

Danke für die schnelle Antwort!

Habe ich dich da richtig verstanden? Du meinst:

in test.c:
Code:
#include </usr/src/linux-headers-3.16.0-4-amd64/include/config/core/dump/default/elf/headers.h>

oder

Code:
$ C_INCLUDE_PATH =/usr/src/linux-headers-3.16.0-4-amd64/include/config/core/dump/default/elf
$ export C_INCLUDE_PATH
resp.

Code:
gcc test.c -o test -l /usr/src/linux-headers-3.16.0-4-amd64/include/config/core/dump/default/elf/headers.h

Die Fehlermeldung bzgl. list.h bleibt bei diesen leider bestehen.

Grüsse
 
Nein, ich meine dass du dem GCC den Include-Pfad als Parameter mitgibst:

Code:
gcc -I/usr/src/linux-headers-3.16.0-4-amd64/include/ ...
 
Ok, Danke für die Info.
Das hat mich ein Schritt weiter gebracht. Danach fand er asm/cache.h nicht. Ich habe das file selber gefunden und zusammen mit /usr/src/linux-headers-3.16.0-4-common/include in $C_INCLUDE_PATH gepackt (und auch in einer 2. Variante nach deinem Tipp mittels -I eingebunden, beide Varianten liefern folgende Fehler).
Jetzt spuckt er mehrere Dutzend Fehler in verschiedenen Headerdateien aus, im Styl von "error: expected ... token" und findet zusätzlich einige andere Header nicht.
Aber ich kann jetzt erst mal weiter basteln, Danke für die bisherige tolle Hilfestellung!

Grüsse
 
Ich habe es inzwischen hinbekommen mit
Code:
make -C /lib/modules/$(uname -r)/build M=$PWD <name>.o
Gibt mir erst den Fehler ".tmp_versions" nicht zu finden, wenn ich das dir aber manuell erstelle und nochmals ausführe klappt es.

Grüsse
 
Zurück
Oben