前置:這裡使用的linux版本是4.8,x86體系。
其實linux的核心啟動的入口檔案還是非常好找的,init/main.c。
首先了解的是static和extern的差別:
這個代碼說的是kernel_init函數的定義在這個檔案中,extern說明init_IRQ函數的定義在其他檔案中。
這三個extern分别是對中斷的初始化,對fork功能的初始化,對基數樹的初始化。不過具體不知道為什麼有的函數以init_xxx為風格,有的又以xxx_init的風格來做。
main的第一行看到了這麼個語句
感覺有點奇怪,原來還有#define <宏名> 而沒有定義具體的值。其實這個可以當作已經有定義,且定義了空串來了解。
<a href="http://bbs.csdn.net/topics/390960776?page=1">http://bbs.csdn.net/topics/390960776?page=1</a>
繼續往下面看,還會看到
bool early_boot_irqs_disabled __read_mostly;
這裡最後的__read_mostly 是一個宏,它标記了前面這個變量是很經常被讀取的。那麼做了标記有什麼用呢?
如果在有緩存的平台上,它就能把這個變量存放到cache中,以保證後續讀取的速度。這個宏定義在 arch/arm/include/asm/cache.h
這裡的意思是将這個資料結構連結進data.read_mostly段。
EXPORT_SYMBOL(system_state);
這個是和extern一起使用的,表示system_state這個方法在這個子產品中定義了,提供給其他子產品使用。
在其他子產品中,隻需要使用extern 就可以使用這個方法。
這裡就涉及到子產品的概念。
子產品是linux核心對外提供的一個插件機制,由于linux是單核心,這個單核心是相對微核心來說的。是以linux很大可能會非常龐大,這個子產品機制就是對單核心的一種補充,把一些功能放給核心子產品開發。比如像上面的那個代碼,就是對核心提供了system_state的函數接口。
下面代碼:
char __initdata boot_command_line[COMMAND_LINE_SIZE];
這裡的__initdata也是一個宏,定義在include/linux/init.h
同上面__read_mostly一樣,是用來把這個變量綁定在某個區裡面。
<a href="http://blog.csdn.net/beatbean/article/details/8448623">http://blog.csdn.net/beatbean/article/details/8448623</a>
這個圖就說明了什麼是__section。它的功能有點像是全局變量,隻是這個全局變量是對彙編這個層次的表達,某個變量,我固定在某個記憶體段裡面。這麼做其實還有一個好處,段也是一種分類,比如這個段存儲的是init函數的變量,那麼等初始化結束之後,我把這個段的記憶體直接釋放。裡面的變量也一次性消除了。
下面看到一個很奇怪的方法
EXPORT_SYMBOL_GPL(static_key_initialized);
這個和之前的EXPORT_SYMBOL不一樣,多了一個GPL字尾。
由于子產品很有可能是第三方(非linux核心組成員)開發的。那麼有人希望自己開發的子產品是閉源的。它就會在自己開發的子產品裡面使用
MODULE_LICENSE("Proprietary")
來标記這個子產品是閉源的。相對的,如果你的子產品遵循GPL這個開源許可證規則,那麼則增加下面的:
MODULE_LICENSE("GPL");
好了,linux對這兩種許可證行為的子產品開放的接口并不相同,本節的這個函數就是說明這個方法隻對GPL的子產品開放。
<a href="http://www.ruanyifeng.com/blog/2010/02/why_gpl_is_a_better_choice.html">http://www.ruanyifeng.com/blog/2010/02/why_gpl_is_a_better_choice.html</a>
unsigned int reset_devices;
EXPORT_SYMBOL(reset_devices);
static int __init set_reset_devices(char *str)
{
reset_devices = 1;
return 1;
}
__setup("reset_devices", set_reset_devices);
這段代碼,首先需要了解__setup,這個函數就了解為:啟動時候如果有接收reset_devices參數,那麼就調用set_reset_devices方法。而詳細看了下set_reset_devices方法,裡面隻是把reset_devices變量設定為1,但是呢,這個reset_devices變量又是一個給所有子產品使用的變量。
是以這段代碼能達到的功能是隻要啟動參數有包含reset_device,通過設定reset_devices通知給所有子產品。
與__setup相對應的還有一個叫做early_param。這兩個宏函數的功能一樣,差別就在于early_param定義的參數比__setup更早。
<a href="http://www.linuxde.net/2013/02/12446.html">http://www.linuxde.net/2013/02/12446.html</a>
本文轉自軒脈刃部落格園部落格,原文連結:http://www.cnblogs.com/yjf512/p/5992038.html,如需轉載請自行聯系原作者