天天看點

openwrt 啟動流程一、init程序介紹二、OpenWrt軟體啟動機制三、“/etc/init.d/*”腳本分析

一、init程序介紹

  • init程序是所有系統程序的父程序,它被核心調用起來并負責調用所有其他的程序。 如果任何程序的父程序退出,init程序将成為它的父程序。但是init程序是如何将其他程序調用起來的呢?接下來介紹

二、OpenWrt軟體啟動機制

第一步:

  • 核心啟動完成後讀取/etc/inittab檔案,然後執行inittab中的sysinit所指的腳本(/etc/init.d/rcS)
  • OpenWrt的inittab檔案内容如下:
  • openwrt 啟動流程一、init程式介紹二、OpenWrt軟體啟動機制三、“/etc/init.d/*”腳本分析

第二步:

  • 如果按照通常的簡單做法:我們會将每一個待啟動的程式啟動指令按行放入rcS檔案中,并順序執行。這種實作方法在軟體啟動程序清單不變時工作得非常好,如果需要動态修改,則不容易以程式來控制(在OpenWrt下,使用ls指令檢視不到/etc/init.d/rcS這個檔案)。OpenWrt引入了一個便于控制的啟動機制,這種機制是在/etc/rc.d目錄下建立每個軟體的軟連結方式,由rcS腳本在該目錄讀取啟動指令的軟連結, 然後啟動軟連結所指向的程式,由于每一個軟連結均包含一個數字,這樣就可以按照數字順序讀取并進行啟動了
  • 具體執行流程:執行/etc/init.d/rcS腳本時,給腳本傳遞兩個參數(分别為S何boot),接着rcS腳本通過run_scripts函數來啟動軟體,将每一個以/etc/rc.d/S開頭的腳本按照數字傳遞boot參數并調用
    • S:表示軟體啟動子產品,是和 K(軟體關閉)相對應的
    • boot:表示首次啟動
    openwrt 啟動流程一、init程式介紹二、OpenWrt軟體啟動機制三、“/etc/init.d/*”腳本分析
  • 例如從/etc/rc.d目錄下的腳本可以看出,就是先執行../init.d/sysfixtime,再執行../init.d/boot,以此類推......。幾個比較重要的程式如下:
    • S10boot:調用uci_apply_defaults執行第1此開機時的UCI配置初始化,該函數執行/etc/uci-defaults/下的所有腳本,執行成功後就删除,是以該目錄下的腳本隻有第一次開機才會執行
    • S10system:根據UCI配置檔案/etc/config/system配置系統,具體可參考該配置檔案
    • S11sysctl:根據/etc/sysctl.conf配置系統([-f  /etc/sysctl.conf]  && sysctl -p -e >&-)
    • S19filewall:啟動防火牆fw3,該工具來自openwrt軟體包package/network/config/firewal
    • S20network:根據UCI配置檔案/etc/config/network,使用守護程序/sbin/netifd來配置網絡
openwrt 啟動流程一、init程式介紹二、OpenWrt軟體啟動機制三、“/etc/init.d/*”腳本分析

三、“/etc/init.d/*”腳本分析

  • 上面那些最終調用的軟體啟動shell腳本,包含變量定義和函數定義(start、stop和restart等函數)
  • 備注:因為/etc/rc.d/下面檔案是/etc/int.d/下腳本的軟連結,根據軟連結的特性,我們檢視軟連結檔案也就可以通路到/etc/int.d/下面的腳本檔案
  • 另外使用 opkg 指令安裝軟體時一般均有執行權限,如果是自己手動新增腳本,不要忘記确認腳本是否有執行權限(通過運作 chmod +x /etc/init.d/hello指令來增加執行權限)

腳本分析

openwrt 啟動流程一、init程式介紹二、OpenWrt軟體啟動機制三、“/etc/init.d/*”腳本分析
  • /etc/rc.common:這個腳本沒有解析自己的指令行參數,這是通過“/etc/rc.common”腳本回調來完成的。第一行是特殊的注釋行,表示使用“/etc/rc.common”來提供一些基本函數,包含主函數及預設功能以及檢查腳本執行等
  • START、STOP變量:腳本的執行順序通過START和 STOP變量來定義
    • 如果這兩個變量被更改了,再次運作/etc/init.d/hello enable才會再次生效,并且這将删除以前建立的啟動連結,然後再根據新的變量定義建立連結(建立的啟動連結儲存在“/etc/rc.d”目錄下)
    • 如果多個初始化腳本有相同的啟動優先值,則調用順序取決于啟動腳本名稱的字母順序(在上上張圖中S10boot與S10system檔案中的START變量值相同,但是他們按照腳本名稱的字母排序啟動)
  • start()、stop()函數:腳本中最重要的函數是 start 和 stop,這兩個函數決定如何啟動和停止服務

rc.common函數含義

  • 備注:其中的start()、stop()函數實作為空,供應用軟體重新實作,相當于C++語言中的虛函數
  • enable、disable 和 enabled函數提供自啟動狀态的設定和查詢
  • help函數提供指令幫助資訊,如果你不帶參數運作軟體指令,将會自動調用help函數輸出幫助資訊
  • boot函數與start函數的關系:指令在啟動時取代 start 函數而執行 boot 函數,如果 boot 函數沒 有被重新定義,将執行 rc.common 中預定義的 boot 函數,boot 函數再次調用 start 函數
  • 詳情見下表:
函 數 含 義
start 啟動服務。相當于 C++語言中的虛函數,通常情況下每一個服務均需重寫該函數
stop 關閉服務。相當于 C++語言中的虛函數,通常情況下每一個服務均需重寫該函數
restart 重新開機服務。調用 stop 函數退出程序,然後再調用 start 函數啟動程序
reload 重新讀取配置,如果讀取配置失敗則調用 restart 函數重新開機程序
enable 打開服務自啟動,即将啟動腳本軟連結檔案放在/etc/rc.d 目錄下
disable 關閉服務自啟動,删除在/etc/rc.d 的軟連結檔案
enabled 提供服務自啟動的狀态查詢
boot 調用 start 函數
shutdown 調用 stop 函數
help 輸出幫助資訊

軟連結特性

  • ①當我們使用enable設定一個軟體為開機自啟動時,将自動在/etc/rc.d/目錄下建立一個軟連結指向/etc/init.d/目錄下的軟體
  • ②當我們使用disable關閉一個軟體開機自啟動時,軟體在/etc/rc.d/目錄下的軟連結将删除