两个模块,分别为A和B,在A中导出了一些函数,而在B中使用A导出的函数。模块都使用GPL。
问题是在2.6.22和2.6.24下运行加载都很正常,当在2.6.26内核下加载时却出现了了Unknow symbol in module的错误。详见下面的具体描述。
两个模块的源码如下:
// 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 func1
EXPORT_SYMBOL(func1);
static int __init hello_init(void) { printk("Module 1,Init!\n"); return 0; }
static void __exit hello_exit(void) { printk("Module 1,Exit!\n"); }
module_init(hello_init); module_exit(hello_exit); /*********************************/ // 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 __init hello_init(void) { printk("Module 2,Init!\n"); func2(); return 0; }
static void __exit hello_exit(void) { printk("Module 2,Exit!\n"); }
module_init(hello_init); module_exit(hello_exit); /*********************************/ //Makefile for Module A
obj-m += mod1.o mod1-y := mod_a.o
KVERSION = $(shell uname -r)
all: make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules clean: make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean rm -f *.o *.ko *.cmd /*********************************/ //Makefile for Module B
obj-m += mod2.o mod2-y := mod_b.o
KVERSION = $(shell uname -r)
all: make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules clean: make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean rm -f *.o *.ko *.cmd
#insmod ./mod1.ko #insmod ./mod2.ko FATAL: Error inserting mod2 (/home/user/test/mod2.ko): Unknown symbol in module, or unknown parameter (see dmesg) #dmesg [ 7029.008527] mod2: no symbol version for func1 [ 7029.008534] mod2: Unknown symbol func1
|
这是linux kernel 2.6.26 之后版本的bug (详细描述, 请看)
并且这个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的值
阅读(2907) | 评论(0) | 转发(0) |