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