uclinux-2008r1(bf561)内核中的EXPORT_SYMBOL

本文详细解析了UCLinux内核中的EXPORT_SYMBOL宏定义及其作用,阐述了如何通过该宏为动态加载的模块提供必要的符号表,使模块能够调用内核函数。
 
   
在uclinux内核中,随处可见EXPORT_SYMBOL的定义,它的作用在于为动态插入内核的模块提供一个符号表,使之能调用内核中的函数。因而,如果内核不需要支持insmod,那么自然也就不需要EXPORT_SYMBOL。实际上,在内核没有定义CONFIG_MODULES这个宏的时候,EXPORT_SYMBOL这个宏定义什么也不做:
#define EXPORT_SYMBOL(sym)
而当需要支持insmod的时候,这个宏的定义就变成了:
#define MODULE_SYMBOL_PREFIX ""
#define __CRC_SYMBOL(sym, sec)
/* For every exported symbol, place a struct in the __ksymtab section */
#define __EXPORT_SYMBOL(sym, sec)                  /
     extern typeof(sym) sym;                   /
     __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, "")
下面以一个实际的EXPORT_SYMBOL来分析一下这个宏的作用。在mm/nommu.c的开头有这样的语句:
struct page *mem_map;
EXPORT_SYMBOL(mem_map);
代入EXPORT_SYMBOL宏之后就变成了:
     extern struct page * mem_map;                     
     static const char __kstrtab_mem_map[]         
     __attribute__((section("__ksymtab_strings")))     
     = mem_map;                   
     static const struct kernel_symbol __ksymtab_mem_map
     __attribute_used__                  
     __attribute__((section("__ksymtab" sec), unused)) 
     = { (unsigned long)&mem_map, __kstrtab_mem_map }
在这里kernel_symbol定义为:
struct kernel_symbol
{
     unsigned long value;
     const char *name;
};
很明显,在这里定义了两个全局变量__kstrtab_mem_map__ksymtab_mem_map,值得注意的是这两个变量都是放在特定的section中的,据此猜测insmod在读取模块文件后,必须根据此模块的符号表中的名称在__ksymtab这个段中按顺序查找符号,再将此符号相对应的value替换掉动态模块中的指针(当然,目前还不理解insmod是如何取得这个段的首地址的)。
在vmlinux.lds.s中为这两个段留了空间:
     __ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {      /
         VMLINUX_SYMBOL(__start___ksymtab) = .;             /
         *(__ksymtab)                         /
         VMLINUX_SYMBOL(__stop___ksymtab) = .;          /
     }                                    /
     /* Kernel symbol table: strings */                 /
        __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {    /
         *(__ksymtab_strings)                      /
     }                                    /
以上两个定义出现在RO_DATA的宏定义中,在vmlinux.lds.s中使用了此宏定义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌云阁主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值