当前位置: 技术问答>linux和unix
内核 2.6.26 下的驱动模块 "Unknown symbol in module" 问题
来源: 互联网 发布时间:2016-05-13
本文导语: 最简单的示例程序,写两个模块,分别为A和B,在A中导出了一些函数,而在B中使用A导出的函数。模块都使用GPL。 问题是在2.6.22和2.6.24下运行加载都很正常,当在2.6.26内核下加载时却出现了了Unknow symbol in module的错...
最简单的示例程序,写两个模块,分别为A和B,在A中导出了一些函数,而在B中使用A导出的函数。模块都使用GPL。
问题是在2.6.22和2.6.24下运行加载都很正常,当在2.6.26内核下加载时却出现了了Unknow symbol in module的错误。详见下面的具体描述。
两个模块的源码如下:
Makefile for Module A
[code=BatchFile]
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
[/code]
Makefile for Module B
[code=BatchFile]
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
[/code]
编译完成后开始加载模块:
[code=BatchFile]
#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
[/code]
在 /proc/kallsyms 里可以找到module A导出的symbol。
内核2.6.26版本以前都很正常,只有2.6.26版出现这个错误。请高手帮忙~谢谢
问题是在2.6.22和2.6.24下运行加载都很正常,当在2.6.26内核下加载时却出现了了Unknow symbol in module的错误。详见下面的具体描述。
两个模块的源码如下:
// Module A (mod_a.c)
#include
#include
#include
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
#include
#include
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
[code=BatchFile]
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
[/code]
Makefile for Module B
[code=BatchFile]
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
[/code]
编译完成后开始加载模块:
[code=BatchFile]
#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
[/code]
在 /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的值
并且这个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的值