J'essaie donc de compiler un module de noyau simple sur Ubuntu 18.04, noyau 4-15.32 générique:
#define MODULE
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void){
printk("<1> Hello,World\n");
return 0;
}
void cleanup_module(void){
printk("<1> Goodbye.\n");
}
Notez que j’ai <linux/kernel.h>
, car il est mentionné sur les forums qu’il s’agit d’une omission fréquente lorsqu’une erreur se produit, mais dans ce cas, je n’ai pas ce problème. Compiler ceci avec gcc -o hello.o hello.c
entraîne l'erreur implicit declaration of function 'printk'
.
La question est donc de savoir comment obtenir exactement la compilation de ce module de noyau le plus élémentaire.
Problème résolu avec un couple de leçons apprises:
"Vous devez utiliser les en-têtes du noyau avec lequel vous compilez. L'utilisation de la valeur par défaut /usr/include/linux
ne fonctionnera pas" ( source )
Compiler directement avec gcc
n'est pas recommandé - Le noyau a kbuild system : "L'auteur d'un module externe doit fournir un fichier makefile qui cache la plus grande partie de la complexité, il suffit donc de taper" make "pour construire le module."
$(PWM)
pour une raison quelconque ne fonctionne pas, mais $(Shell pwm)
fonctionne. (trouvé ici ). Cela a également joué un rôle parce que M=$(PWM)
donnerait
make[2]: *** No rule to make target 'Arch/x86/entry/syscalls/syscall_32.tbl', needed by 'Arch/x86/include/generated/asm/syscalls_32.h'. Stop.
erreur. En outre, par documentation du noya on pourrait aussi faire
make -C /lib/modules/`uname -r`/build M=$PWD
mais je n'ai pas essayé ça.
Makefile que j'ai utilisé:
obj-m += hello.o
KDIR := /lib/modules/$(Shell uname -r)/build
all:
$(MAKE) -C $(KDIR) M=$(Shell pwd) modules
clean:
make -C /lib/modules/$(Shell uname -r)/build M=$(Shell pwd) modules
Le module obtenu fonctionne comme prévu et peut être inséré et supprimé avec les messages de Nice "<1> Hello World" et "<1> Au revoir" imprimés en dmesg
.