在做Openwrt中IPv6的過渡方案6in4的過程中,遇到了啟動中的一些問題,加上 siaisjack 的文章 《OpenWrt啟動過程分析+添加自啟動腳本》 中的一些內容,重新整理一下。(本人菜鳥,歡迎批評指正)
啟動流程預覽:
- CFE
- LINUX
- init相關
- /etc/preinit
- /sbin/init
- /etc/inittab
- /etc/rc.d/S*
CFE
引導內核啟動的程序,即Common Firmware Environment,簡稱CFE,它是BroadCom公司專用的bootloader。其開發者為Mitch Lichtenberg。CFE是博通公司基于MIPS芯片的bootloader,就如同u-boot是啟動內核的引導程序一樣。CFE支持基本的設備訪問,其設計理念是滿足引導程序所具有的基本功能,如:Flash設備等存儲設備的訪問、基本的UI接口。(源自 百度百科)
它的任務只是創造一個簡單的環境,讓系統先運行起來。除了能夠跳轉到特定地址上啟動操作系統(如Linux)外,它還能讓你download東西到上面,比如download一個linux,然后啟動它。另外,值得一提的是,CFE在啟動之后會有1,2秒的時間等待由tftp上傳的內核并燒寫到flash上,這就給一些操作系統損壞但CFE還能工作的"磚頭"板一個起死回生的機會。請注意一旦linux啟動之后,將由linux全部接管系統。(siaisjack)
話不多說,看圖:
這是我用TTL小板看到最開始的輸出,這部分沒有弄明白,但是我猜應該是內存相關的操作,但是下邊這張圖應該就是傳說中的CFE了:
在這一部分系統默認是選擇的3,如果在啟動到這部分的時候提前點一下2,就可以通過TFTP來刷進去例如Uboot之類的,就可以達到救磚的作用,按說也是可以直接刷固件的,但是我還沒有成功過。
Linux
當系統通過默認的3開始啟動內核以后,就開始了Linux的啟動,從上圖中可以看到相關信息。而最下邊一句話“似乎”應該標志著第二階段的結束:LINUX started...
。
在這里,CFE會傳遞給內核一個命令行的參數,這個可以在linux啟動起來之后用下面的命令查看(這里是原作者的輸出):
root@OpenWrt:/# cat /proc/cmdline
console=ttyS0,115200 mtdparts=spi_flash:1m(u-boot)ro,3m(kernel),-(rootfs)
我在啟動信息中找到了如下一句話,介紹了相關的Linux版本的信息:
這張是我的輸出:
init相關
在這一部分主要是系統啟動完成后,把控制權交給init來完成其他初始化,在這部分我找了兩篇比較好的博客,大家共同學習,分別是《關于Linux下/sbin/init程序的執行過程》和 《linux系統/sbin/init執行過程》。下面這部分是部分我的看法。
/etc/preinit
該過程為Linux的初始化,可通過:
root@OpenWrt:/# cat /etc/preinit
查看相關代碼(下圖)。
(以我四級沒過的水平的英語,這個pre應該是啥啥以前的前綴嘛,就是init以前嘛。 = 。= )
exec /sbin/init
OpenWrt上也就是busybox的init程序。
/etc/inittab
這后兩行決定了是否開啟TTL,如果想用TTL的話把后兩行的注釋取消掉。
/etc/rc.d/S*
這一部分也是值得好好說一下的,仔細對比,會發現每一個 /etc/init.d/
下的腳本在 /etc/rc.d/
下都有一個類似于 S*
的鏈接,所以,當我們要通過系統自動啟動一些東西的時候,可以通過這個方法來實現。
我們打開一個簡單的腳本 led
,發現有這樣一行:START=96
,而/etc/rc.d/
下對應的腳本恰好也是S96led
,其實,當我們寫好腳本以后,執行 /etc/init.d/led enable
,系統就會“自動”生成一個根據 START
后邊的數字大小的鏈接在 /etc/rc.d/
下,系統啟動時就會根據數字大小依次調用。