加载驱动模块时-1 Unknown symbol …

来源:互联网 发布:广电网络是什么 编辑:程序博客网 时间:2024/05/18 08:54
最简单的示例程序,写两个模块,分别为A和B,在A中导出了一些函数,而在B中使用A导出的函数。模块都使用GPL。
问题是在2.6.22和2.6.24下运行加载都很正常,当在2.6.26内核下加载时却出现了了Unknow symbol inmodule的错误。详见下面的具体描述。

两个模块的源码如下:
C/C++ code
// Module A (mod_a.c)#include<linux/init.h>#include<linux/module.h>#include<linux/kernel.h> static int func1(void) {printk("In Func: %s...\n",__func__); return 0; }// Export symbol func1EXPORT_SYMBOL(func1); static int __inithello_init(void) {printk("Module 1,Init!\n");return 0; }static void __exithello_exit(void) {printk("Module 1,Exit!\n"); }module_init(hello_init); module_exit(hello_exit);


C/C++ code
// Module B (mod_b.c)#include<linux/init.h>#include<linux/kernel.h>#include<linux/module.h> static int func2(void){ extern int func1(void);func1(); printk("In Func:%s...\n",__func__); return 0; }static int __inithello_init(void) {printk("Module 2,Init!\n");func2(); return0; } static void __exithello_exit(void) {printk("Module 2,Exit!\n"); }module_init(hello_init); module_exit(hello_exit);


Makefile for Module A
BatchFile code
obj-m += mod1.o mod1-y:= mod_a.oKVERSION = $(shell uname-r) all: make -C /lib/modules/$(KVERSION)/buildM=$(PWD)modules clean: make -C/lib/modules/$(KVERSION)/buildM=$(PWD)clean rm -f *.o*.ko *.cmd


Makefile for Module B
BatchFile code
obj-m += mod2.o mod2-y:= mod_b.oKVERSION = $(shell uname-r) all: make -C /lib/modules/$(KVERSION)/buildM=$(PWD)modules clean: make -C/lib/modules/$(KVERSION)/buildM=$(PWD)clean rm -f *.o*.ko *.cmd


编译完成后开始加载模块:
BatchFile code
#insmod ./mod1.ko#insmod ./mod2.ko FATAL:Error inserting mod2 (/home/user/test/mod2.ko): Unknownsymbol in module,or unknown parameter(see dmesg)#dmesg[ 7029.008527]mod2: no symbol version for func1[ 7029.008534]mod2: Unknown symbol func1


在 /proc/kallsyms 里可以找到module A导出的symbol。
内核2.6.26版本以前都很正常,只有2.6.26版出现这个错误。
原因:

这是linux kernel 2.6.26 之后版本的bug (详细描述,请看http://bugzilla.kernel.org/show_bug.cgi?id=12446)
并且这个bug不会被fix

解决办法是把mod_a的Module.symvers放到mod_b的当前路径,从而编译mod_b,符号信息会自动连接进去.
或者在mod_b的makefile中使用KBUILD_EXTRA_SYMBOLS指定mod_a的Module.symvers,如:
KBUILD_EXTRA_SYMBOLS=/mod_a/Module.symvers

编译mod_b时,搜索Module.symvers的路径是:
1, kernel source path, e.g. /usr/src/kernels/linux-2.6.28.10
2, makefile中M=所指定的路径, 它等效于变量KBUILD_EXTMOD的值
3, 变量KBUILD_EXTRA_SYMBOLS的值
0 0
原创粉丝点击