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####\n");
}
EXPORT_SYMBOL(hello_fun); static int __init hello_init(void)
{
printk(KERN_ERR "#### hello world\n");
return 0;
} static void __exit hello_exit(void)
{
printk(KERN_ERR "#### exit\n");
} 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\n");
} 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 校验码出错。

Kernel-----EXPORT_SYMBOL使用的更多相关文章

  1. 使用 /proc 文件系统来访问 linux操作系统 内核的内容 && 虚拟文件系统vfs及proc详解

    http://blog.163.com/he_junwei/blog/static/19793764620152743325659/ http://www.01yun.com/other/201304 ...

  2. (转)使用 /proc 文件系统来访问 Linux 内核的内容

    转载网址:http://www.ibm.com/developerworks/cn/linux/l-proc.html 这个虚拟文件系统在内核空间和用户空间之间打开了一个通信窗口/proc 文件系统是 ...

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

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

  4. EXPORT_SYMBOL的使用

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

  5. linux kernel 字符设备详解

    有关Linux kernel 字符设备分析: 参考:http://blog.jobbole.com/86531/ 一.linux kernel 将设备分为3大类,字符设备,块设备,网络设备. 字符设备 ...

  6. linux kernel input 子系统分析

    Linux 内核为了处理各种不同类型的的输入设备 , 比如说鼠标 , 键盘 , 操纵杆 , 触摸屏 , 设计并实现了一个对上层应用统一的试图的抽象层 , 即是Linux 输入子系统 . 输入子系统的层 ...

  7. linux kernel 平台总线实例分析

    linux 平台总线的实现有三大块  , platform bus , platform device , platform drvice 平台类型结构体: /** * struct bus_type ...

  8. 如何在 kernel 和 hal 层读取同一个标志

    很多时候我们需要从 HAL 层(Hardware Abstract Layer)传一个标志给 kernel 层.一般这种传递是不能直接通过定义全局变量来实现的. 此时可以通过读写文件来实现该标志. 譬 ...

  9. Linux Kernel sys_call_table、Kernel Symbols Export Table Generation Principle、Difference Between System Calls Entrance In 32bit、64bit Linux

    目录 . sys_call_table:系统调用表 . 内核符号导出表:Kernel-Symbol-Table . Linux 32bit.64bit环境下系统调用入口的异同 . Linux 32bi ...

  10. Intel 80x86 Linux Kernel Interrupt(中断)、Interrupt Priority、Interrupt nesting、Prohibit Things Whthin CPU In The Interrupt Off State

    目录 . 引言 . Linux 中断的概念 . 中断处理流程 . Linux 中断相关的源代码分析 . Linux 硬件中断 . Linux 软中断 . 中断优先级 . CPU在关中断状态下编程要注意 ...

随机推荐

  1. 用户从手机的浏览器访问www.baidu.com,看到的可能跟桌面PC电脑,是不太一样的网页效果,会更适合移动设备使用。请简要分析一下,实现这种网页区分显示的原因及技术原理。

    手机的网速问题.屏幕大小.内存.CPU等.通过不同设备的特征,实现不同的网页展现或输出效果.根据useragent.屏幕大小信息.IP.网速.css media Query等原理,实现前端或后端的特征 ...

  2. OD 实验(二十) - 对反调试程序的逆向分析(一)

    程序: Keyfile.dat 里的内容 该文件中要至少有 9 个 ReverseMe.A: 运行程序 用 OD 打开该程序,运行 弹出的是错误的对话框 该程序发现 OD 对它的调试,所以该程序对 O ...

  3. Flask之模板

    2 了解Jinja2模板 知识点 模板使用 变量 过滤器 web表单 控制语句 宏.继承.包含 Flask中的特殊变量和方法 3.1 模板 在前面的示例中,视图函数的主要作用是生成请求的响应,这是最简 ...

  4. LeetCode题解 #12 Integer to Roman

    题目大意:给定数字,将其转化为罗马数字的形式 罗马数字其实只有 I V X L C D M 这几种形式,其余均为组合的,去百度了解一下就ok. 所以首先想到的就是,将个.十.百.千位的数字构造出来,然 ...

  5. 关于 warning CS0659:“***”重写Object.Equals(object o)但不重写Object.GetHashCode()

    对象相等性和同一性 System.Object 类型提供了以下方法, namespace System { // // 摘要: // 支持 .NET Framework 类层次结构中的所有类,并为派生 ...

  6. Apache加载curl_init 失败 php_curl.dll

    Call to undefined function curl_init php.ini curl_init extension=php_curl.dll xampp\php\php.ini 2018 ...

  7. hibernate中 criteria.setProjection(Projections.rowCount()).uniqueResult()为null的Bug

    在hibernate中,在查询总数时,会使用如下方法; public Integer getCount(final DetachedCriteria detachedCriteria) {       ...

  8. postman的使用方法详解

    Collections:在Postman中,Collection类似文件夹,可以把同一个项目的请求放在一个Collection里方便管理和分享,Collection里面也可以再建文件夹.如果做API文 ...

  9. 使用ControllerClassNameHandlerMapping实现SpringMVC的CoC配置

    使用CoC,惯例优先原则(convention over configuration)的方式来配置SpringMVC可以帮我们声明Controller的时候省下很多功夫. 只要我们的Controlle ...

  10. jsp get 乱码

    String str=request.getParameter("name");str=new String(str.getBytes("iso8859-1") ...