__init宏使內建模塊中的init函數在執行完成後釋放掉,僅用於初始化。編譯器將所有代碼存儲到特殊的內存段中,初始化結束就釋放這段內存。
__initdata,和__init的作用基本上一樣,不過它是針對數據。
__exit和__exitdata 僅用於退出和關閉線程,一般在注銷設備驅動程序時使用。
likely和unlikely 的實現:#define likely(x) __builtin_expect(!!(x),1)#define unlikely(x) __builtin_expect(!!(x),0)
__builtin_expect() 是編譯器來預測分之。
通知程序鏈// notifier_block 對象鏈表。
include/linux/notifier.h struct notifier_block { int(*notifier_call)(struct notifier_block *self, unsigned long, void *); struct notifier_block *next; 指向鏈中的下一個通知塊。 int priority; 優先級聲明};
#define __define_initcall(level,fn,id) \ static initcall_t __initcall_##fn##id __attribute_used__ \ __attribute__ ((__section__(".initcall" level ".init"))) = fn這條宏帶有3個參數:level,fn, id。1.用來定義類型為initcall_t的static函數指針,函數指針的名稱由參數fn和id決定:__initcall_##fn##id,這就是函數指針的名稱,它其實是一個變量名稱。利用宏的參數產生名稱。
2. __attribute__ ((__section__ (".initcall" level ".init"))),輸入段的名稱由level決定,如果level="1",則輸入段是.initcall1.init,如果level="3s",則輸入段是.initcall3s.init。這一函數指針變量就是放在用這種方法決定的輸入段中的。
3. 函數指針變量的初始值其實就是宏參數fn,實際使用中,fn其實就是真實定義好的函數。一般用法如下:#define pure_initcall(fn) __define_initcall("0",fn,0)#define core_initcall(fn) __define_initcall("1",fn,1)
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))asmllinkage這個標志符和函數聲明放在一起,告訴gcc編譯器該函數不需要通過任何寄存器來傳遞參數,參數只是通過堆棧來傳遞。