LINUX核心中的xx_initcall初始化標號__LINUX

來源:互聯網
上載者:User

LINUX核心中的xx_initcall初始化標號

 

田海立@CSDN 2011-07-02

 

          LINUX核心中有很多的初始化指示標誌postcore_initcall(), arch_initcall(), subsys_initcall(), device_initcall(), etc. 這些起什麼作用呢。查閱原始碼(android goldfish-2.6.29)並搜尋網上相關文章,對此做一總結。 初始化標號

先看這些宏的定義(定義在檔案include/linux/init.h中) [cpp] view plain copy #define pure_initcall(fn)               __define_initcall("0",fn,0)   #define core_initcall(fn)               __define_initcall("1",fn,1)   #define core_initcall_sync(fn)          __define_initcall("1s",fn,1s)   #define postcore_initcall(fn)           __define_initcall("2",fn,2)   #define postcore_initcall_sync(fn)      __define_initcall("2s",fn,2s)   #define arch_initcall(fn)               __define_initcall("3",fn,3)   #define arch_initcall_sync(fn)          __define_initcall("3s",fn,3s)   #define subsys_initcall(fn)             __define_initcall("4",fn,4)   #define subsys_initcall_sync(fn)        __define_initcall("4s",fn,4s)   #define fs_initcall(fn)                 __define_initcall("5",fn,5)   #define fs_initcall_sync(fn)            __define_initcall("5s",fn,5s)   #define rootfs_initcall(fn)             __define_initcall("rootfs",fn,rootfs)   #define device_initcall(fn)             __define_initcall("6",fn,6)   #define device_initcall_sync(fn)        __define_initcall("6s",fn,6s)   #define late_initcall(fn)               __define_initcall("7",fn,7)   #define late_initcall_sync(fn)          __define_initcall("7s",fn,7s)  

  __define_initcall

這些宏都用到了__define_initcall(),再看看它的定義(同樣定義在檔案include/linux/init.h中) [cpp] view plain copy #define __define_initcall(level,fn,id) \           static initcall_t __initcall_##fn##id __used \           __attribute__((__section__(".initcall" level ".init"))) = fn  

 

這其中initcall_t是函數指標,原型如下, [cpp] view plain copy typedef int (*initcall_t)(void);  

 

而屬性 __attribute__((__section__())) 則表示把對象放在一個這個由括弧中的名稱所指代的section中。

所以__define_initcall的含義是:

1) 聲明一個名稱為__initcall_##fn的函數指標;

2) 將這個函數指標初始化為fn;

3) 編譯的時候需要把這個函數指標變數放置到名稱為 ".initcall" level ".init"的section中。


3.  放置.initcall.init SECTION

明確了__define_initcall的含義,就知道了是分別將這些初始化標號修飾的函數指標放到各自的section中的。

SECTION“.initcall”level”.init”被放入INITCALLS(include/asm-generic/vmlinux.lds.h) [cpp] view plain copy #define INITCALLS                                                   \               *(.initcallearly.init)                                  \               VMLINUX_SYMBOL(__early_initcall_end) = .;               \               *(.initcall0.init)                                      \               *(.initcall0s.init)                                     \               *(.initcall1.init)                                      \               *(.initcall1s.init)                                     \               *(.initcall2.init)                                      \               *(.initcall2s.init)                                     \               *(.initcall3.init)                                      \               *(.initcall3s.init)                                     \               *(.initcall4.init)                                      \               *(.initcall4s.init)                                     \               *(.initcall5.init)                                      \               *(.initcall5s.init)                                     \               *(.initcallrootfs.init)                                 \               *(.initcall6.init)                                      \               *(.initcall6s.init)                                     \               *(.initcall7.init)                                      \               *(.initcall7s.init)  

 

__initcall_start和__initcall_end以及INITCALLS中定義的SECTION都是在arch/xxx/kernel/vmlinux.lds.S中放在.init段的。 [plain] view plain copy SECTIONS   {           .init : {                   __initcall_start = .;                           INITCALLS                   __initcall_end = .;           }   }  

 

4.   初始化.initcallxx.init裡的函數

而這些SECTION裡的函數在初始化時被順序執行(init核心線程->do_basic_setup()[main.c#778]->do_initcalls())。

程式(init/main.c檔案do_initcalls()函數)如下,do_initcalls()把.initcallXX.init中的函數按順序都執行一遍。 [cpp] view plain copy for (call = __early_initcall_end; call < __initcall_end; call++)           do_one_initcall(*call);  

 

*************************** 本文完 *****************************

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.