我正在尝试编译“hello world”内核模块的示例, 在ubuntu 11.04,内核3.2.6,gcc 4.5.2和fedora 16,内核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:找不到文件
然后我发现在/ usr / src / linux / include /中没有名为'asm'但'asm-generic'的文件夹; 所以我把'asm'软链接到'asm-generic',编译agail:
这次错误是:
在/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
答案 0 :(得分:9)
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 documentation
要查看编译器调用之间的区别,您可以
cat /lib/modules/$(shell uname -r)/build/Makefile
分析输出
答案 1 :(得分:3)
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模块。
答案 2 :(得分:1)
asm
应该是您正在编译的实际架构的链接,而不是asm-generic
的链接。
您无法编译可在通用体系结构上运行的通用内核模块。你必须为你将要使用的特定架构编译它。
我不知道为什么asm
不存在。它应该作为配置过程的一部分创建
如果配置在其他方面不完整,您可能会在以后遇到其他错误。
答案 3 :(得分:0)
asm 包括(例如linkage.h)是特定于体系结构的。在:
下应该有一组目录 /usr/src/kernels/(kernel version goes here)/arch
提供针对要编译的代码的特定CPU体系结构的特定包含。
尝试将此添加到您的Makefile:
KVERSION :=R(shell uname -r)
并添加内核和体系结构(本例中为x86):
INCDIRS = -I./include -I/usr/src/kernels/$(KVERSION)/include -I/usr/src/kernels/$(KVERSION)/arch/x86
答案 4 :(得分:-1)
模块编译:找不到asm / linkage.h文件
这意味着在指定的DIR中找不到此特定文件,当我们在make中使用-I选项时会指定该文件。
如果所有标头都存在于asm-generic中,我们可以将asm-generic链接到asm,或者我们可以使用 make utility 。
在构建内核模块的情况下,首选make实用程序。
创建&#39; Makefile&#39;在工作DIR。
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
在阅读makefile或执行其他任何操作之前,-C选项的使用将更改为指定的DIR。
为避免此错误,请在DIR /lib/modules/$(shell uname -r)/build
通过此,您的程序将能够找到所需的文件,您将获得hello.ko
文件。
您可以通过
将其添加到内核模块sudo insmod hello.ko
同样,您可以通过
删除sudo rmmod hello