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
  • 1644

Linux内核—EXPORT_SYMBOL宏的使用

前言 EXPORT_SYMBOL宏的使用时出现在Linux-2.6之后,在Linux-2.4内核中,默认的非static 函数和变量都会自动导入到kernel 空间, 都不用EXPORT_SYMBO...
  • zengxianyang
  • zengxianyang
  • 2016年01月30日 17:41
  • 3652

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

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

linux 内核模块编程之内核符号导出(五)

/proc/kallsyms 记录了内核中所有导出的符号的名字与地址
  • gs1069405343
  • gs1069405343
  • 2016年01月07日 20:29
  • 749

linux 内核源码 系统调用宏定义

linux 内核源码中关于系统调用源码阅读
  • yueyingshaqiu01
  • yueyingshaqiu01
  • 2015年09月28日 17:07
  • 560

define宏定义中的#,##,@#及\符号

一、# 名称:字符串化操作符 其作:将宏定义中的传入参数名转换成用一对双引号括起来参数名字符串。 使用条件:只能用于有传入参数的宏定义中,且必须置于宏定义体中的参数名前 举例:...
  • zhubosa
  • zhubosa
  • 2016年04月28日 18:17
  • 2275

Linux内核源代码情景分析笔记

Linux内核源代码情景分析笔记好吧,首先我承认我要是读者的话,这篇文章我看着也头疼,因为写的太长太泛(其主要部分集中在内存管理,进程管理,文件系统)!原本是想按自己理解的精简精简的,按照操作系统中两...
  • u010865478
  • u010865478
  • 2017年03月10日 22:24
  • 907

Linux内核源码分析方法

Linux内核源码分析方法   一、内核源码之我见 Linux内核代码的庞大令不少人“望而生畏”,也正因为如此,使得人们对Linux的了解仅处于泛泛的层...
  • dyllove98
  • dyllove98
  • 2013年05月11日 22:41
  • 30518

内核符号表详解——如何在module中利用内核符号

前言:在内核开发中,有时候我们必须检查某些内核状态,或者我们想冲用某些内核功能,我们需要得到(read,write,exe)内核符号。本文主要为你介绍内核如何保存这些符号表,我们怎样应用这些内核符号表...
  • trochiluses
  • trochiluses
  • 2013年07月24日 10:41
  • 6959

宏内核与微内核、Linux内核与Unix内核的区别

操作系统内核可能是微内核,也可能是单内核(后者有时称之为宏内核Macrokernel)。按照类似封装的形式,这些术语定义如下: 单内核:也称为宏内核。将内核从整体上作为一个大过程实现,并同时运行在一...
  • Silencegll
  • Silencegll
  • 2016年05月25日 10:06
  • 3166
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux内核导出符号宏定义EXPORT_SYMBOL的源码分析
举报原因:
原因补充:

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