我想编译一个“hello world”内核模块的例子,在ubuntu 11.04,kernel 3.2.6,gcc 4.5.2和fedora 16,kernel 3.2.7,gcc 4.6.7上发现的问题。
码:
#include <linux/module.h> #include <linux/init.h> MODULE_LICENSE("GPL"); static int __init hello_init (void) { printk("Hello module init\n"); return 0; } static void __exit hello_exit (void) { printk("Hello module exit\n"); } module_init(hello_init); module_exit(hello_exit);
编译:
gcc -D__KERNEL__ -I /usr/src/linux/include/ -DMODULE -Wall -O2 -c hello.c -o hello.o
错误:
在/usr/src/linux/include/linux/kernel.h:13:0包含的文件/usr/src/linux/include/linux/cache.h:4中,从/ usr / src / linux / include /linux/time.h:7,来自/usr/src/linux/include/linux/stat.h:60,来自/usr/src/linux/include/linux/module.h:10,来自hello.c: 1:/usr/src/linux/include/linux/linkage.h:5:25:致命错误:asm / linkage.h:文件未find
那么我在/ usr / src / linux / include /中find没有名为“asm”但是“asm-generic”的文件夹; 所以我做了一个软链接“asm”到“asm-generic”,并编译了一下:
这一次的错误是:
在/usr/src/linux/include/linux/preempt.h:9:0包含的文件/usr/src/linux/include/linux/spinlock.h:50中,从/ usr / src / linux / include /linux/seqlock.h:29,来自/usr/src/linux/include/linux/time.h:8,来自/usr/src/linux/include/linux/stat.h:60,来自/ usr / src /linux/include/linux/module.h:10,来自hello.c:1:/usr/src/linux/include/linux/thread_info.h:53:29:致命错误:asm / thread_info.h:文件不是发现
所以我意识到我错了,但为什么呢? T_T
obj-m += hello.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
是一个正确的方式来建立模块见kbuild文档
要看到你的编译器调用之间的差异,你可以
cat /lib/modules/$(shell uname -r)/build/Makefile
并分析一个输出
obj-m += hello.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
这里hello.c是你的内核源文件。 只需使用make来构建你的hello.ko模块。
asm
应该链接到你正在编译的实际架构,而不是asm-generic
。
你不能编译一个通用的内核模块,这将在一个通用的体系结构上工作。 您必须针对您要使用的特定架构进行编译。
我不知道为什么asm
不存在。 它应该被创建为配置过程的一部分。
如果以其他方式配置不完整,则以后可能会出现其他错误。
模块编译:没有找到asm / linkage.h文件
这意味着这个特定的文件没有在指定的DIR中找到,当我们在make中使用-I选项时,这个文件被指定。
我们可以将asm-generic链接到asm,如果所有头文件都以asm-generic的形式存在,或者我们可以使用make实用程序。
在构建内核模块的情况下,首选Make实用程序。
obj-m + = hello.o
all:make -C / lib / modules / $(shell uname -r)/ build M = $(PWD)模块
清洁:
使用-C选项将在读取makefile或执行其他任何操作之前更改为指定的DIR。
所以为了避免这个错误,在DIR中使用-C选项“/ lib / modules / $(shell uname -r)/ build”
通过这个你的程序将能够找到所需的文件,你会得到hello.ko文件。
您可以通过添加到内核模块
sudo insmod hello.ko
同样,你可以通过删除
sudo rmmod你好