刚开始学习linux内核加载,第一次加载最简单的hello模块的时没出什么问题,成功的在messages上看到了输出的hello,但第二次做模块间调用时遇到一个问题。
附源码:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
1 //export_symbol.c
2 #include<linux/module.h>
3
4 MODULE_LICENSE("Dual BSD/GPL");
5
6 int add_(int a, int b)
7 {
8 printk(KERN_INFO"a+b\n");
9 return (a+b);
10 }
11
12 int sub_(int a,int b)
13 {
14 printk(KERN_INFO"a-b\n");
15 return (a-b);
16 }
17
18 EXPORT_SYMBOL(add_);
19 EXPORT_SYMBOL(sub_);
20
21 EXPORT_SYMBLE(add_);
22 EXPORT_SYMBLE(sub_);
23
24 int init_module(void)
25 {
26 printk(KERN_INFO"Hello,I am module one!\n");
27 return 0;
28 }
29
30 void cleanup_module(void)
31 {
32 printk(KERN_INFO"Module One:Goodbye everybody!\n");
33 }
34
35 MODULE_AUTHOR("Eggerxu");
36 MODULE_DESCRIPTION("Simple module1");
37 MODULE_VERSION("Ver 0.1");
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
1 //simple_calculation.c
2 #include<linux/init.h>
3 #include<linux/module.h>
4
5 MODULE_LICENSE("Dual BSD/GPL");
6
7 static char *user_name = "eggerxu";
8 static int first_operator = 0;
9 static int second_operator = 0;
10 int result = 0;
11
12 extern int add_(int a,int b);
13 extern int sub_(int a,int b);
14
15 int init_module(void)
16 {
17 printk(KERN_INFO"Hello,I am module two!\n");
18 printk(KERN_INFO"%s,Welcome to use this simple calculator !\n",user_name);
19 result = add_(first_operator,second_operator);
20 printk(KERN_INFO"Result of %d + %d :%d",first_operator,second_operator,result);
21 return 0;
22 }
23
24 void cleanup_module(void)
25 {
26 printk(KERN_INFO"Module two:Goodbye %s\n",user_name);
27 result = sub_(first_operator,second_operator);
28 printk(KERN_INFO"Result of %d - %d : %d",first_operator,second_operator,result);
29 return ;
30 }
31
32 module_param(user_name,charp,S_IRUGO);
33 module_param(first_operator,int,S_IRUGO);
34 module_param(second_operator,int,S_IRUGO);
35
36 EXPORT_SYMBOL(user_name);
37 EXPORT_SYMBOL(first_operator);
38 EXPORT_SYMBOL(second_operator);
39 MODULE_AUTHOR("Eggerxu");
40 MODULE_DESCRIPTION("Simple Module two,used to calculate simple nums");
41 MODULE_VERSION("Ver 0.1");
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
ifneq ($(KERNELRELEASE),)
obj-m +=export_symbol.o
else
PWD :=$(shell pwd)
KVER ?=$(shell uname -r)
KDIR :=/lib/modules/$(KVER)/build
all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf *.o *.mod.c *.ko *.symvers
endif
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
1 ifneq ($(KERNELRELEASE),)
2
3 obj-m+= simple_calculation.o
4
5 else
6 PWD :=$(shell pwd)
7 KVER ?=$(shell uname -r)
8 KDIR :=/lib/modules/$(KVER)/build
9 KBUILD_EXTRA_SYMBOLS=/home/eric/main/module/module1/Module.symvers
10 all:
11 $(MAKE) -C $(KDIR) M=$(PWD)
12 clean:
13 rm -rf *.0 *.mod.c *.ko *.symvers
14 endif
export_symbol.ko文件正常加载,但在加载simple_calculation.ko并导入参数时出现了错误.
terminal上显示:
insmod: error inserting './simple_calculation.ko': -1 Unknown symbol in module
然后查看messages显示结果如下:
7573 Nov 9 11:43:50 ubuntu kernel: [ 801.506758] simple_calculation: no symbol version for sub_
7574 Nov 9 11:43:50 ubuntu kernel: [ 801.506765] simple_calculation: Unknown symbol sub_
7575 Nov 9 11:43:50 ubuntu kernel: [ 801.506962] simple_calculation: no symbol version for add_
7576 Nov 9 11:43:50 ubuntu kernel: [ 801.506966] simple_calculation: Unknown symbol add_
terminal上的显示毫无帮助,messages上显示说两个调用函数无symbol version,可是在export_symbol.c中我明明已经写了
EXPORT_SYMBOL(add_);
EXPORT_SYMBOL(sub_);
为什么第二个模块无法找到呢?然后就上网查了一下,原来是2.6.26之后内核的问题,在编译第二个模块时搜索Module.symvers的路径顺序为先检查内核源路径如/usr/src/kernels/linux-2.6.26,然后是Makefile中的M=指定的路径而这个路径等效于变量KBUILD_EXTMOD的值,再然后就是变量KBUILD_EXTRA_SYMBOLS的值了。于是我就在simple_calculation的Makefile中添加了KBUILD_EXTRA_SYMBOLS=home/eric/moudle/moudle1/Module.symvers 指向export_symbol的Module.symvers文件,这样在编译第二个模块时就能找到第一个模块的Module.symvers 了。然后重新make,然后执行,问题顺利解决
结果如下:
刚开始接触linux内核,很多东西不懂,这次遇到的关于内核的问题还是在另一个论坛上遇到的,然后又去了kernal的官网上看了一下有关kernel2.6的相关bug才解决的问题。