Linux内核导出符号宏定义EXPORT_SYMBOL的源码分析

转载 2015年07月11日 10:43:22

源代码:

<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的源码分析

源代码: ……. #ifndef MODULE_SYMBOL_PREFIX #define MODULE_SYMBOL_PREFIX "" #endif ……. struct kernel_symb...
  • fzubbsc
  • fzubbsc
  • 2014年06月23日 11:45
  • 1541

EXPORT_SYMBOL linux的内核符号表

http://hi.baidu.com/adokaixin/blog/item/03d79e8822668d8fa5c27263.html   在内核中通过/proc/ka...
  • diy534
  • diy534
  • 2011年11月06日 23:58
  • 1594

Linux内核—EXPORT_SYMBOL宏的使用

前言 EXPORT_SYMBOL宏的使用时出现在Linux-2.6之后,在Linux-2.4内核中,默认的非static 函数和变量都会自动导入到kernel 空间, 都不用EXPORT_SYMBO...

Linux开发心得总结20 - 内核编程中的全局变量使用(EXPORT_SYMBOL())

和我们通常写程序不同,如果仅仅是全局变量,虽然编译内核的时候能连接成功,但是连接之后再就没有办法使用这个变量了 而模块的加载是运行时的,它引用某个变量时,内核需要解析它,否则模块不能工作,EXPOR...
  • ynttmp
  • ynttmp
  • 2012年06月06日 09:45
  • 2424

Linux 驱动之 EXPORT_SYMBOL 函数以及 2.6 内核 Unknown symbol bug 解决办法

1、Linux中EXPORT_SYMBOL的用法 EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用。您还可以手工修改内核源代码来导出...

盘点Linux内核源码中使用宏定义的若干技巧(1)

盘点Linux内核源码中使用宏定义的若干技巧(1) (2012-03-20 21:30) 标签:  Linux内核源码  宏定义  宏的使用技巧  分类: Linux系统内核 ...

Linux内核源码中使用宏定义的若干技巧

在C中,宏定义的概念虽然简单,但是真要用好却并不那么容易,下面从Linux源码中抽取一些宏定义的使用方法,希望能从中得到点启发: 1. 类型检查 比如module_init的宏定义: ...
  • sdulibh
  • sdulibh
  • 2016年04月19日 15:05
  • 444

linux内核源码中常见宏定义

1. gcc的__attribute__编绎属性 要了解Linux Kernel代码的分段信息,需要了解一下gcc的__attribute__的编绎属性,__attribute__主要用于改变所声明...

Linux内核源码--min,swap宏定义

Linux3.5的部分宏定义在Linux-3.5/include/linux/kernel.h的头文件中有定义 一: 最大值和最小值相关的宏 [cpp] view ...

【C语言】Linux内核源码--min,swap宏定义

Linux3.5的部分宏定义在linux-3.5/include/linux/kernel.h的头文件中有定义 /* * min()/max()/clamp() macros that also d...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux内核导出符号宏定义EXPORT_SYMBOL的源码分析
举报原因:
原因补充:

(最多只允许输入30个字)