1 系統(tǒng)介紹
任何系統(tǒng)的啟動(dòng)都是開發(fā)人員首要關(guān)注的問題,因?yàn)橹挥辛私饬讼到y(tǒng)的啟動(dòng)流程和啟動(dòng)機(jī)制,才能真正掌握一個(gè)系統(tǒng),如果對(duì)啟動(dòng)的啟動(dòng)不熟悉的話,是不可能真正用好一個(gè)系統(tǒng),openwrt系統(tǒng)也不例外,他的啟動(dòng)和一般的嵌入式系統(tǒng)啟動(dòng)還有所區(qū)別,現(xiàn)在咱們就分析一下openwrt的啟動(dòng)流程。
2 內(nèi)核補(bǔ)丁
在Openwrt的官網(wǎng)上面下載的源碼,其中包括了一些內(nèi)核補(bǔ)丁,這里究竟為什么要給內(nèi)核做補(bǔ)丁呢?因?yàn)镺penwrt為了支持更多的路由器,更多的操作和Openwrt特有的一些內(nèi)核功能,linux源碼是不具備的,這樣Openwrt為了增加這些功能,就需要在linux官網(wǎng)上面下載的源代碼中做一些修改,在這里體現(xiàn)為給linux源碼打補(bǔ)丁。Openwrt源碼中的linux補(bǔ)丁文件放在target/linux/generic文件下面,有對(duì)于不同版本的linux內(nèi)核補(bǔ)丁文件。MT7621采用的是4.14版本的內(nèi)核,所以他的補(bǔ)丁文件在patches-3.10目錄下面。這里是所有的內(nèi)核補(bǔ)丁文件,在編譯Openwrt的時(shí)候,會(huì)首先把他們拷貝到內(nèi)核目錄下面,然后在內(nèi)核上面打上這些補(bǔ)丁,然后再編譯內(nèi)核。咱們首先分析他對(duì)于linux啟動(dòng)的補(bǔ)丁,它的名字是921-use_preinit_as_init.patch(在Ubuntu源文件中),咱們可以看看他的內(nèi)容。
可以看到他它修改linux內(nèi)核中默認(rèn)的啟動(dòng)項(xiàng),可以看到它首先啟動(dòng)/etc/preinit(開發(fā)板的文件系統(tǒng)中),它是個(gè)腳本,咱們就從這個(gè)腳本說起。
3 preinit
preinit腳本在etc目錄下面,首先先看看他的內(nèi)容:
這就是個(gè)bash腳本,前半部分只是定義了一些變量,先記住他們的內(nèi)容即可,有兩個(gè)函數(shù)是我們需要了解的,boot_hook_init和boot_run_hook。他們定義在/lib/functions/preinit.sh文件中,boot_hook_init是初始化一個(gè)函數(shù)隊(duì)列,boot_run_hook是運(yùn)行一個(gè)函數(shù)隊(duì)列,還有一個(gè)這個(gè)文件沒有體現(xiàn),后面的文件中會(huì)遇到,這里說明一下,boot_book_add這個(gè)是在一個(gè)函數(shù)隊(duì)列中添加一個(gè)函數(shù)。然后就是執(zhí)行:
循環(huán)執(zhí)行/lib/preinit 目錄下面的腳本,這里簡要分析/lib/preinit目錄下的一個(gè)文件,循環(huán)執(zhí)行/lib/preinit目錄下面的腳本,這里簡要分析一個(gè),這里分析02_default_set_state,首先看看他的內(nèi)容。
可以看到它就是在preinit_main函數(shù)隊(duì)列中增加一個(gè)函數(shù),這個(gè)函數(shù)就是簡單的執(zhí)行一個(gè)腳本。當(dāng)運(yùn)行preinit_main的時(shí)候,隊(duì)列中的所有函數(shù)就會(huì)依次執(zhí)行。其他文件可以自行分析,都比較簡單。
最后在preinit腳本中執(zhí)行preinit_main。執(zhí)行完這個(gè)腳本之后init進(jìn)程會(huì)根據(jù)inittab文件執(zhí)行其他的啟動(dòng)項(xiàng)。
4 inittab
inittab為linux初始化文件系統(tǒng)時(shí)init初始化程序用到的配置文件。這個(gè)文件負(fù)責(zé)設(shè)置init初始化程序初始化腳本在哪里;每個(gè)運(yùn)行級(jí)初始化時(shí)運(yùn)行的命令;開機(jī)、關(guān)機(jī)、重啟對(duì)應(yīng)的命令;各運(yùn)行級(jí)登陸時(shí)所運(yùn)行的命令。
如果存在/etc/inittab文件,Busyboxinit程序解析它,然后按照它的指示創(chuàng)建各種子進(jìn)程,否則使用默認(rèn)的配置創(chuàng)建子進(jìn)程。
/etc/inittab文件中每個(gè)條目用來定義一個(gè)子進(jìn)程,并確定它的啟動(dòng)方法,格式如下
:::
1、id:表示這個(gè)子進(jìn)程要使用的控制臺(tái),如果省略,則使用與init進(jìn)程一樣的控制臺(tái).
2、runlevels:這個(gè)字段沒有意義,可以省略。在linux有意義.
3、action:表示init進(jìn)程如何控制這個(gè)子進(jìn)程,具體取值見下表.
4、process:要執(zhí)行的程序,它可以是可執(zhí)行程序,也可以是腳本.如果process字段前有“-”字符,這個(gè)程序被稱為“交互的”.
【attention】action取值
名稱 | 執(zhí)行條件 | 說明 |
---|---|---|
sysinit | 系統(tǒng)啟動(dòng)后最先執(zhí)行 | 指定初始化腳本路徑,只執(zhí)行一次,init進(jìn)程等待它結(jié)束才繼續(xù)執(zhí)行其它動(dòng)作 |
wait | 系統(tǒng)執(zhí)行完sysinit進(jìn)程后 | 只執(zhí)行一次,init進(jìn)程等待它結(jié)束才繼續(xù)執(zhí)行其它動(dòng)作 |
once | 系統(tǒng)執(zhí)行完wait進(jìn)程后 | 只執(zhí)行一次,init進(jìn)程不等待它結(jié)束 |
respawn | 啟動(dòng)完once進(jìn)程后 | init進(jìn)程監(jiān)測發(fā)現(xiàn)子進(jìn)程退出時(shí),重新啟動(dòng)它,永不結(jié)束.如Shell命令解釋器 |
askfirst | 啟動(dòng)完respawn進(jìn)程后 | 與respawn類似,不過init進(jìn)程先輸出“Please pressEntertoactivatethis console”,等用戶輸入回車后才啟動(dòng)子進(jìn)程 |
shutdown | 當(dāng)系統(tǒng)關(guān)機(jī)時(shí) | 即重啟、關(guān)閉系統(tǒng)時(shí)執(zhí)行的程序 |
restart | 系統(tǒng)重啟時(shí) | init進(jìn)程重啟時(shí)執(zhí)行的程序,通常是init程序本身先重新讀取、解析/etc/inittab文件,再執(zhí)行restart程序 |
ctrl+alt+del | 按下Ctrl+Alt+Del | 鍵時(shí)按Ctrl+Alt+Del組合鍵時(shí)執(zhí)行的程序 |
先肯看/etc/inittab中的內(nèi)容:
從上面的分析可以看出它在開機(jī)啟動(dòng)的時(shí)候執(zhí)行/etc/init.d/rcS腳本,以前是有/etc/init.d/rcS腳本的,現(xiàn)在的openwrt已經(jīng)去掉了這個(gè)腳本文件,只要有rcSSboot這幾個(gè)參數(shù)就可以,但是功能是有的就是按順序執(zhí)行/etc/rc.d下面的各個(gè)腳本,以S開頭代表啟動(dòng)的時(shí)候執(zhí)行的腳本,與命令行中的S對(duì)應(yīng),以K開頭的代表關(guān)機(jī)的時(shí)候需要執(zhí)行的腳本,與命令行中的K對(duì)應(yīng)。
5 總結(jié)
從上面的分析我們來總結(jié)一下openwrt的啟動(dòng)流,/etc/preinit->/lib/preinit/->/etc/inittab->/etc/rc.d/S。
-
嵌入式
+關(guān)注
關(guān)注
5082文章
19104瀏覽量
304794 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4327瀏覽量
62569 -
OpenWrt
+關(guān)注
關(guān)注
10文章
130瀏覽量
39296 -
啟動(dòng)流程
+關(guān)注
關(guān)注
0文章
14瀏覽量
6473 -
腳本
+關(guān)注
關(guān)注
1文章
389瀏覽量
14858
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論