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####\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 校验码出错。

EXPORT_SYMBOL的作用是什么的更多相关文章

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

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

  2. 谈EXPORT_SYMBOL使用

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

  3. 内核中 EXPORT_SYMBOL 标志分析

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

  4. EXPORT_SYMBOL使用

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

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

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

  6. [置顶] 谈EXPORT_SYMBOL使用

    转自:http://blog.csdn.net/macrossdzh/article/details/4601648 EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static ...

  7. [fw]谈EXPORT_SYMBOL使用

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

  8. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

  9. Kernel-----EXPORT_SYMBOL使用

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

随机推荐

  1. OC11_自动释放池

    // // Dog.h // OC11_自动释放池 // // Created by zhangxueming on 15/6/18. // Copyright (c) 2015年 zhangxuem ...

  2. requirejs实验002. r.js合并文件. 初体验.

    requirejs的官网上有介绍如何使用r.js合并,压缩文件的.http://requirejs.org/docs/optimization.html https://github.com/jrbu ...

  3. 关于TCP的两个小练习_第一个博客~

    先来一个本地的,客户端发送请求,服务端接收请求的简单代码 1 package com.TCP.java; 2 3 import java.io.IOException; 4 import java.i ...

  4. Dao层和Service层设计

    1.Dao接口层 public interface IBaseDao<T, ID extends Serializable>{ public abstract Serializable s ...

  5. 基础学习总结(三)--文本、SD卡数据读写

    简单的文本数据写入文件不需要权限,读写SD卡在4.0版本前需要写权限.在4.0后需要读写权限 布局: <LinearLayout xmlns:android="http://schem ...

  6. ASP.NET 将DataTable解析成JSON简介

    这里解析json使用的是Newtonsoft.Json.dll程序集.下面请看code: using System; using System.Collections.Generic; using S ...

  7. 纯CSS3代码实现简单的图片轮播

    以4张图片为例:1.基本布局:将4张图片左浮动横向并排放入一个div容器内,图片设置统一尺寸,div宽度设置4个图片的总尺寸,然后放入相框容器div,相框设置1个图片的大小并设置溢出隐藏,以保证正确显 ...

  8. Sublime Text 3 使用备注

    去年开始为了正规化自己的日常编辑工作,在dw,editplus,notap++,st里做了个选择,最终决定改曾经的dw为st. 毕竟dw是上个世纪的东西了,体积比较臃肿了.所以,在这里记录关于st的使 ...

  9. AngularJS(10)-数据验证

    AngularJS 表单和控件可以提供验证功能,并对用户输入的非法数据进行警告.客户端的验证不能确保用户输入数据的安全,所以服务端的数据验证也是必须的. <!DOCTYPE html> & ...

  10. Oracle RAC LoadBalance

    LoadBalance 就是把负载平均的分配到集群中的各个节点,从而提高整体的吞吐能力. Oracle 10g RAC 提供了两种不同的方法来分散负载: 通过Connection Balancing, ...