web-dev-qa-db-fra.com

Comment inclure des fichiers d'en-tête locaux dans le module de noyau Linux

Dis que j'ai un module mymod avec des fichiers source comme suit:

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

J'essaie d'inclure myMod.h comme suit

#include <mymod.h>

Mon fabricant contient EXTRA_CFLAGS= -I$(Shell pwd)/../inc/ Mais lorsque le noyau est fait, je reçois une erreur indiquant:

mymod.h non trouvé

La raison semble être que lorsque les modules de noyau sont fabriqués cette commande est exécutée à partir du makefile: (en utilisant make v1):

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

Dans d'autres œuvres, ma $(Shell pwd) a été étendue à <path/to/linux>. Ce n'est pas ce que je veux. Comment puis-je spécifier le paramètre -I À pointer sur src/inc De mon mymod arbre source?

17
Om Narasimhan

Les maquillages de noyau Linux utilisent le cadre de Kbuild. Bien que ceux-ci soient interprétés par GNU FAIRE, KBUILD consiste en un grand ensemble de macros avec des conventions d'utilisation particulières, de sorte que les directives de fabrication typiques de Makefile ne s'appliquent pas. La bonne chose à propos de Kbuild est que vous avez besoin de très peu de boiseries compte tenu de la complexité de la tâche.

Kbuild est documentée dans la source du noyau, en Documentation/kbuild . En tant qu'auteur de module, vous devriez lire en particulier modules.txt (et au moins écrémé par les autres).

Ce que vous faites est maintenant ne fonctionne pas parce $(Shell pwd) est étendu lorsque la variable EXTRA_CFLAGS Est utilisé. Étant donné que le maquillage fonctionne de l'arborescence source du noyau plutôt que de votre répertoire de votre module (c'est l'un des nombreux aspects nonobevés de Kbuild), il ramasse le mauvais répertoire.

L'idiome officiel pour spécifier include dans un module hors-arbre est dans §5.3 de modules.txt. La variable src est définie sur le répertoire Toplevel de votre module. Par conséquent:

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

Notez que cette déclaration doit être dans un fichier appelé Kbuild à la racine de votre arbre de module. (Vous voudrez peut-être envisager le répertoire src pour être la racine de votre arborescence de module; si oui, mettez Kbuild là et remplacez la valeur ci-dessus par -I$(src)/inc). Il est également possible de les mettre dans un Makefile, mais cette définition (tant que toute autre chose qui ne s'applique que lorsque la construction d'un module de noyau) doit être dans une directive conditionnelle ifeq ($(KERNELRELEASE),). Voir la section 4.1 de modules.txt.

Si vous ne disposez pas d'un Kbuild fichier déjà et que vous voulez passer à avoir une, lecture de §4.1 modules.txt. Avoir un fichier Kbuild est légèrement plus clair. Ne mettez rien qui s'applique au noyau dans votre maquillage principal, autre qu'une règle d'appel make -C $(KERNELDIR) M=$(pwd). Dans Kbuild, le minimum dont vous avez besoin est la liste des modules que vous construisez (souvent juste celui) et une liste de fichiers à inclure dans votre module, plus une déclaration de dépendance:

EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h

Traditionnellement la voie à #include Les fichiers avec des chemins par rapport au répertoire du code source actuel consiste à utiliser des guillemets plutôt que des crochets:

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

Dans ce cas, le premier #include Référencera le chemin de recherche du compilateur (qui, dans le cas de GCC, est contrôlé par le -I Commutateur de ligne de commande), alors que la seconde apparaît dans le répertoire contenant le fichier source avec le #include.

Ces chemins peuvent aussi être relatifs. Donc, dans src/mod/mymod.c, vous pouvez dire:

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

et il devrait "travailler juste".

Je ne sais pas si cela est une pratique courante dans l'arbre du noyau de Linux, mais c'est sûrement mieux que de vous brouiller avec le chemin incluant, qui pourrait avoir un nombre quelconque d'effets secondaires inattendus.

1
a CVn