EXPORT_SYMBOL的作用是什么
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的作用是什么的更多相关文章
- Whats meaning of “EXPORT_SYMBOL” in Linux kernel code?
EXPORT_SYMBOL的作用是什么? EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一 ...
- 谈EXPORT_SYMBOL使用
EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的.2.6就必须用EXPO ...
- 内核中 EXPORT_SYMBOL 标志分析
内核版本:Linux-4.19 1. EXPORT_SYMBOL 的作用: EXPORT_SYMBOL 定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在其它内核模块中直接调用,即使用 E ...
- EXPORT_SYMBOL使用
EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的.2.6就必须用EXPO ...
- linux模块导出符号 EXPORT_SYMBOL_GPL&EXPORT_SYMBOL(转)
转自:http://blog.csdn.net/angle_birds/article/details/7396748 一个模块mod1中定义一个函数func1:在另外一个模块mod2中定义一个函数f ...
- [置顶]
谈EXPORT_SYMBOL使用
转自:http://blog.csdn.net/macrossdzh/article/details/4601648 EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static ...
- [fw]谈EXPORT_SYMBOL使用
EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的.2.6就必须用EXPO ...
- Linux 驱动开发
linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...
- Kernel-----EXPORT_SYMBOL使用
EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动 导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的. 2.6就必须用EX ...
随机推荐
- OC11_自动释放池
// // Dog.h // OC11_自动释放池 // // Created by zhangxueming on 15/6/18. // Copyright (c) 2015年 zhangxuem ...
- requirejs实验002. r.js合并文件. 初体验.
requirejs的官网上有介绍如何使用r.js合并,压缩文件的.http://requirejs.org/docs/optimization.html https://github.com/jrbu ...
- 关于TCP的两个小练习_第一个博客~
先来一个本地的,客户端发送请求,服务端接收请求的简单代码 1 package com.TCP.java; 2 3 import java.io.IOException; 4 import java.i ...
- Dao层和Service层设计
1.Dao接口层 public interface IBaseDao<T, ID extends Serializable>{ public abstract Serializable s ...
- 基础学习总结(三)--文本、SD卡数据读写
简单的文本数据写入文件不需要权限,读写SD卡在4.0版本前需要写权限.在4.0后需要读写权限 布局: <LinearLayout xmlns:android="http://schem ...
- ASP.NET 将DataTable解析成JSON简介
这里解析json使用的是Newtonsoft.Json.dll程序集.下面请看code: using System; using System.Collections.Generic; using S ...
- 纯CSS3代码实现简单的图片轮播
以4张图片为例:1.基本布局:将4张图片左浮动横向并排放入一个div容器内,图片设置统一尺寸,div宽度设置4个图片的总尺寸,然后放入相框容器div,相框设置1个图片的大小并设置溢出隐藏,以保证正确显 ...
- Sublime Text 3 使用备注
去年开始为了正规化自己的日常编辑工作,在dw,editplus,notap++,st里做了个选择,最终决定改曾经的dw为st. 毕竟dw是上个世纪的东西了,体积比较臃肿了.所以,在这里记录关于st的使 ...
- AngularJS(10)-数据验证
AngularJS 表单和控件可以提供验证功能,并对用户输入的非法数据进行警告.客户端的验证不能确保用户输入数据的安全,所以服务端的数据验证也是必须的. <!DOCTYPE html> & ...
- Oracle RAC LoadBalance
LoadBalance 就是把负载平均的分配到集群中的各个节点,从而提高整体的吞吐能力. Oracle 10g RAC 提供了两种不同的方法来分散负载: 通过Connection Balancing, ...