EXPORT_SYMBOL的作用是什么

摘要:
模块许可证(“GPL”);staticint_inithello_init(void){printk(KERN_ERR“####helloworld”);rm rf*.o.cmd*.ko*.mod.c.tmp_versions(2)调用模块.c#include<externavoidhello_fun(void);

http://www.cnblogs.com/riskyer/p/3221805.html

EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动

导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的。

2.6就必须用EXPORT_SYMBOL() 来导出来(因为2.6默认不到处所有的符号)。

1、EXPORT_SYMBOL的作用是什么?

EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代

码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符

号的方式导出给其他模块使用。

这里要和System.map做一下对比:


System.map 中的是连接时的函数地址。连接完成以后,在2.6内核运行过程中,是不知道哪个符号在哪个地址的。
EXPORT_SYMBOL 的符号, 是把这些符号和对应的地址保存起来,在内核运行的过程中,可以找到这些符号对应的地址。而模块在加载过程中,其本质就是能动态连接到内核,如果在模块中引 用了内核或其它模块的符号,就要EXPORT_SYMBOL这些符号,这样才能找到对应的地址连接。

2、使用方法
第一、在模块函数定义之后使用EXPORT_SYMBOL(函数名)
第二、在掉用该函数的模块中使用extern对之声明

第三、首先加载定义该函数的模块,再加载调用该函数的模块


例如:

一个模块mod1中定义一个函数func1;

在另外一个模块mod2中定义一个函数func2,func2调用func1。

在模块mod1中,EXPORT_SYMBOL(func1);

在模块mod2中,extern int func1();

就可以在mod2中调用func1了。


(1)helloworld.c

#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");

static void hello_fun(void)
{
  printk("##### helloworld####
");
}
EXPORT_SYMBOL(hello_fun);

static int __init hello_init(void)
{
   printk(KERN_ERR "#### hello world
");
   return 0;
}

static void __exit hello_exit(void)
{
   printk(KERN_ERR "#### exit
");
}

module_init(hello_init);
module_exit(hello_exit);


Makefile

obj-m := hello.o
hello-objs := helloworld.o

KID := /lib/modules/`uname -r`/build
PWD := $(shell pwd)

all:
	make -C $(KID) M=${PWD} modules

clean:
	rm -rf *.o .cmd *.ko *.mod.c .tmp_versions  



(2)call-module.c

#include <linux/module.h>
#include <linux/init.h>

extern void hello_fun(void);

static int __init hello_init(void)
{
   hello_fun();
   return 0;
}

static void __exit hello_exit(void)
{
   printk(KERN_ERR "#### exit
");
}

MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);


Makefile

obj-m := call-module.o

KID := /lib/modules/`uname -r`/build
PWD := $(shell pwd)
KBUILD_EXTRA_SYMBOLS=/usr/src/linux-headers-3.5.0-34-generic/Module.symvers

KBUILD_EXTRA_SYMBOLS +=/home/snail/work/2.linux-driver/1.helloworld/Module.symvers

all:
	make -C $(KID) M=${PWD} modules

clean:
	rm -rf *.o .cmd *.ko *.mod.c .tmp_versions *.order *.symvers .*


(3)

加载 hello.ko

sudo insmod ./hello.ko


加载 call-module.ko 

sudo insmod ./call-module.ko 


观察 dmesg

<4>[ 3837.857657] ##### helloworld####


(4)注意事项

加载call-module.ko可能会出现

“NO SYMBOL VERSION FOR”问题


解决:


这是linux kernel 2.6.26 之后版本的bug (详细描述, 请看http://bugzilla.kernel.org/show_bug.cgi%3Fid%3D12446)
并且这个bug不会被fix
解决办法:

(1)mod_a的Module.symvers放到mod_b的当前路径,从而编译mod_b,符号信息会自动连接进去.
(2)或者在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的值

问题的本质:
简单说来,就是小b生成的时候不知道小a symbol的校验码,小b加载的时候自然check 校验码出错。

免责声明:文章转载自《EXPORT_SYMBOL的作用是什么》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇hibernate(三) 一对多映射关系笔记:bash脚本入门下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

【Python与机器学习】:利用Keras进行多类分类

多类分类问题本质上可以分解为多个二分类问题,而解决二分类问题的方法有很多。这里我们利用Keras机器学习框架中的ANN(artificial neural network)来解决多分类问题。这里我们采用的例子是著名的UCI Machine Learning Repository中的鸢尾花数据集(iris flower dataset)。 1. 编码输出便签...

深入跟踪MFC程序的执行流程

来源: http://blog.csdn.net/ljianhui/article/details/8781991 在MFC程序设计的学习过程中最令人感到难受,甚至于有时会动摇学习者信心的就是一种对于程序的一切细节都没有控制权的感觉。这种感觉来源于学习者不知道一个MFC程序是如何运行起来的(即一个MFC程序的执行流程)和MFC程序的设计思想和机制,即使是写...

c++ Beep(发声函数)

c++ Beep(发声函数) Windows API 提供了一个奇妙的发音函数-Beep函数。Beep可以通过控制主板扬声器的发声频率和节拍来演奏美妙的旋律 Beep函数原型 BOOL Beep( DWORD dwFreq; DWORD dwDuration; ); dwFreq 指定要发出的频率(HZ) dwDuration 指...

python 内置数据类型之数字

目录: 1.2. 数字 1.2.1. 数字类型 1.2.2. 浮点数 1.2.3. 进制记数 1.2.4. 设置小数精度 1.2.5. 分数 1.2.6. 除法   1.2 数字   1.2.1 数字类型 python 内置可以处理大部分常见的数字类型,比如整数,浮点数。 还有一些模块包括更高级的数学工具。第三方开源扩展领域还包含了更多的类型(矩...

iOS学习笔记之typedef

typedef unsigned long long weiboId; typedef 定义一个使用方便的类型,谓之为“宏定义“。 unsigned long long 是一种无符号的长长整型。本应该是这样,unsigned long long int ,这里省略了int ,编译器会自动认可。 unsigned long long ,是64 位的数据,8...

Golang中的插件开发

  插件化开发提供了很多便利,可动态扩展程序的相关功能,如Windows中的DLL、Linux中的So文件、还有IDEA中的插件,应用范围不可谓不广;   在Golang中提供了自己的插件机制,可使用其进行插件化开发;在Golang的plugin包中提供了加载插件、调用插件中函数的相关方法; Golang中的插件机制使用非常简单;就只有这么三步:   1、...