這些宏包括 __init、__initdata、__initfunc()、asmlinkage、ENTRY()、FASTCALL()等等。它們的定義主要位於 Include\linux\linkage.h和 include\asm-i386\Init.h以及其他一些.h文件中。
1) __init位置:include\asm-i386\Init.h
定義:#define __init __attribute__ ((__section__ (".text.init")))
注釋:這個標志符和函數聲明放在一起,表示gcc編譯器在編譯的時候需要把這個函數放.text.init section中,而這個section在內核完成初始化之後,會被釋放掉。
舉例:asmlinkage void __init start_kernel(void){...}
2) __initdata
位置:include\asm-i386\Init.h
定義:#define __initdata __attribute__ ((__section__ (".data.init")))
注釋:這個標志符和變量聲明放在一起,表示gcc編譯器在編譯的時候需要把這個變量放在.data.init section中,而這個section在內核完成初始化之後,會被釋放掉。
舉例:static struct kernel_param raw_params[] __initdata = {....}
3) __initfunc()
位置:include\asm-i386\Init.h
定義: #define __initfunc(__arginit) \
__arginit __init; \
__arginit
注釋: 這個宏用來定義一個 __init 函數。
舉例: __initfunc(void mem_init(unsigned long start_mem, unsigned long e
nd_mem)) {....}
4) asmlinkage
位置:Include\linux\linkage.h
定義:#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
注釋:這個標志符和函數聲明放在一起,告訴gcc編譯器該函數不需要通過任何寄存器來傳遞參數,參數只是通過堆棧來傳遞。
舉例:asmlinkage void __init start_kernel(void){...}
5) ENTRY()
位置:Include\linux\linkage.h
定義: #define ENTRY(name) \
.globl SYMBOL_NAME(name); \
ALIGN; \
SYMBOL_NAME_LABEL(name)
注釋: 將name聲明為全局,對齊,並定義為標號。
舉例: ENTRY(swapper_pg_dir)
.long 0x00102007
.fill __USER_PGD_PTRS-1,4,0
/* default: 767 entries */
.long 0x00102007
/* default: 255 entries */
.fill __KERNEL_PGD_PTRS-1,4,0
等價於
.globl swapper_pg_dir
.align 16,0x90
/* if i486 */
swapper_pg_dir:
.long 0x00102007
.fill __USER_PGD_PTRS-1,4,0
/* default: 767 entries */
.long 0x00102007
/* default: 255 entries */
.fill __KERNEL_PGD_PTRS-1,4,0
6) FASTCALL()
位置:Include\linux\kernel.h
定義:#define FASTCALL(x) x __attribute__((regparm(3)))
注釋:這個標志符和函數聲明放在一起,帶regparm(3)的屬性聲明告訴gcc編譯器這個函數可以通過寄存器傳遞多達3個的參數,這3個寄存器依次為EAX、EDX 和 ECX。更多的參數才通過堆棧傳遞。這樣可以減少一些入棧出棧操作,因此調用比較快。