和我们通常写程序不同,如果仅仅是全局变量,虽然编译内核的时候能连接成功,但是连接之后再就没有办法使用这个变量了
而模块的加载是运行时的,它引用某个变量时,内核需要解析它,否则模块不能工作,EXPORT_SYMBOL 的定义如下
- #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 }
它放在固定的节,这样内核解析的时候就能在此节里找符号了,之后的重定位和普通的连接原理类似.
-------------------------------------------------------------------------------------------
EXPORT_SYMBOL宏的用法:
在a.c中这样写:
int var = 100; //var是全局的.
EXPORT_SYMBOL(var);然后在b.c中调用它的话就:
extern int var;
阅读(3975) | 评论(0) | 转发(3) |