Openwrt啟動流程及啟動指令碼分析

2021-07-23 08:21:39 字數 4497 閱讀 8795

在linux的發展過程中,

linux

的啟動程式也在發展,從

sysv init

到現在的

upstart

、systemd,

通常該程式是程序號為

1的程序,該程式在

linux

系統有著舉足輕重的地方。在

openwrt

中,使

用了另外一種啟動程式叫做

procd

,本文的重點並不在於介紹

procd

,本文主要介紹並解析

procd

、preinit

及各種指令碼如何完成整個系統的初始化。

linux發行版:

ubuntu14.04 lts

openwrt版本:

barrier break 14.07 r42635 

(linux kernel 3.10.49)

硬體:mpr-a2

模組(rt5350)

在檢視linux

核心**及根檔案系統下的指令碼之前,需要對

openwrt

進行配置,執行

make menuconfig,在

target system

中選擇ralink rt288x/rt3***

,subtarget

中選擇rt3x5x/rt5350 

based boards

,target profile

選擇hame mpr-a2

,然後make

完成openwrt

的編譯。打完

patch

的核心

**在build_dir/target-mipsel_24kec+dsp_uclibc-0.9.33.2/linux-ramips_rt305x/

目錄下,根檔案系統目 錄在

build_dir/target-mipsel_24kec+dsp_uclibc-0.9.33.2/root-ramips/。

linux的啟動入口為

start_kernel()

(init/main.c

),該函式的最後會呼叫

rest_init()

(init/main.c),

該函式建立兩個核心執行緒

init

和kthreadd

之後,進入死迴圈,即所謂的

0號程序。init執行緒執行

kenrel_init()

(init/main.c

)函式,在

kernel_init

函式中,首先會檢查核心的啟動引數中是否有設定

init

引數,如果有,則會使用該引數指定的程式作為

init

程式,否則會按照如下**(打上

patch

後的)

中所示的順序依次嘗試啟動,如果都無法啟動就會導致

kernel panic。

if (!run_init_process("/etc/preinit") ||

!run_init_process("/sbin/init") ||

!run_init_process("/etc/init") ||

!run_init_process("/bin/init") ||

!run_init_process("/bin/sh"))

return 0;

在目前的環境下,核心啟動引數未設定init

引數,所以會以

/etc/preinit

程式作為

init

程式,preinit

實際為shell

指令碼。        /etc/preinit

/lib/functions.sh

/lib/functions/preinit.sh

/lib/functions/system.sh

/lib/preinit/下所有指令碼

在proc

程式包中,編譯完會生成兩個可執行程式:

init

和procd

,均在目 錄

/sbin

下,這兩個程式均會使用到。

這個初始化過程遵循如下主線:

下面我們一步一步分析這個過程。

在/etc/preinit指令碼中,第一條命令如下:

[ -z "$preinit" ] && exec /sbin/init

在從核心執行這個指令碼時,preinit

這個變數時沒有定義的,所以會直接執行

/sbin/init

。/sbin/init

程式主要做

了一些初始化工作,如環境變數設定、檔案系統掛載、核心模組載入等,之後會建立兩個程序,分別執行

/etc/preinit 和

/sbin/procd

,執行/etc/preinit

之前會設定變數

preinit

,/sbin/procd

會帶-h

的引數,當

procd

退出後會呼叫

exec執行

/sbin/proc

替換當前

init

程序(具體過程可參見

procd

程式包中的

init

和procd

程式)。這就是系統啟動完成後,

ps命令顯示

的程序號為

1的程序名最終為

/sbin/procd

的由來,中間是有幾次變化的。

繼續看/etc/preinit

指令碼,出來變數設定外,接下來是執行了三個

shell

指令碼:

. /lib/functions.sh

. /lib/functions/preinit.sh

. /lib/functions/system.sh

注意「.

」和「/

」之間是有空格的,這裡的點相當與

souce

命令,但

souce

是bash

特有的,並不在

posix

標準中,「.」

是通用的用法。使用「

.」的意思是在當前

shell

環境下執行,並不會在子

shell

中執行。這幾個

shell

指令碼主要定義了

shell

函式,

特別是preinit.sh

中,定義了

hook

相關操作的函式。

之後會使用boot_hook_init

定義五個

hook

結點如下:

boot_hook_init preinit_essential

boot_hook_init preinit_main

boot_hook_init failsafe

boot_hook_init initramfs

boot_hook_init preinit_mount_root

之後會向這些結點中新增hook

函式。

在之後就是乙個迴圈,依次在當前shell

下執行/lib/preinit/

目錄下的指令碼,

for pi_source_file in /lib/preinit/*; do

. $pi_source_file

done

/lib/preinit/目錄下的指令碼具體類似的格式,定義要新增到

hook

結點的函式,然後通過

boot_hook_add

將該函式新增到

對應的hook

結點。

最後,/etc/preinit

就會執行

boot_run_hook

函式執行對應

hook

結點上的函式。在當前環境下只執行了

preinit_essential和

preinit_main

結點上的函式,如下:

boot_run_hook preinit_essential

boot_run_hook preinit_main

到此,/etc/preinit

執行完畢並退出。如果需要跟蹤除錯這些指令碼,可以 在

/etc/preinit

的最開始新增一條命令

set -x,這

樣就會列印出執行命令的過程, 當並不會真正執行。

至於系統服務程式的啟動及初始化將全由procd

完成,procd

的功能不僅在於此,它還整合更多其他功能,具體可參見

procd

的資料。

1.openwrt啟動指令碼分析,

2.openwrt barrier break 14.07原始碼

**:

openwrt啟動流程

openwrt是通過一系列shell指令碼進行啟動流程的組織,下面是啟動流程的提綱。如 果想詳細了解啟動的過程,則需要仔細走讀指令碼檔案。1.在make menuconfig 選擇target平台 broadcom bcm947xx 953xx 2.4 2.linux核心的配置檔案由下面兩個檔案組成...

openwrt啟動流程

了解openwrt系統的啟動流程 1.1 系統介紹 任何系統的啟動都是開發人員首要關注的問題,因為只有了解了系統的啟動流程和啟動機制,才能真正掌握乙個系統,如果對系統的啟動不熟悉的話,是不可能用好乙個系統的。openwrt系統也不例外,他的啟動和一般的嵌入式系統的啟動還有所區別,下面記錄一下open...

OpenWrt啟動指令碼規則

在做專案過程中,時常新增一些啟動指令碼,但是對整個指令碼的啟動流程和規則缺乏理解,所以整理加深一下。etc init.d etc rc.d bin sh 指令碼直譯器 etc rc.common 指令碼執行前的檢查指令碼,可以檢測出非法的引數 start 40 在etc rc.d 生成s40 在啟動...