EXPORT_SYMBOL

參考:http://shaojiashuai123456.iteye.com/blog/840015


include/linux/module.h:

/* 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))) \
	= MODULE_SYMBOL_PREFIX #sym;                    	\
	static const struct kernel_symbol __ksymtab_##sym	\
	__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")

#define EXPORT_SYMBOL_GPL_FUTURE(sym)				\
	__EXPORT_SYMBOL(sym, "_gpl_future")

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 }
 
3. gcc 附加屬性

1>. __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段中。

4./proc/kallsyms
cat /proc/kallsyms會打印出內核當前的符號表,例如:
...
d8834a24 t snd_free_sgbuf_pages [snd_page_alloc]
c0180d7a U create_proc_entry [snd_page_alloc]
d88341d8 T snd_dma_free_pages [snd_page_alloc]
c013d858 U __get_free_pages [snd_page_alloc]
d8834ab5 t snd_malloc_sgbuf_pages [snd_page_alloc]
c014f906 U kmem_cache_alloc [snd_page_alloc]
c0106dcd U dma_alloc_coherent [snd_page_alloc]
...
其中第一列是該符號在內核地址空間中的地址;第二列是符號屬性,小寫表示局部符號,大寫表示全局符號,具體含義參考man nm; 第三列表示符號字符串. 
這裏只顯示EXPORT_SYMBOL,EXPROT_SYMBOL_GPL處理過的符號。

5.System.map內核符號文件
通過more /boot/System.map 可以查看內核符號列表。
可以顯示編譯好內核後所有在內核中的符號,模塊中的要另行查看。

6.通過nm vmlinux也可以查看內核符號列表
可以顯示編譯好內核後所有在內核中的符號,模塊中的要另行查看。

發佈了64 篇原創文章 · 獲贊 17 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章