1.內(nèi)核引導(dǎo)
操作系統(tǒng)接管硬件之后街氢,首先讀入/boot目錄下的內(nèi)核文件土辩,本人使用ubuntu 15.10
:
2.啟動初始化進(jìn)程
沒有這個進(jìn)程,系統(tǒng)中任何進(jìn)程都不會啟動,從進(jìn)程編號(pid)看出,init
是第一個運(yùn)行的程序:
ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 185192 5788 ? Ss 3月03 0:10 /sbin/init splash
//各欄位意義,參考鳥哥私房菜
USER:該 process 屬於哪個使用者帳號的甥桂?
PID :該 process 的程序識別碼涨椒。
%CPU:該 process 使用掉的 CPU 資源百分比;
%MEM:該 process 所占用的實(shí)體內(nèi)存百分比谴餐;
VSZ :該 process 使用掉的虛擬內(nèi)存量 (Kbytes)
RSS :該 process 占用的固定的內(nèi)存量 (Kbytes)
TTY :該 process 是在那個終端機(jī)上面運(yùn)行,若與終端機(jī)無關(guān)則顯示 ?呆抑,另外岂嗓, tty1-tty6是本機(jī)上面的登陸者程序,若為 pts/0 等等的理肺,則表示為由網(wǎng)絡(luò)連接進(jìn)主機(jī)的程序摄闸。
STAT:該程序目前的狀態(tài)善镰,狀態(tài)顯示與 ps -l 的 S 旗標(biāo)相同 (R/S/T/Z)
START:該 process 被觸發(fā)啟動的時間妹萨;
TIME :該 process 實(shí)際使用 CPU 運(yùn)行的時間。
COMMAND:該程序的實(shí)際命令為何炫欺?
所以第一個運(yùn)行的程序是/sbin/init
乎完。
3.運(yùn)行級別
Linux中許多程序需要開機(jī)啟動,稱之為daemon(守護(hù)進(jìn)程)
品洛,init
的進(jìn)程的一大任務(wù)就是去運(yùn)行這些開機(jī)啟動的程序树姨;那么linux怎么確定啟動哪些程序呢摩桶?這就涉及到運(yùn)行級別(runlevel)
,不同的運(yùn)行級別啟動不同的程序帽揪。
Linux系統(tǒng)有7個運(yùn)行級別:
0:系統(tǒng)停機(jī)狀態(tài)硝清,系統(tǒng)默認(rèn)運(yùn)行級別不能設(shè)為0,否則不能正常啟動
1:單用戶工作狀態(tài)转晰,root權(quán)限芦拿,用于系統(tǒng)維護(hù),禁止遠(yuǎn)程登陸
2:多用戶狀態(tài)(沒有NFS)
3:完全的多用戶狀態(tài)(有NFS)查邢,登陸后進(jìn)入控制臺命令行模式
4:系統(tǒng)未使用蔗崎,保留
5:X11控制臺,登陸后進(jìn)入圖形GUI模式
6:系統(tǒng)正常關(guān)閉并重啟扰藕,默認(rèn)運(yùn)行級別不能設(shè)為6缓苛,否則不能正常啟動
啟動了init
進(jìn)程之后,其首先會讀取/etc/inittab
文件來進(jìn)行初始化工作邓深,就是查看運(yùn)行級別未桥,然后確定要啟動的程序。
但這里要注意一個問題庐完,現(xiàn)在的linux發(fā)行版本钢属,主要有以下初始化方式,分別是sysvinit (System V initialization)
门躯、ubuntu的Upstart
以及systemd
淆党,所以在ubuntu
環(huán)境下,改用/etc/init/rc-sysinit.conf
讶凉,以前的版本有可能是在/etc/event.d
中染乌。
所以在初始化的時候會讀取rc-sysinit.conf
并執(zhí)行相關(guān)配置和腳本,其主要作用是設(shè)置系統(tǒng)默認(rèn)runlevel(運(yùn)行級別)
。
下面是rc-sysinit.conf的代碼:
# rc-sysinit - System V initialisation compatibility
#
# This task runs the old System V-style system initialisation scripts,
# and enters the default runlevel when finished.
description "System V initialisation compatibility"
author "Scott James Remnant <scott@netsplit.com>"
start on (filesystem and static-network-up) or failsafe-boot
stop on runlevel
# Default runlevel, this may be overriden on the kernel command-line
# or by faking an old /etc/inittab entry
env DEFAULT_RUNLEVEL=2 #默認(rèn)運(yùn)行級別為2
emits runlevel
# There can be no previous runlevel here, but there might be old
# information in /var/run/utmp that we pick up, and we don't want
# that.
#
# These override that
env RUNLEVEL=
env PREVLEVEL=
console output
env INIT_VERBOSE
task
script
# Check for default runlevel in /etc/inittab
if [ -r /etc/inittab ]
then
eval "$(sed -nre 's/^[^#][^:]*:([0-6sS]):initdefault:.*/DEFAULT_RUNLEVEL="\1";/p' /etc/inittab || true)"
fi
# Check kernel command-line for typical arguments
for ARG in $(cat /proc/cmdline)
do
case "${ARG}" in
-b|emergency)
# Emergency shell
[ -n "${FROM_SINGLE_USER_MODE}" ] || sulogin
;;
[0123456sS])
# Override runlevel
DEFAULT_RUNLEVEL="${ARG}"
;;
-s|single)
# Single user mode
[ -n "${FROM_SINGLE_USER_MODE}" ] || DEFAULT_RUNLEVEL=S
;;
esac
done
# Run the system initialisation scripts
[ -n "${FROM_SINGLE_USER_MODE}" ] || /etc/init.d/rcS
# Switch into the default runlevel
telinit "${DEFAULT_RUNLEVEL}" #調(diào)用telinit進(jìn)入設(shè)置的runlevel
end script```
通過代碼可以看出其會檢測是否存在/etc/inittab草戈,說明該系統(tǒng)下也支持`sysvinit (System V initialization)`初始化方式旗国,然后其設(shè)定的默認(rèn)運(yùn)行級別是2。
終端輸入命令`runlevel`會返回當(dāng)前運(yùn)行級別勒庄,本機(jī)返回`N 2`;再看倒數(shù)第二行瘫里,`telinit "${DEFAULT_RUNLEVEL}" `調(diào)用了telinit進(jìn)入了設(shè)定的runlevel实蔽。
再來看看當(dāng)前目錄下的rc.conf文件:
``` shell
# rc - System V runlevel compatibility
#
# This task runs the old System V-style rc script when changing between
# runlevels.
description "System V runlevel compatibility"
author "Scott James Remnant <scott@netsplit.com>"
emits deconfiguring-networking
emits unmounted-remote-filesystems
start on runlevel [0123456]
stop on runlevel [!$RUNLEVEL]#這里$RUNLEVEL=2,表示非2就不啟動
export RUNLEVEL
export PREVLEVEL
console output
env INIT_VERBOSE
task
script
if [ "$RUNLEVEL" = "0" -o "$RUNLEVEL" = "1" -o "$RUNLEVEL" = "6" ]; then
status plymouth-shutdown 2>/dev/null >/dev/null && start wait-for-state WAITER=rc WAIT_FOR=plymouth-shutdown || :
fi
/etc/init.d/rc $RUNLEVEL
end script
由代碼/etc/init.d/rc $RUNLEVEL
可看出/etc/init.d/rc
接受參數(shù)$RUNLEVEL
來調(diào)用/etc/rc${runlevel}.d/
下的腳本谨读,這里以/etc/rc2.d
為例局装,列出該目錄下的文件:
ls -l /etc/rc2.d
總用量 4
-rw-r--r-- 1 root root 677 6月 15 2015 README
lrwxrwxrwx 1 root root 21 3月 23 21:03 S05loadcpufreq -> ../init.d/loadcpufreq
lrwxrwxrwx 1 root root 17 3月 23 21:03 S16openvpn -> ../init.d/openvpn
lrwxrwxrwx 1 root root 22 3月 23 21:03 S19cpufrequtils -> ../init.d/cpufrequtils
lrwxrwxrwx 1 root root 17 3月 23 21:03 S20hddtemp -> ../init.d/hddtemp
lrwxrwxrwx 1 root root 20 3月 23 21:03 S20kerneloops -> ../init.d/kerneloops
lrwxrwxrwx 1 root root 20 3月 23 21:03 S20mintsystem -> ../init.d/mintsystem
lrwxrwxrwx 1 root root 15 3月 23 21:03 S20rsync -> ../init.d/rsync
lrwxrwxrwx 1 root root 27 3月 23 21:03 S20speech-dispatcher -> ../init.d/speech-dispatcher
lrwxrwxrwx 1 root root 32 3月 23 21:03 S20virtualbox-guest-utils -> ../init.d/virtualbox-guest-utils
lrwxrwxrwx 1 root root 15 3月 23 21:03 S50saned -> ../init.d/saned
lrwxrwxrwx 1 root root 19 3月 23 21:03 S70dns-clean -> ../init.d/dns-clean
lrwxrwxrwx 1 root root 18 3月 23 21:03 S70pppd-dns -> ../init.d/pppd-dns
lrwxrwxrwx 1 root root 17 3月 25 22:51 S91apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 21 3月 23 21:03 S99grub-common -> ../init.d/grub-common
lrwxrwxrwx 1 root root 18 3月 23 21:03 S99ondemand -> ../init.d/ondemand
lrwxrwxrwx 1 root root 19 3月 24 00:03 S99prltoolsd -> ../init.d/prltoolsd
lrwxrwxrwx 1 root root 18 3月 23 21:03 S99rc.local -> ../init.d/rc.local
該目錄下的文件名的命名形式都是字母S+兩位數(shù)字+程序名
,S表示start,如果是K铐尚,就表示kill拨脉,兩位數(shù)字表示處理順序,越小越早處理宣增,如果數(shù)字相同玫膀,就按照字母順序進(jìn)行啟動。
從中還可以看出這些文件的真正目錄都在/etc/init.d
目錄下爹脾,這是為了防止在不同的運(yùn)行級別下啟動相同的程序匆骗,這樣設(shè)置為鏈接提供了很大的方便。
后面執(zhí)行l(wèi)ogin程序進(jìn)行登錄誉简。
暫時over碉就,以后對代碼進(jìn)行更加詳細(xì)的說明。