2012-02-29 695 views
10

我想编译一个“hello world”内核模块的例子, 在ubuntu 11.04,kernel 3.2.6,gcc 4.5.2和fedora 16上发现的问题,kernel 3.2.7,gcc 4.6.7。模块编译:asm/linkage.h文件没有找到

代码:

#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 

错误:

In file included from /usr/src/linux/include/linux/kernel.h:13:0, from /usr/src/linux/include/linux/cache.h:4, from /usr/src/linux/include/linux/time.h:7, from /usr/src/linux/include/linux/stat.h:60, from /usr/src/linux/include/linux/module.h:10, from hello.c:1: /usr/src/linux/include/linux/linkage.h:5:25: fatal error: asm/linkage.h: file not found

后来我发现在/ usr/src/linux中/包括/没有文件夹命名'asm',但'asm​​-generic'; 所以我做了一个软链接“ASM”到“ASM-通用的”,并编译agail:

这一次的错误是:

In file included from /usr/src/linux/include/linux/preempt.h:9:0, from /usr/src/linux/include/linux/spinlock.h:50, from /usr/src/linux/include/linux/seqlock.h:29, from /usr/src/linux/include/linux/time.h:8, from /usr/src/linux/include/linux/stat.h:60, from /usr/src/linux/include/linux/module.h:10, from hello.c:1: /usr/src/linux/include/linux/thread_info.h:53:29: fatal error: asm/thread_info.h: file not found

于是我意识到我错了,但是为什么呢? T_T

回答

7
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

而且看到差异beetween你的编译器调用,你可以

cat /lib/modules/$(shell uname -r)/build/Makefile 

并分析输出

1

asm应该是您正在编译的实际架构的链接,而不是asm-generic
您无法编译通用内核模块,该模块可用于通用体系结构。您必须针对您要使用的特定架构进行编译。

我不知道为什么asm不存在。应该创建它作为配置过程的一部分。
如果以其他方式配置不完整,稍后可能会出现其他错误。

+0

删除我已经检查了3台机器内核的src文件夹(3.2+)与Ubuntu,Fedora和gentoo,它们都不包含文件夹'asm'。所以我认为这可能不是一个错误.. – 2012-02-29 08:17:12

+2

在我检查过的Redhat中,'/ usr/src/kernels /.../include/asm'是一个到'asm-x86_64'的链接。 – ugoren 2012-02-29 10:43:49

2
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模块。

+3

我知道这可以工作,但为什么它不工作在我的方式? “gcc -D__KERNEL__ -I/usr/src/linux/include/-DMODULE -Wall -O2 -c hello.c -o hello.o” – 2012-02-29 09:26:59

-1

模块编译有道: asm/linkage.h文件未找到

这意味着这个特定的文件没有在指​​定的DIR中找到,当我们在make中使用-I选项时,它会被指定。

我们可以将asm-generic链接到asm,如果所有头文件都存在于asm-generic中,或者我们可以使用make utility

在构建内核模块的情况下,首选Make实用程序。

在工作目录中创建一个'Makefile'。阅读的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 

使用-C选项将变为DIR。

因此,为了避免此错误,使用-C选项与DIR /lib/modules/$(shell uname -r)/build

通过这个程序将能够找到所需的文件,你会得到hello.ko文件。

您可以添加此通过

sudo insmod hello.ko 

内核模块同样可以通过

sudo rmmod hello