因此,我尝试在 Ubuntu 18.04、内核 4-15.32 通用上编译一个简单的内核模块:
#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");
}
请注意,我确实有<linux/kernel.h>
,因为论坛上有参考资料说,当我遇到错误时,这是一个经常遗漏的问题,但在这种情况下,我没有遇到这个问题。用编译这个会gcc -o hello.o hello.c
导致implicit declaration of function 'printk'
错误。
所以问题是我究竟如何才能编译这个最基本的内核模块?
答案1
问题解决了,并吸取了几个教训:
“您必须使用您正在编译的内核的内核头文件。使用默认的内核头文件
/usr/include/linux
将不起作用”(来源)gcc
不建议直接使用编译- 内核有内核构建系统:“外部模块的作者应该提供一个隐藏大部分复杂性的 makefile,因此只需输入“make”即可构建模块。”$(PWM)
由于某种原因不起作用,但是$(shell pwm)
有效。(发现这里)。这也起到了一定作用,M=$(PWM)
因为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.
错误。此外,每内核文档也可以做
<pre><code>
make -C /lib/modules/`uname -r`/build M=$PWD
</code></pre>
but haven't tried that.
我使用过的 Makefile:
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) clean
生成的模块按预期工作,可以插入和删除,并打印出好听的消息“<1> Hello World”和“<1> Goodbye” dmesg
。