要瞭解Linux Kernel代碼的分段資訊,需要瞭解一下gcc的__attribute__的編繹屬性或定義的函數或數,__attribute__主要用於改變所聲明據的特性,它有很多子項,用於改變作用對象的特性。比如對函數,noline將禁止進行內聯擴充、noreturn表示沒有傳回值、pure表明函數除傳回值外,不會通過其它(如全域變數、指標)對函數外部產生任何影響。但這裡我們比較感興趣的是對程式碼片段起作用子項section。
__attribute__的section子項的使用格式為:
__attribute__((section("section_name")))
其作或用是將作用的函數資料放入指定名為"section_name"輸入段。
這裡還要注意一下兩個概念:輸入段和輸出段
輸入段和輸出段是相對於要產生最終的elf或binary時的Link過程說的,Link過程的輸入大都是由原始碼編繹產生的目標檔案.o,那麼這些.o檔案中包含的段相對link過程來說就是輸入段,而Link的輸出一般是可執行檔elf或庫等,這些輸出檔案中也包含有段,這些輸出檔案中的段就叫做輸出段。輸入段和輸出段本來沒有什麼必然的聯絡,是互相獨立,只是在Link過程中,Link程式會根據一定的規則(這些規則其實來源於Link Script),將不同的輸入段重新組合到不同的輸出段中,即使是段的名字,輸入段和輸出段可以完全不同。
其用法舉例如下:
int var __attribute__((section(".xdata"))) = 0;
這樣定義的變數var將被放入名為.xdata的輸入段,(注意:__attribute__這種用法中的括弧好像很嚴格,這裡的幾個括弧好象一個也不能少。)
static int __attribute__((section(".xinit"))) functionA(void)
{
.....
}
這個例子將使函數functionA被放入名叫.xinit的輸入段。
需要著重注意的是,__attribute__的section屬性只指定對象的輸入段,它並不能影響所指定對象最終會放在可執行檔的什麼段。
2. Linux Kernel原始碼中與段有關的重要宏定義
A. 關於__init、__initdata、__exit、__exitdata及類似的宏
開啟Linux Kernel原始碼樹中的檔案:include/init.h,可以看到有下面的宏定議:
#define __init __attribute__ ((__section__ (".init.text"))) __cold
#define __initdata __attribute__ (( __section__ (".init.data")))
#define __exitdata __attribute__ (( __section__ (".exit.data")))
#define __exit_call __attribute_used__ __attribute__ (( __section__ (".exitcall.exit")))
#define __init_refok oninline __attribute__ ((__section__ (".text.init.refok")))
#define __initdata_refok __attribute__ ((__section__ (".data.init.refok")))
#define __exit_refok noinline __attribute__ ((__section__ (".exit.text.refok")))
.........
#ifdef MODULE
#define __exit __attribute__ (( __section__ (".exit.text"))) __cold
#else
#define __exit __attribute_used__ __attribute__ ((__section__ (".exit.text"))) __cold
#endif
對於經常寫驅動模組或翻閱Kernel原始碼的人,看到熟悉的宏了吧:__init, __initdata, __exit, __exitdata。
__init 宏最常用的地方是驅動模組初始化函數的定義處,其目的是將驅動模組的初始化函數放入名叫.init.text的輸入段。當核心啟動完畢後,這個段中的記憶體會被釋放掉供其他使用。
__initdata宏用於資料定義,目的是將資料放入名叫.init.data的輸入段。其它幾個宏也類似。
另外需要注意的是,在以上定意中,用__section__代替了section。還有其它一些類似的宏定義,這裡不一一列出,其作用都是類似的。
原文連結:http://www.cnblogs.com/hanyan225/archive/2010/12/30/1922232.html