Kernel. EXPORT_SYMBOL解析

Code Segment:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

include/module.h:

struct kernel_symbol
{
unsigned long value;
const char *name;
};

/* For every exported symbol, place a struct in the __ksymtab section */
#define __EXPORT_SYMBOL(sym, sec) /
__CRC_SYMBOL(sym, sec) /
static const char __kstrtab_##sym[] /
__attribute__((section("__ksymtab_strings"))) /
= MODULE_SYMBOL_PREFIX #sym; /
static const struct kernel_symbol __ksymtab_##sym /
__attribute_used__ /
__attribute__((section("__ksymtab" sec), unused)) /
= { (unsigned long)&sym, __kstrtab_##sym }
#define EXPORT_SYMBOL(sym) /
__EXPORT_SYMBOL(sym, "")
#define EXPORT_SYMBOL_GPL(sym) /
__EXPORT_SYMBOL(sym, "_gpl")
#endif

Analysis:

  1. kernel_symbol: 内核函数符号结构体

    value: 记录使用EXPORT_SYMBOL(fun),函数fun的地址
    name: 记录函数名称(”fun”),在静态内存中

  2. EXPORT_SYMBOL(sym) :导出函数符号,保存函数地址和名称

宏等价于:(去掉gcc的一些附加属性,MODULE_SYMBOL_PREFIX该宏一般是””)

static const char __kstrtab_sym[] = "sym";
static const struct kernel_symbol __ksymtab_sym =
    {(unsigned long)&sym, __kstrtab_sym }
  1. gcc 附加属性

atrribute 指定变量或者函数属性。在此查看详细http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Variable-Attributes.html#Variable-Attributes

__attribute((section(“section-name”)) var : 编译器将变量var放在section-name所指定的data或者bss段里面。

很容易看出:EXPORT_SYMBOL(sym)将sym函数的名称kstrtab_sym记录在,段名为”kstrtab_strings”数据段中。 将sym所对应的kernel_symbol记录在名为__ksymtab段中。

EXPORT_SYMBOL_GPL(sym) 和EXPORT_SYMBOL不同之处在于sym对应的kenel_symbol记录在__ksymtab_gpl段中。

David++