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