danny 2006-11-19 18:42
FreeBSD 的開機流程
FreeBSD 預設使用三個階段的開機流程,基本上需要用到三個程式 (兩個 boot blocks, 和 loader)。 每一個程式都需要靠著上一個程式的配合才能完成整個開機程序。
接著 kernel 載入,開始偵測硬體裝置和初始化。一但整個 kernel 載入完成之後, kernel 會藉著呼叫 init(8) 來把系統的控制權交給使用者, init(8) 會先確定磁碟不是在使用中的狀態,接著開始使用者層的資源配置, 並掛載所要使用的分割區,設定網路卡,再開始啟動 FreeBSD 所需的起始程序。
開機磁區:開機步驟的一和二
開機 指的是電腦開始偵測硬體裝置並初始化, 好讓程式開始執行。
這牽涉到了一個特殊的唯讀晶片,這個晶片將決定進一步的開機程序, 通常是送訊號至其他晶片作訊號的調節,及記憶體測試,設定硬體週置, 並提供一個機制去設定各種的硬體詳細組態。
在標準的個人電腦上,這通常是 BIOS (掌管整個開機流程),和 CMOS (儲存各項設定) ,BIOS 和 CMOS 必須要偵測到磁碟機, 並要知道可以載入作業系統的程式是放在磁碟機的哪個位置。
這個章節不會解釋第一階段的開機流程,而將重點放在這個磁碟機上的系統載入程式。
開機磁區負責找到 boot loader (通常是這樣),並執行它, 這必須要了解要如何在檔案系統中找到它, 要怎麼執行,和要如何做一些適當的設定讓這程式正常執行。
boot0
這通常是最前面的一個開機磁區,稱為 boot0,儲存在 Master Boot Record, 這個區域也就是 BIOS 所要去搜尋和執行的, 這裡所需要儲存的資訊為一個可以開機的區域列表。
boot0 所佔的容量很小,因為放在 MBR 的程式無法超過 512 bytes.
顯示如下表:
Example boot0 的顯示畫面
F1 DOS
F2 FreeBSD
F3 Linux
F4 ??
F5 Drive 1
Default: F2
boot1
boot1 位於開機磁區上的開機磁軌裡,這裡就是 boot0 或是任何其他存放於 MBR 的程式所要尋找以繼續完成開機程序的地方。
boot1 也是很小,因為容量無法超過 512 bytes,不過這對 FreeBSD disklabel 的而言已經足夠。 disklabel 是用來儲存 slice 的相關訊息, 並去找到和執行 boot2。
boot2
boot2 比較高階,boot2 必須要在 FreeBSD 的檔案系統上找到檔案, 並提供一個介面去選擇 kernel 或 loader 來執行。
因為 loader 比 boot2 又更加高級,而且易於設定,所以 boot2 通常會執行它, 不過之前 boot2 設定是直接執行 kernel。
Example boot2 的畫面
>> FreeBSD/i386 BOOT
Default: 0:wd(0,a)/kernel
boot:
開機步驟之三
loader 是三個步驟的最後一個,loader 必須放在檔案系統裡, 通常是在 /boot/loader。
Note: 雖然 /boot/boot0、 /boot/boot1、和 /boot/boot2 的確存在,但是他們並不是在 MBR、開機磁軌和 disklabel 中的正本。
Loader 提供了一個容易的設定方法,並使用簡易的內建命令, loader 的背後是由一個強大的命令解譯程式 (使用較複雜的命令集) 組成的。
Loader 的執行流程
在初始化的過程中,loader 會偵測終端機和磁碟機, 並開始設置所要開啟的磁碟,設定變數對應, 接著命令解譯程式啟動,開始解譯 loader 所傳遞的命令。
loader will then read /boot/loader.rc, which by default reads in /boot/defaults/loader.conf which sets reasonable defaults for variables and reads /boot/loader.conf for local changes to those variables. loader.rc then acts on these variables, loading whichever modules and kernel are selected.
最後,loader 預設花 10 秒等待任何按鍵的輸入,如果沒有, 就開始載入 kernel。如果有, 就啟動一個提示符號讓使用者輸入那些易懂的命令,藉此可以調整變數, 載入/卸載 module,最後決定要開機還是重開機。
較深入的技術探討可以在 loader(8) 找到。
Loader 的內建命令
這些命令集包括了:
autoboot seconds
如果在所給的秒數之間沒被按鍵中斷的話就接著載入 kernel, 這將會由所給的秒數開始倒數,預設的秒數為 10 秒。
boot [-options] [kernelname]
直接配合所給的參數載入核心。
boot-conf
在要開機時,使用自動的變數配置模組, 這只在你先用 unload 時才有意義,並改變一些變數, 通常是 kernel。
help [topic]
顯示來自 /boot/loader.help 的求助訊息, 如果所給的主題 (topic) 是 index, 那就顯示所有的主題列表。
include filename ...
執行所給的檔案,這檔案將被讀入並一行一行地被執行, 一但有錯誤發生就直接停止這個 inlucde 命令。
load [-t type] filename
載入 kernel,kernel 模組或所先指定檔案類型,再接著檔名, 任何接在檔案之後的參數都將會傳給此檔來執行。
ls [-l] [path]
列出在路徑中的檔案,如果沒有指定路徑將顯示根目錄的檔案列表 如果有附加 -l 參數,那麼將一起顯示檔案容量。
lsdev [-v]
列出所有可以載入 module 的裝置,如果有指定 -v 參數, 那麼更詳細的資訊會一起列出。
lsmod [-v]
顯示已被載入的 module,如果有指定 -v 參數,那麼更詳細的資訊會一起列出。
more filename
顯示所指定的檔案內容,並在每 LINES (環境變數) 暫停。
reboot
直接重開機。
set variable, set variable=value
設定 loader 的環境變數。
unload
卸載所有被載入的 module。
Loader 的使用範例
底下是一些實際的 loader 使用範例。
單純的載入 kernel,不過將進入單人模式:
boot -s
卸載通常要載入的 kernel 和 module,接著載入另一個 kernel:
unload
load kernel.old
你可以使用 kernel.GENERIC, 這是安裝光碟上的通用 kernel,或是 kernel.old, 這是你上一個安裝的 kernel (如果你有升級或重新配置你自己的 kernel 的話)。
Note: 照著下列的步驟可以配合原先的 module 來載入其他的 kernel:
unload
set kernel="kernel.old"
boot-conf
載入核心配置的 script 檔 (這是一個自動的 script 檔案, 用來執行你在 kernel 開機階段所要執行的命令):
load -t userconfig_script
/boot/kernel.conf
開機階段的 kernel 調節
一但 kernel 經由 loader (一般而言) 或 boot2 (略過執行 loader),kernel 將會檢查它的開機旗標,如果有, 就開始依照旗標做一些必要的調節。
Kernel 的開機旗標
底下是最常用的開機旗標:
-a
在 kernel 初始化階段,訊問要使用哪一個裝置當 root 檔案系統。
-C
從光碟機開機。
-c
執行 UserConfig,開機階段的 kernel 配置檔。
-s
進入單人模式。
-v
在 kernel 啟動時顯示較多的訊息。
Note: 要知道更多的開機旗標請參閱 boot(8)。
Init:進行系統控制權轉移
一但 kernel 完成載入後,kernel 就將控制權交給使用者層的命令 init,通常放置在 /sbin/init, 或是 loader 的環境變數 init_path 所指定的位置。
自動 reboot 啟動程序
這個程序將會確定系統將要使用的檔案系統是存在的,如果不存在, 那麼 fsck 就不能正常的被執行去修復磁碟機, 接著 init 將把系統切換成 單人模式, 系統管理者就可以在這時候直接處理這錯誤。
單人模式
要進入這個模式可以經由 自動 reboot 啟動程序 ,或是在開機階段設置 -s 參數,或者設定 boot_single 的變數給 loader。
或在 多人模式 之下,執行 shutdown, 不加 reboot (-r) 或 halt (-h) 參數,也可以進入 單人模式。
如果系統主控台 console 在 /etc/ttys 之中是設定成 insecure 的, 那麼在進入 單人模式 時,系統就會要求輸入 root 的密碼。
Example 在 /etc/ttys 中設定一個 console 為 insecure
# name getty type status comments
#
# This entry needed for asking password when init goes to single-user mode
# If you want to be asked for password, change "secure" to "insecure" here
console none unknown off insecure
Note: 一個 insecure 的 console 代表你認定你的 console 的安全等級是 insecure 的, 並且想確定有人想進入單人模式時都要輸入 root 的密碼才行,請注意,insecure 不代表你的 console 是 inscure 的, 而是,如果你要多一點的安全防護,請選擇 insecure,而不是 secure。
多人模式
如果 init 無誤地找到了你的檔案系統, 或結束了 單人模式, 系統就會進入多人模式,並開始系統的資源配置。
系統資源配置 (rc)
開始系統資源配置時,系統將先執行預設的配置檔 /etc/defaults/rc.conf, 和系統的詳細配置 /etc/rc.conf,接著依照 /etc/fstab 來掛載檔案系統, 再啟動網路服務,和其他的系統監控程式 (daemon),最後,執行部份程式的起始 script 檔。
rc(8) 是個參考資源設定系統的好地方,同理,直接查閱 那些 scripts 也是個好方法。
關機程序
藉由 shutdown 可以控制系統進行關機, init 將會執行 /etc/rc.shutdown 這個 script 檔,接著送出終止 (terminate) 信號給所有的程序, 在此時如果有無法終止的程序,那麼就送出 kill 的信號。