资源:

<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源代码分析的更多相关文章

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

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

  2. 内核中的宏定义__init、__initdata和__exit、__exitdata

    __init.__initdata和__exit.__exitdata的定义位于<kernel/include/linux/init.h> /* These are for everybo ...

  3. 剖析linux内核中的宏---------container_of

    #define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) * __mptr = (ptr); ...

  4. Linux内核中的list用法和实现分析

    这些天在思考知识体系的完整性,发现总是对消息队列的实现不满意,索性看看内核里面的链表实现形式,这篇文章就当做是学习的i笔记吧.. 内核代码中有很多的地方使用了list,而这个list的用法又跟我们平时 ...

  5. Linux内核中container_of宏的详细解释

    上一节拒绝造轮子!如何移植并使用Linux内核的通用链表(附完整代码实现)我们在分析Linux内核链表的时候注意到内核在求解结构体偏移的时候巧妙的使用了container_of宏定义,今天我们来详细剖 ...

  6. linux内核中的宏ffs(x)

    linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __ ...

  7. Linux内核设计第五周学习总结 分析system_call中断处理过程

    陈巧然原创作品 转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 使用gdb跟踪分析一 ...

  8. Linux内核调试方法总结之死锁问题分析

    死锁问题分析 死锁就是多个进程(线程)因为等待别的进程已占有的自己所需要的资源而陷入阻塞的一种状态,死锁状态一旦形成,进程本身是解决不了的,需要外在的推动,才能解决,最重要的是死锁不仅仅影响进程业务, ...

  9. Linux内核设计第六周学习总结 分析Linux内核创建一个新进程的过程

    陈巧然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.实验过程 登陆实验楼 ...

随机推荐

  1. 工作经常使用的SQL整理,实战篇(二)

    原文:工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实战篇,地址一览: 工作经常使用的SQL整理,实战篇(一) 工作经常使用的SQL整理,实战篇(二) 工作经常使用的SQL整理,实 ...

  2. poj 2586 Y2K Accounting Bug (贪心)

    Y2K Accounting Bug Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8678   Accepted: 428 ...

  3. s3c2440的A/D转换应用

    10 地点 CMOS ADC(模/数字转换器)是 8 通道模拟输入型设备回收.该模拟输入信号转换 10 位二进制数字编码,A/D变化.也被称为模数转换.该模拟信号被转换成美元 算机可以处理的数字信号. ...

  4. 【Android进阶】关于PagerAdapter的使用方法的总结

    PagerAdapter简介 PagerAdapter是android.support.v4包中的类,它的子类有FragmentPagerAdapter, FragmentStatePagerAdap ...

  5. cookie在vs又一次run的时候丢失

    今天写个关于http cookie的demo,发现仅仅要vs又一次执行后cookie的值就会丢失,代码例如以下 protected void Page_Load(object sender, Even ...

  6. hdu4288 Coder(段树+分离)

    主题链接: huangjing 题意: 题目中给了三个操作 1:add x 就是把x插进去  2:delete x 就是把x删除 3:sum 就是求下标%5=3的元素的和. 另一个条件是插入和删除最后 ...

  7. 【Web探索之旅】第一部分:什么是Web?

    内容简介 1.Web探索之旅:开宗明义 2.第一部分第一课:什么是Web? 3.第一部分第二课:Web,服务和云 4.第一部分第三课:Web的诞生史 Web探索之旅:开宗明义 大家好. 我们这个系列课 ...

  8. 大约C++ const 全面总结

    C++中的const关键字的使用方法很灵活,而使用const将大大改善程序的健壮性,本人依据各方面查到的资料进行总结例如以下,期望对朋友们有所帮助. Const 是C++中经常使用的类型修饰符,常类型 ...

  9. HDU 4391 Paint The Wall 段树(水

    意甲冠军: 特定n多头排列.m操作 以下是各点的颜色 以下m一种操纵: 1 l r col 染色 2 l r col 问间隔col色点 == 通的操作+区间内最大最小颜色数的优化,感觉非常不科学... ...

  10. Android-管理Activity生命周期 -开始一个Activity

    很多程序都是从main()方法开始启动的,和其他程序不同,android是在activity生命周期的特定状态的特定回调方法中初始化代码的.activity启动和销毁的时候都用很多回调方法. 这里将要 ...