2010年1月15日 星期五

Linux Kernel: __init, __initdata屬性

在trace Linux核心原始碼很常看到__init和__initdata兩個屬性。其原型如下:
#define __init __section(.init.text) __cold notrace
#define __initdata __section(.init.data)


只要函數被定義__init屬性,代表此函數的所有內容被編譯器放置在.init.text節區。此節區代表該函數只會執行一次,此後就不會再執行,因此執行完該函數,核心會將該函數所佔記憶體空間釋放出來。__init屬性非常適合裝置驅動程式的init_module函數,其範例宣告如下:
static int __init dm_init(void); (from linux-source-2.6.31/drivers/md/dm.c)


利用objdump觀察dm_init函數被放置在哪個節區:
adrian@adrian-laptop:/usr/src/linux-source-2.6.31$ objdump -x drivers/md/built-in.o | grep md_init
00000000 l F .init.text 000000de md_init
00000000 l O .initcall4.init 00000004 __initcall_md_init4


__initdata屬性跟__init屬性的作用大同小異,唯一不同在於前者放置在.init.data節區。

範例:
static int (*_inits[])(void) __initdata = {
     local_init,
     dm_target_init,
     dm_linear_init,
     dm_stripe_init,
     dm_kcopyd_init,
     dm_interface_init,
};

利用objdump觀察_inits變數被放置在哪個節區:
adrian@adrian-laptop:/usr/src/linux-source-2.6.31$ objdump -x drivers/md/built-in.o | grep _inits
00000000 l O .init.data 00000018 _inits


問題來了,釋放記憶體的工作由核心的哪一函數負責呢? 答案是: free_initmem (arch/x86/mm/init.c)

【Reference】
FAQ/InitExitMacros
Linux Kernel Source 2.6.31

沒有留言: