bootloader 階段
- 硬體初始化及測試
- 載入 kernel image:Downloading Kernel Image and Initial Ram Disk: 從 flash 或網路載入到記憶體, 需要時作解壓縮。
- 設定 Linux kernel 需要的開機參數。
- 跳到 Kernel Entry Point,控制權轉移到 Linux kernel。
kernel 階段
一般 Linux 電腦開機在 kernel 階段最後會去執行 /sbin/init,而 OpenWrt 是去執行 /etc/preinit,進入 preinit 階段。preinit 階段
/etc/preinit 是 shell script,會載入 /lib/preinit 下更多的 shell script 依序執行,最後掛載根目錄後會去執行 busybox 提供的 /sbin/init,進入 init 階段。init 階段
/sbin/init 執行哪些程式,由 /etc/inittab 決定。/etc/inittab 有四的欄位,格式是 tty:runlevel;action:command,其中 tty 是 optional,runlevel 沒用到,action 決定執行順序及時機,command 是執行的指令。init 依據 action,依序執行 sysinit → wait → once 的指令,然後進入無窮迴圈執行不斷重新執行 respawn 跟 askfirst 的指令。askfirst 跟 respawn 的差別只是多了等候連接的 tty 按 Enter。但在 NOMMU 處理器無法等候,所以兩者是一樣的。除了上述所提 action 外,還有其它 action:ctrlaltdel (SIGINT 時執行)、shutdown (SIGUSR1, SIGTERM, SIGUSR2 時執行) 跟 restart (SIGQUIT 時執行)。ctrlaltdel 通常設成執行重開機,restart 會重開機,而 shutdown 可能重開機或者關閉電源。OpenWrt 的 inittab 依處理器或板子不同而有所不同,基本上大概的樣子是
::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
ttyS0::askfirst:/bin/ash --login
tty1::askfirst:/bin/ash --login
::shutdown:/etc/init.d/rcS K shutdown
ttyS0::askfirst:/bin/ash --login
tty1::askfirst:/bin/ash --login
所以開機時執行 /etc/init.d/rcS S boot,也就是依序執行 /etc/rc.d/ 下,所有 S 開頭的程式裡的 boot() 功能。/etc/rc.d/ 下的程式是連結到 /etc/init.d/ 下的命令檔,這些命令檔大多會帶入 /etc/rc.common,提供預設的動作函數,boot() 預設是執行 start()。也會帶入 /lib/functions.sh (一些共同的函數,包括 config_ 開頭的函數)、/lib/config/uci.sh (uci_ 開頭存取 uci 的函數)、及 /lib/functions/service.sh (使用 busybox start-stop-daemon 提供 service_ 開頭的函數)。
第一個執行的 rc.d 程式通常是 boot,再來可能是 sysctl、ubus、firewall、network
設定
OpenWrt 的設定用 UCI,並提供標準的命令檔函數以便於存取,放在 /etc/functions.sh (也就是 /lib/functions.sh)。. /etc/functions.sh #載入
config_load config_file # 載入設定檔
如果要特別的回呼,要在 config_load 之前設好 config_cb() 或 option_cb()。config_cb() 每遇到一個新 section 或設定檔載入完畢時呼叫,有兩個參數 -- section type 跟 section name。option_cb() 每個 option 或 list 時呼叫,一樣有兩個參數 -- option name 跟 option value。config_cb() 裡可以修改 option_cb(),讓每個 section 可以有不同的 option_cb()。變數 CONFIG_SECTION 紀錄目前 section 的 ID。
以下對記憶體處理:
- config_foreach function-called [section-name [function-args ...]]
- 補充 function-called 的參數
- config_get variable-stored section-id option-name [default-value]
- config_set section-id option-name value
- config_list_foreach section-id list-name function-called [function-args...]
- 補充 function-called 的參數
- config_get_bool:跟 config_get 一樣,多了把 on, true, enabled 取得為 1
Wi-Fi 啟用
Wi-Fi 預設的設定檔是 /etc/config/wireless。/sbin/wifi 啟用 Wi-Fi,有 detect、up、跟 down 三種動作。在開機 init 階段的 boot 時執行 /sbin/wifi detect,產生設定檔;network 時的 start() 最後執行 /sbin/wifi down 跟 /sbin/wifi up 動作來啟用 Wi-Fi。/sbin/wifi 整理:
- 三種動作
- detect:偵測 Wi-Fi,產生 /etc/config/wireless
- down:停用 Wi-Fi
- up (沒指定或其它):啟用 Wi-Fi
- 載入共用函數 /lib/functions.sh。
- 載入 /lib/wifi/ 下所有的 .sh:每個 .sh 檔是跟 Wi-Fi 驅動程式搭配,會附加 driver 名稱到 DRIVERS 變數,讓 /sbin/wifi 知道有什麼 driver,並提供 detect_driver()、scan_driver()、disable_driver()、enable_driver() 函數,為完成上述三種動作所需要。
- 執行 scan_wifi 來載入設定檔。設定檔有一些 type 為 wifi-device 跟 wifi-iface 的 section,一個 wifi-device 可以有多個 wifi-iface。載入過程中,會將 wifi-device 的 section-name 附加到 DEVICES 變數,並把其對應的 wifi-iface 的 section-name 設到 wifi-device 的 vifs 選項,以便後續利用
- 最後依動作執行對應的函數。
- 提供的函數
- find_net_config()
- bridge_interface()
- prepare_key_wep()
- wifi_fix_hwmode()
- wifi_updown:動作 up 或 down 時執行
- down → wifi_updown disable→對每個 DEVICES 的 type,也就是 driver 名稱,執行 scan_driver() 跟 disable_driver()
- up (沒指定或其它)→wifi_updown enable→會先執行 wifi_updown disable,並重新 scan_wifi。如果設定不是 disabled,執行 scan_driver() 跟 enable_driver()
- wifi_detect:動作 detect 執行的函數, 對每個 DRIVERS 執行 detect_driver(),產生設定檔。最終設定檔會存到 /etc/config/wireless
- start_net ifname network vifmac:啟用界面,將網路界面 ifname 連到 network 網域。vifmac 作用待研究。
- set_wifi_up()
- set_wifi_down
- scan_wifi
- 執行 scan_wifi 來載入預設的 Wi-Fi 設定檔
- 附加 driver 名稱到 DRIVERS 變數,讓 /sbin/wifi 知道有什麼 driver
- 提供的函數
- detect_driver():只有 detect 動作用到,偵測 Wi-Fi 界面,輸出設定檔
- scan_driver():up 跟 down 動作都會用到,掃描 wifi-iface 的 mode,設定 ifname。wifi-device 設 phy 及重設 vifs
- enable_driver():
- disable_driver():
config wifi-device radio0 # section name 給 wifi-iface 的 device 選項對應用
option type driver # driver 名稱,對應函數 detect_driver(), scan_driver(), enable_driver(), disable_driver()
option channel 11
option disabled 1 # 非必要,是否 disabled
config wifi-iface
option device radio0 # 對應到 wifi-device
option mode ap # 運作模式
option network lan # 搭到哪個網域使用
option ssid SSID
option encryption none
完整的 wireless 設定參考 http://wiki.openwrt.org/doc/uci/wireless
沒有留言:
張貼留言