Linux内核导出符号宏定义EXPORT_SYMBOL源代码分析
资源:
<include/linux/moudule.h>
…….
#ifndef MODULE_SYMBOL_PREFIX
#define MODULE_SYMBOL_PREFIX ""
#endif
…….
struct kernel_symbol //内核符号结构
{
unsignedlong value; //该符号在内存地址中的地址
constchar *name; //该符号的名称
};
……
#define __EXPORT_SYMBOL(sym,sec) \
externtypeof(sym) sym; \
__CRC_SYMBOL(sym,sec) \
staticconst char __kstrtab_##sym[] \
__attribute__((section(“__ksymtab_strings”),aligned(1))) \
=MODULE_SYMBOL_PREFIX#sym; \
staticconst struct kernel_symbol __ksymtab_##sym \
__used \
__attribute__((section(“__ksymatab”sec),unused)) \
={(unsignedlong)&sym,_kstrab_#sym}
#define EXPORT_SYMBOL(sym) \
__EXPOTR_SYMBOL(sym,””)
#define EXPORT_SYMBOL_GPL(sym) \
__EXPOTR_SYMBOL(sym,”_gpl”)
#define EXPORT_SYMBOL(sym) \
__EXPOTR_SYMBOL(sym,”_gpl_future”)
1、预备知识:
在分析前,先了解例如以下相关知识:
(1)#运算符,##运算符
通常在宏定义中使用#来创建字符串 #abc就表示字符串”abc”等。
##运算符称为预处理器的粘合剂,用来替换粘合两个不同的符号,
如:#definexName (n) x##n
则xName(4) 则变为x4
(2)gcc的__attribute__属性:
__attribute__((section(“section_name”)))的作用是将指定的函数或变量放入到名为”section_name”的段中。
__attribute__属性加入能够再函数或变量定义的时候直接加入在定义语句中。
如:int myvar__attribute__((section("mydata"))) = 0;
表示定义了整形变量myvar=0;而且将该变量存放到名为”mydata”的section中
关于gcc_attribute具体解释能够參考:http://blog.sina.com.cn/s/blog_661314940100qujt.html
2、代码分析:
举例说明:若要导出内核符号(内核函数)myfc,
如调用 EXPORT_SYMBOL(myfc)
展开为 __EXPORT_SYMBOL(myfc,””)
展开为
static const char __kstrtab_myfc[] __attribute__((section(“__ksymtab_strings”),aligned(1)))
=MODULE_SYMBOL_PREFIX myfc;
static const struct kernel_symbol __ksymtab_myfc
__used
__attribute__((section(“__ksymatab”),unsed))
={(unsigned long)&sym,_kstrab_myfc}
由前面可知__attribute__是gcc中的属性(__used也是gcc属性),用于向指定的函数或者变量加入相关的属性。为了不影响对变量定义的理解,先将__attribute__属性掩盖。则上面的定义变为:
static const char __kstrtab_myfc[] =” myfc”;
static const struct kernel_symbol__ksymtab_myfc={(unsigned long)&myfc,_kstrab_myfc}。
//定义了一个字符数组__kstrtab_myfc[]用于存放导出的符号名myfc
//定义了一个内核符号结构__ksymtab_myfc用于存放引出符号myfc在内存中的地址和名称。
加入了__attribute__属性后。则表示:
将字符数组__kstrtab_myfc[]放置到一个名为“__ksymtab_strings”的section中。
将内核符号结构__ksymtab_myfc放置到一个名为”__ksymatab”的section中。
若是调用了EXPORT_SYMBOL_GPL(myfc)。则相应的内核符号结构被放置到名 为”__ksymatab_gpl”的section中。
3、总结:在内核符号导出中。调用了EXPORT_SYMBOL(sym),则会完毕下面操作:
(1) 定义一个字符数组存放内核导出符号的名称。并放置到“__ksymtab_strings”的section中。
(2) 定义一个内核符号结构用于存放导出符号的内存地址和名称,并放置到”__ksymatab”中。
即通过EXPORT_SYMBOL(sym)告诉了内核以外的世界关于这个符号的两点信息:内核符号的名称和其内存地址。
版权声明:本文博主原创文章,博客,未经同意不得转载。
Linux内核导出符号宏定义EXPORT_SYMBOL源代码分析的更多相关文章
- linux模块导出符号 EXPORT_SYMBOL_GPL&EXPORT_SYMBOL(转)
转自:http://blog.csdn.net/angle_birds/article/details/7396748 一个模块mod1中定义一个函数func1:在另外一个模块mod2中定义一个函数f ...
- 内核中的宏定义__init、__initdata和__exit、__exitdata
__init.__initdata和__exit.__exitdata的定义位于<kernel/include/linux/init.h> /* These are for everybo ...
- 剖析linux内核中的宏---------container_of
#define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) * __mptr = (ptr); ...
- Linux内核中的list用法和实现分析
这些天在思考知识体系的完整性,发现总是对消息队列的实现不满意,索性看看内核里面的链表实现形式,这篇文章就当做是学习的i笔记吧.. 内核代码中有很多的地方使用了list,而这个list的用法又跟我们平时 ...
- Linux内核中container_of宏的详细解释
上一节拒绝造轮子!如何移植并使用Linux内核的通用链表(附完整代码实现)我们在分析Linux内核链表的时候注意到内核在求解结构体偏移的时候巧妙的使用了container_of宏定义,今天我们来详细剖 ...
- linux内核中的宏ffs(x)
linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __ ...
- Linux内核设计第五周学习总结 分析system_call中断处理过程
陈巧然原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 使用gdb跟踪分析一 ...
- Linux内核调试方法总结之死锁问题分析
死锁问题分析 死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态,死锁状态一旦形成,进程本身是解决不了的,需要外在的推动,才能解决,最重要的是死锁不仅仅影响进程业务, ...
- Linux内核设计第六周学习总结 分析Linux内核创建一个新进程的过程
陈巧然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验过程 登陆实验楼 ...
随机推荐
- Hadoop认知--在不同的阶段
入门阶段 出于兴趣,及工作中的简单有用,大约经过1个月的时间,完毕了对Hadoop的基本认知. 在这个月中我干了例如以下几件事 1.大体看了<Hadoop权威指南>.把里面的代码手工码了一 ...
- Ibatis之3个不经常使用的Query方法
1.queryForObject /** * Executes a mapped SQL SELECT statement that returns data to populate * the su ...
- 【转】Qt事件循环与线程 二
转自:http://blog.csdn.net/changsheng230/article/details/6153449 续上文:http://blog.csdn.net/changsheng230 ...
- CSAPP 六个重要的实验 lab5
CSAPP && lab5 实验指导书: http://download.csdn.net/detail/u011368821/7951657 实验材料: http://downlo ...
- java 线程、线程池基本应用演示样例代码回想
java 线程.线程池基本应用演示样例代码回想 package org.rui.thread; /** * 定义任务 * * @author lenovo * */ public class Lift ...
- JavaScript概要
当用户填写表单在线,用户输入表单经常要推测在页面上,它提示用户填写正确的邮箱.哪些项目不填之类,这些都是JavaScript小的特点. JavaScript是一种基于对象的脚本语言,使用它能够开 ...
- cnBlog 的windows live writer 客户端配置
重装系统后总是忘,备个档 CNBLOG 博客名 cnblog 日志帐户 http://www.cnblogs.com/liulaocai2/ 用户:359444066 密码:同QQ密码,比QQ少一位 ...
- cocos2dx-2.x CCFileUtils文件管理分析(2)
于1于,我只是对整体结构进行了分析,然后,2于,我会在一些我们经常使用的分析功能. //获取给定文件名称的全路径 //以下这非常长一段凝视.通过举样例,像我们说明cocos2dx获取文件全路径的规则. ...
- poj 3237 Tree(树链拆分)
题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...
- Android - 数据存储 -在SQL数据库中保存数据
对于重复的或结构化的数据,保存到数据库中是很好的选择,比如联系人信息.这里假设你对SQL数据库大体上了解然后帮助你学习Android上的SQLite数据库.在Android数据库上需要用到的API可以 ...