0. 背景
EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。
在模块函数定义之后使用“EXPORT_SYMBOL(函数名)”来声明。
在调用该函数的另外一个模块中使用extern对之声明。
//经观察内核里面使用EXPORT_SYMBOL声明之后,很多不需要extern也能直接使用函数;
先加载定义该函数的模块,然后再加载调用该函数的模块,请注意这个先后顺序。
1. 举例
函数声明位置:
LA.UM.5.6\kernel\msm-3.18\kernel\irq\devres.c
函数使用位置:
LA.UM.5.6\kernel\msm-3.18\drivers\input\hall_sensor.c
grep一下不存在extern的地方;
2. EXPORT_SYMBOL代码追踪
EXPORT_SYMBOL(devm_request_threaded_irq);
->__EXPORT_SYMBOL(sym, “”)
->
/* 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"), aligned(1))) \
= VMLINUX_SYMBOL_STR(sym); \
extern const struct kernel_symbol __ksymtab_##sym; \
__visible const struct kernel_symbol __ksymtab_##sym \
__used \
__attribute__((section("___ksymtab" sec "+" #sym), unused)) \
= { (unsigned long)&sym, __kstrtab_##sym }
3. 代码结构简化与理解
这个宏代码很庞大,让人看的懵逼。
我们尝试优化代码,首先这个extern typeof(sym) sym;
extern int sym; typeof(sym)用于获取这个函数的返回值。
__attribute__是gcc中的属性(__used也是gcc属性),用于向指定的函数或者变量添加相关的属性,为了不影响对变量定义的理解,先将__attribute__属性掩盖,
简化如下:
/* Some toolchains use a `_' prefix for all user symbols. */
#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
#define __VMLINUX_SYMBOL(x) _##x
#define __VMLINUX_SYMBOL_STR(x) "_" #x
#else
#define __VMLINUX_SYMBOL(x) x
#define __VMLINUX_SYMBOL_STR(x) #x
#endif
这个也不晓得加没加_,这里按照不开这个CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX宏来分析:
一个#的意思是把后面的变成字符串;
VMLINUX_SYMBOL_STR(sym); --> “sym”
两个##号的意思是把前后链接起来;
所以宏继续简化如下:
4. 那我们再看这个宏干了啥
-
首先把传进来的这个函数指针声明为全局;
-
定义了一个const类型的字符串数组来存放这个函数指针的名字
-
定义一个内核符号结构__ksymtab_sym用于存放导出符号的内存地址和名称,
(unsigned long)&sym存地址,__kstrtab_sym指针传给name
5. 补充
// (unsigned long)&sym,这行代码,首先指针本身的类型都是unsigned long int,所以需要强制类型转换,此外这里&sym的意思,是取指向函数sym的指针,如果直接用sym的话,
表明函数的首地址.
gcc编译运行两者结果是一致的:
__attribute__相关的理解可以参阅:
http://blog.sina.com.cn/s/blog_661314940100qujt.html
还有以下这篇文章对我得帮助很大,再次特别特别感谢博主:
https://blog.csdn.net/fzubbsc/article/details/33726329