/************************************************************************************linux
*本文爲我的學習記錄,若有錯誤,歡迎指正。數據結構
* http://www.javashuo.com/article/p-kclgvccq-m.htmlpost
* https://blog.csdn.net/qingkongyeyue/article/details/72935439學習
************************************************************************************/優化
在Linux內核的/kernel/include/linux/init.h文件中,定義了一些初始化宏。spa
初始化宏的做用主要有如下兩點:.net
1)保證內核的初始化函數按照指定的順序來執行;code
2)提升系統效率。blog
(1)保證內核的初始化函數按照指定的順序來執行
初始化宏的實質是段聲明。在內核連接的時候,被初始化宏修飾的函數將被連接至指定的段。內核初始化時,會按照相應段的優先級來順序執行初始化函數。
kernel將初始化要執行的init函數,分爲7個級別:
1)core_initcall
2)postcore_initcall
3)arch_initcall
4)subsys_initcall
5)fs_iitcall
6)device_initcall
7)late_initcall
這7個級別優先級遞減,即先執行core_initcall, 最後執行late_initcall。經過使用初始化宏,gcc會將初始化代碼按下面的結構安排:
在內核初始化時,從__initcall_start到__initcall_end之間的initcall被一次執行。
(2)提升系統效率
初始化代碼的特色是,在系統啓動時運行,且一旦運行後立刻推出內存,再也不佔用內存。
初始化宏的實質是段聲明。在內核連接的時候,被初始化宏修飾的函數將被連接至指定的段。
//標記內核啓動時所用的初始化代碼,內核啓動完成後就再也不使用 #define __init __section(.init.text) __cold notrace //標記內核啓動時所用的初始化數據結構,內核啓動完成後再也不使用 #define __initdata __section(.init.data) //標記模塊退出代碼,對非模塊無效 #define __exit __section(.exit.text) __exitused __cold //標記設備初始化所用的代碼 #define __devinit __section(.devinit.text) __cold //標記設備初始化所用的數據結構 #define __devinitdata __section(.devinit.data) //標記設備移除時所用的代碼 #define __devexit __section(.devexit.text) __exitused __cold
對於驅動程序模塊來講,這些優化標記使用的狀況以下: