在前面的文章裡,我們學習了怎麼顯示和管理運行中的進程。今天,我想描述一下那些進程實際上如何啟動的。
當你啟動計算機進入FreeBSD時會有很多巧妙的事情發生。在此我無法論及所有的細節,但FreeBSD handbook極好地解釋了引導過程。當你啟動你的計算機時,可能會注意到內核對硬件作了檢測並在終端上顯示了相應的結果。當檢測結束時,內核會啟動兩個進程:進程 0 (swapper)和進程 1 (init)。
負責進程控制初始化的程序是init;沒有它,其它的進程無法啟動。在引導時,init要做兩項重要的工作:首先,它在rc的控制之下裝入啟動腳本,然後它初始化終端以便使用戶可以登錄。讓我們分別描述這些功能,從rc開始:
whatis rc
rc(8) - command scripts for auto-reboot and daemon startup
這些腳本實際位於/etc/rc;通常,位於/etc下的這個配置文件對應於手冊的第五部分,所以你可以根據手冊對配置文件作正確地修改。但是,如果你打:
man 5 rc
你卻會得到以下信息:
No entry for rc in section 5 of the manual
這對於上面提到的它位於手冊第八部分來說看起來有點古怪,因為這部分手冊包含的是系統維護和操作命令,通常它們都是後台進程。讓我們進一步來看一下這個文件:
more /etc/rc
# System startup script run by init on autoboot
# or after single-user.
# Output and error are redirected to console by init,
# and the console is the controlling terminal.
# Note that almost all of the user-configurable behavior
# is no longer in # this file, but rather in /etc/defaults/rc.conf.
# Please check that file first before contemplating any changes
# here. If you do need to change this file for some reason, we
# would like to know about it.
好,相當清晰;看來對於該文件我們自己是不能亂來的。這裡有些相當重要的東西對於正確引導我們的系統所必須的。讓我們往後跳,看一些重要的部分來找出啟動時實際上都發生了些什麼。注意當在引導過程中處理rc腳本時,init會把所有的輸出和錯誤信息記錄到終端上。
rc首先做的事之一就是設置路徑變量,以使它可以找到你FreeBSD系統上的可執行程序:
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin
然後它會查找/etc/defaults/rc.conf and和/etc/rc.conf這兩個文件:
# If there is a global system configuration file, sUCk it in.
if [ -f /etc/defaults/rc.conf ]; then
. /etc/defaults/rc.conf
elif [ -f /etc/rc.conf ]; then
. /etc/rc.conf
fi
接著它會作一個文件系統連貫性檢查。如果你曾經非正常關閉FreeBSD系統,你會在引導過程中看到它在這一步上發出抱怨的。
echo Automatic boot in progress...
fsck -p
假定fsck沒有遇到任何問題,它就馬上裝載你的文件系統:
# Mount everything except nfs filesystems.
mount -a -t nonfs
在其它任何進程啟動之前,你的CMOS時鐘必須調整為內核時鐘可以理解的形式:
adjkerntz -i
然後整理var目錄,將引導信息寫入dmesg.boot:
clean_var() {
if [ ! -f /var/run/clean_var ]; then
rm -rf /var/run/*
find /var/spool/lock ! -type d -delete
rm -rf /var/spool/uucp/.Temp/*
# Keep a copy of the boot messages around
dmesg >/var/run/dmesg.boot
接著rc會讀取以下文件:
/etc/rc.sysctl
/etc/rc.serial
/etc/rc.pccard
/etc/rc.network
/etc/rc.network6
然後復位終端權限:
# Whack the pty perms back into shape.
chflags 0 /dev/tty[pqrsPQRS]*
chmod 666 /dev/tty[pqrsPQRS]*
chown root:wheel /dev/tty[pqrsPQRS]*
並清理自己產生的“垃圾”以及/tmp目錄:
# Clean up left-over files
# Clearing /tmp at boot-time seems to have a long tradition. It doesn't
# help in any way for long-living systems, and it might accidentally
# clobber files you would rather like to have preserved after a crash
# (if not using mfs /tmp anyway).
# See also the example of another cleanup policy in /etc/periodic/daily.
# Remove X lock files, since they will prevent you from restarting X11
# after a system crash.
現在rc准備啟動一些後台進程,首先是syslogd和named:
# Start system logging and name service. Named needs to start before syslogd
# if you don't have a /etc/resolv.conf.
然後是inetd、cron、lpd、sendmail、sshd和usbd:
# Now start up miscellaneous daemons that don't belong anywhere else
接著rc將更新motd(每日信息)並執行“uname -m”,這條命令會在屏幕上顯示構架類型。
(/etc/rc文件結尾)
當到達/etc/rc的結尾時,rc的工作就完成了。在此我們重新回顧一下:init調用rc腳本,它會讀取一些全局的和本地的配置文件以正確裝載文件系統並建立系統後台進程可以啟動的環境。你的操作系統現在已經啟動並運行著,但到此為止,還沒有一個用戶可以與操作系統實際交互的環境。這就是init第二個重要的功能。
配置文件/etc/ttys將會被讀取以決定初始化的終端。不象/etc/rc,該文件可以由超級用戶經常編輯以確保讓init來初始化所需的終端。
為了理解此文件,我們必須了解在你的FreeBSD系統上有三種類型的終端。以“ttyv”開頭後跟一個數字的是虛擬終端;它們都是用戶可以獲得的物理存在於FreeBSD系統上的終端。缺省情況下,這些虛擬終端中的第一個,或叫“ttyv0”,表示控制台。以“ttyd”開頭後跟一個數字的是串行線路或撥號終端;它們是用戶用調制解調器遠程訪問你的FreeBSD系統時可獲得的終端。最後一種終端類型就是偽終端或網絡終端;它們以“ttyp”開頭後跟一個數字或字母,用於通過網絡連接訪問你的FreeBSD系統。
如果我們用以下命令看此文件:
more /etc/ttys
我們會看到此文件分為三部分,每個部分分別對應這三種類型的終端。同時每個部分還分為四欄,總結為下面的圖表:
欄名
含義
name
終端設備的名稱
getty
在終端上啟動運行的程序,通常為getty。其它項目包括xdm,它用來啟動X Window系統,或none,說明沒有程序。
type
對於虛擬終端,對應的類型為cons25。其它通常的值包括偽終端network,調制解調器入口dialup,以及unknown,用於用戶試圖以無法預定的類型進行連接的終端。
status
它必須是on或off。如果是on,init將運行getty欄指定的程序。如果出現單詞“secure”,說明該tty允許root登錄;為避免這種情況,可以用單詞“insecure”。
讓我們從虛擬終端部分開始解釋該文件;可以看到它是以設置控制台開始的:
# If console is marked "insecure", then init will ask
# for the root passWord when going to single-user mode.
console none unknown off secure
如果在引導過程中fsck命令運行出了問題,init將使你的FreeBSD系統進入單用戶模式以使root用戶可以修復問題。如果你用insecure代替secure來設置控制台,init將在你可以繼續干之前索取口令。
ttyv0 "/usr/libexec/getty Pc" cons25 on secure
# Virtual terminals
ttyv1 "/usr/libexec/getty Pc" cons25 on secure
ttyv2 "/usr/libexec/getty Pc" cons25 on secure
ttyv3 "/usr/libexec/getty Pc" cons25 on secure
ttyv4 "/usr/libexec/getty Pc" cons25 on secure
ttyv5 "/usr/libexec/getty Pc" cons25 on secure
ttyv6 "/usr/libexec/getty Pc" cons25 on secure
ttyv7 "/usr/libexec/getty Pc" cons25 on secure
ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off secure
你可以看到在我的FreeBSD系統上除了控制台以外還有八個虛擬終端;我可以通過按ALT鍵加一個控制鍵來訪問每個終端。例如ALT F1可訪問控制台,ALT F2訪問ttyv1, ALT F3訪問ttyv2,等等。如果我啟動了X會話,那麼它可以用ALT F8來訪問。如果我把ttyv8上的單詞off改為on,那麼我可以在引導時得到一個X終端而不是控制台。然後可以繼續用我ALT加功能鍵來訪問其它終端。我的所有這些虛擬終端都標為“secure”,說明它們都可接受root登錄。你可以有多少個虛擬終端是由你的FreeBSD版本所決定的;如果你希望建立更多虛擬終端,可以讀一下這個faq。
現在讓我們移到撥號終端:
# Serial terminals
# The 'dialup' keyword identifies dialin lines to login, fingerd etc.
ttyd0 "/usr/libexec/getty std.9600" dialup off secure
ttyd1 "/usr/libexec/getty std.9600" dialup off secure
ttyd2 "/usr/libexec/
ttyv4 "/usr/libexec/getty Pc" cons25 on secure
ttyv5 "/usr/libexec/getty Pc" cons25 on secure
ttyv6 "/usr/libexec/getty Pc" cons25 on secure
ttyv7 "/usr/libexec/getty Pc" cons25 on secure
ttyv8 "/usr/X11R6/bin/xdm -nodaemon" xterm off secure
你可以看到在我的FreeBSD系統上除了控制台以外還有八個虛擬終端;我可以通過按ALT鍵加一個控制鍵來訪問每個終端。例如ALT F1可訪問控制台,ALT F2訪問ttyv1, ALT F3訪問ttyv2,等等。如果我啟動了X會話,那麼它可以用ALT F8來訪問。如果我把ttyv8上的單詞off改為on,那麼我可以在引導時得到一個X終端而不是控制台。然後可以繼續用我ALT加功能鍵來訪問其它終端。我的所有這些虛擬終端都標為“secure”,說明它們都可接受root登錄。你可以有多少個虛擬終端是由你的FreeBSD版本所決定的;如果你希望建立更多虛擬終端,可以讀一下這個faq。
現在讓我們移到撥號終端:
# Serial terminals
# The 'dialup' keyword identifies dialin lines to login, fingerd etc.
ttyd0 "/usr/libexec/getty std.9600" dialup off secure
ttyd1 "/usr/libexec/getty std.9600" dialup off secure
ttyd2 "/usr/libexec/