So fügen Sie lokale Header-Dateien in das Linux-Kernel-Modul ein

17

Angenommen, ich habe ein Modul mymodmit folgenden Quelldateien:

src / mod / mymod.c
src / inc / mymod.h

Ich versuche, mymod.h wie folgt einzuschließen

#include <mymod.h>

Mein Makefile enthält, EXTRA_CFLAGS= -I$(shell pwd)/../inc/aber wenn der Kernel erstellt wird, erhalte ich die Fehlermeldung:

mymod.h nicht gefunden

Der Grund scheint zu sein, dass beim Erstellen von Kernelmodulen dieser Befehl aus dem Makefile ausgeführt wird: (mit makeV1):

make -C <path/to/linux/src> M=<path/to/mymod> modules

In anderen Werken wurde mein zu $(shell pwd)erweitert <path/to/linux>. Das will ich nicht. Wie kann ich den -IParameter angeben, auf den in src/incmeinem mymodQuellbaum verwiesen werden soll?

Om Narasimhan
quelle

Antworten:

19

Die Linux-Kernel-Makefiles verwenden das Kbuild-Framework. Obwohl diese von GNU make interpretiert werden, besteht Kbuild aus einer großen Menge von Makros mit besonderen Verwendungskonventionen, sodass typische Makefile-Richtlinien nicht gelten. Das Schöne an Kbuild ist, dass Sie angesichts der Komplexität der Aufgabe nur sehr wenig Heizplatte benötigen.

Kbuild ist in der Kernelquelle dokumentiert, in Documentation/kbuild. Als Modulschreiber sollten Sie besonders lesen modules.txt(und zumindest die anderen überfliegen).

Was Sie jetzt tun, funktioniert nicht, da $(shell pwd)es erweitert wird, wenn die EXTRA_CFLAGSVariable verwendet wird. Da das Makefile nicht aus dem Verzeichnis Ihres Moduls, sondern aus dem Kernelquellbaum ausgeführt wird (dies ist einer der vielen nicht offensichtlichen Aspekte von Kbuild), wird das falsche Verzeichnis ausgewählt.

Das offizielle Idiom für die Angabe von Include-Verzeichnissen in einem Out-of-Tree-Modul ist in §5.3 von modules.txt. Die srcVariable wird auf das oberste Verzeichnis Ihres Moduls gesetzt. Deshalb:

EXTRA_CFLAGS := -I$(src)/src/inc

Beachten Sie, dass sich diese Deklaration in einer Datei befinden sollte, die im KbuildStammverzeichnis Ihres Modulbaums aufgerufen wird . (Möglicherweise möchten Sie das srcVerzeichnis als das Stammverzeichnis Ihres Modulbaums betrachten. Wenn ja, setzen Sie es Kbuilddort ein und ersetzen Sie den obigen Wert durch. -I$(src)/inc) Es ist auch möglich, sie in a zu setzen Makefile, aber beachten Sie, dass diese Definition (solange alles andere, was nur beim Erstellen eines Kernelmoduls gilt) in einer bedingten Direktive enthalten sein sollte ifeq ($(KERNELRELEASE),). Siehe §4.1 von modules.txt.

Wenn Sie noch keine KbuildDatei haben und zu einer wechseln möchten, lesen Sie §4.1 von modules.txt. Eine separate KbuildDatei ist etwas klarer. Fügen Sie in Ihr Haupt-Makefile nichts ein, was für den Kernel gilt, außer eine Regel, die aufgerufen werden soll make -C $(KERNELDIR) M=$(pwd). Als KbuildMindestanforderung benötigen Sie die Liste der von Ihnen erstellten Module (häufig nur eines) und eine Liste der Dateien, die in Ihr Modul aufgenommen werden sollen, sowie eine Abhängigkeitserklärung:

EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h
Gilles 'SO - hör auf böse zu sein'
quelle
Ich konnte den Beitrag nicht aktualisieren, da ich nicht genug Reputation hatte.
Om Narasimhan
1
@Om Narasimhan: Wenn dies Ihnen geholfen hat, die Lösung zu finden, sollten Sie die Antwort als akzeptiert markieren.
ein
1

Traditionell werden #includeDateien mit Pfaden relativ zum aktuellen Quellcodeverzeichnis in Anführungszeichen und nicht in spitzen Klammern angegeben:

#include <stdio.h>
#include "mygreatfunctions.h"

In diesem Fall #includeverweist der erste auf den Include-Suchpfad des Compilers (der im Fall von gcc von der -IBefehlszeilenoption gesteuert wird), während der zweite auf das Verzeichnis verweist , das die Quelldatei mit dem enthält #include.

Solche Pfade können auch relativ sein. In src / mod / mymod.c können Sie also sagen:

#include "../inc/mymod.h"

und es sollte "einfach funktionieren".

Ich weiß nicht, ob dies im Linux-Kernelbaum üblich ist, aber es ist sicherlich besser, als mit dem Include-Pfad herumzuspielen, der eine beliebige Anzahl von unbeabsichtigten Nebenwirkungen haben könnte.

ein CVn
quelle
1
Gute Ratschläge im Allgemeinen, jedoch sind Linux-Kernel-Makefiles sehr eigenartig. Sie rufen eine ziemlich komplexe Reihe von Makros auf, die als Kbuild bezeichnet werden. Es ist oft am besten, Kbuild als eine Sprache zu behandeln, die fast, aber nicht ganz anders ist als make.
Gilles 'SO- hör auf böse zu sein'
1
Sicher genug, aber das Verhalten des C-Compilers, in einigen konfigurierten Verzeichnissen nach <foo> zu suchen, und nach "bar", das zuerst das aktuelle Verzeichnis ansieht und dann auf den zuvor genannten Pfad zurückfällt, ändert sich nicht durch das, was bizarr heißt der Compiler an erster Stelle.
Vonbrand