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这些符号,这样才能找到对应的地址连接。

使用方法:

第一、在模块函数定义之后使用EXPORT_SYMBOL(函数名)
   第二、在掉用该函数的模块中使用extern对之声明
   第三、首先加载定义该函数的模块,再加载调用该函数的模块

另外,在编译调用某导出函数的模块时,往往会有WARNING: "****" [**********] undefined!
使用dmesg命令后会看到相同的信息。开始我以为只要有这个错误就不能加载模块,后来上网查了一下,发现这主要是因为在编译连接的时候还没有和内核打交道,当然找不到symbol了,但是由于你生成的是一个内核模块,所以LD不提示error,而是给出一个warning,寄希望于在insmod的时候,内核能够把这个symbol连接上。

一个模块mod1中定义一个函数func1;在另外一个模块mod2中定义一个函数func2,func2调用func1。
在模块mod1中,EXPORT_SYMBOL(func1);
在模块mod2中,extern int func1();
就可以在mod2中调用func1了

EXPORT_SYMBOL示范

比如有两个驱动模块:Module A和Module B,其中Module B使用了Module A中的export的函数,因此在Module B的Makefile文件中必须添加:

KBUILD_EXTRA_SYMBOLS += /path/to/ModuleA/Module.symvers

export KBUILD_EXTRA_SYMBOLS

这样在编译Module B时,才不会出现Warning,提示说func1这个符号找不到,而导致编译得到的ko加载时也会出错。

// 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 ;
} // Export symbol func1
EXPORT_SYMBOL(func1); static int __init hello_init(void)
{
printk("Module 1,say hello world!\n");
return ;
} 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>
extern int functl(void);
static int func2(void)
{
func1();
printk("In Func: %s...\n",__func__);
return ;
} static int __init hello_init(void)
{
printk("Module 2,is used Module 1 function!\n");
func2();
return ;
} static void __exit hello_exit(void)
{
printk("Module 2,Exit!\n");
} module_init(hello_init);
module_exit(hello_exit);
在驱动加载的时候,一定要先加载定义function1的Module A模块,然后再加载调用function1的Module B的驱动模块。
如下操作:
insmod Module_A.ko
insmod Module_B.ko

EXPORT_SYMBOL使用的更多相关文章

  1. EXPORT_SYMBOL的使用

    转自:http://blog.csdn.net/cailiwei712/article/details/7998525 在查看内核驱动代码的时候会经常看到在一些函数后面总会跟EXPORT_SYMBOL ...

  2. Whats meaning of “EXPORT_SYMBOL” in Linux kernel code?

    EXPORT_SYMBOL的作用是什么? EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一 ...

  3. 谈EXPORT_SYMBOL使用

    EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的.2.6就必须用EXPO ...

  4. EXPORT_SYMBOL的作用是什么

    http://www.cnblogs.com/riskyer/p/3221805.html EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动 导入到 ...

  5. EXPORT_SYMBOL解析

    一般我们编写C程序时,要调用某个文件中的函数,需要在本文件中包含声明有被调用函数的头文件,然后编译连接后,方能找到调用函数.对于模块依赖的情况,不能简单的使用上面的方法,内核提供了一个机制,就是EXP ...

  6. Linux内核导出符号宏定义EXPORT_SYMBOL源代码分析

    资源: <include/linux/moudule.h> --. #ifndef MODULE_SYMBOL_PREFIX #define MODULE_SYMBOL_PREFIX &q ...

  7. 内核中 EXPORT_SYMBOL 标志分析

    内核版本:Linux-4.19 1. EXPORT_SYMBOL 的作用: EXPORT_SYMBOL 定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在其它内核模块中直接调用,即使用 E ...

  8. driver: linux2.6 内核模块导出函数实例(EXPORT_SYMBOL) 【转】

    转自:http://blog.chinaunix.net/uid-23381466-id-3837650.html 内核版本:2.6.38-11-generic 内核自己都大量利用内核符号表导出函数, ...

  9. linux模块导出符号 EXPORT_SYMBOL_GPL&EXPORT_SYMBOL(转)

    转自:http://blog.csdn.net/angle_birds/article/details/7396748 一个模块mod1中定义一个函数func1:在另外一个模块mod2中定义一个函数f ...

随机推荐

  1. ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点

    LinkedList接口(在代码的使用过程中和ArrayList没有什么区别) ArrayList底层是object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点. 而在L ...

  2. php -- 判断文件是否存在

    file_exists is_file is_dir 基本上,PHP的 file_exists = is_dir + is_file 写程序验证一下: 分别执行1000次,记录所需时间. ------ ...

  3. jQuery实现鼠标悬停显示提示信息窗口的方法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. UIViewController三种不同的初始化view的方式

    You can specify the views for a view controller using a Storyboard created in Interface Builder. A s ...

  5. Oracle中select使用别名

    1 .将字段用as转换成别名. 2 .直接在字段的名字后面跟别名. 3 .在字段后面用双引号引起的别名.   我的朋友 大鬼不动 最近访客 fhwlj kochiyas 大極星 Alz__ deser ...

  6. java基础---->string字面量的使用

    这里简单的理解一下java中关于string字面量的知识,关于字节码可以使用java自带的javap工具查看. string字面量 一.直接贴出测试的代码 A string literal alway ...

  7. 【BZOJ4295】[PA2015]Hazard 乱搞

    [BZOJ4295][PA2015]Hazard Description 有n个人在轮流玩赌博机,一开始编号为i的人有a[i]元钱.赌博机可以抽象为一个长度为m的仅包含1和-1的序列,若抽到1,那么你 ...

  8. ArcGIS中的 .tpk数据

    转:http://blog.csdn.net/mytudousi/article/details/33347249 什么是tpk文件 tpk是ArcGIS10.1推出的一种新的数据文件类型,主要是用于 ...

  9. js apply 引申

    apply 可以接受两个参数, fun.apply(thisArg[, argsArray]) 其中第二个参数是数组或类数组对象,所以有时传 arguments 也很正常,但是,认真的说,我测试出来: ...

  10. 给vmware虚拟机设置Ip,使用xshell远程连接Centos

    参考下面两位的分享才弄好,发表之前先对原作者表示感谢! 给Centos配置网络以及使用xshell远程连接Centos http://www.cnblogs.com/fuly550871915/p/4 ...