羅列一篇,方便我等菜鳥來溫習(xí)和查閱,以Solaris為例
按下電源,首先是BIOS取得系統(tǒng)控制權(quán),BIOS進(jìn)行最初的引導(dǎo)工作,然后交控制權(quán)交給引導(dǎo)分區(qū),由引導(dǎo)分區(qū)加載內(nèi)核并調(diào)用start_kernel函數(shù)。
內(nèi)核首先引導(dǎo)核心數(shù)據(jù)結(jié)構(gòu)的初始化,在start_kernel函數(shù)中完成如下工作:
- 輸出Linux版本信息(printk(linux_banner))
- 設(shè)置與體系結(jié)構(gòu)相關(guān)的環(huán)境(setup_arch())
- 頁(yè)表結(jié)構(gòu)初始化(paging_init())
- 使用"arch/alpha/kernel/entry.S"中的入口點(diǎn)設(shè)置系統(tǒng)自陷入口(trap_init())
- 使用alpha_mv結(jié)構(gòu)和entry.S入口初始化系統(tǒng)IRQ(init_IRQ())
- 核心進(jìn)程調(diào)度器初始化(包括初始化幾個(gè)缺省的Bottom-half,sched_init())
- 時(shí)間、定時(shí)器初始化(包括讀取CMOS時(shí)鐘、估測(cè)主頻、初始化定時(shí)器中斷等,time_init())
- 提取并分析核心啟動(dòng)參數(shù)(從環(huán)境變量中讀取參數(shù),設(shè)置相應(yīng)標(biāo)志位等待處理,(parse_options())
- 控制臺(tái)初始化(為輸出信息而先于PCI初始化,console_init())
- 剖析器數(shù)據(jù)結(jié)構(gòu)初始化(prof_buffer和prof_len變量)
- 核心Cache初始化(描述Cache信息的Cache,kmem_cache_init())
- 延遲校準(zhǔn)(獲得時(shí)鐘jiffies與CPU主頻ticks的延遲,calibrate_delay())
- 內(nèi)存初始化(設(shè)置內(nèi)存上下界和頁(yè)表項(xiàng)初始值,mem_init())
- 創(chuàng)建和設(shè)置內(nèi)部及通用cache("slab_cache",kmem_cache_sizes_init())
- 創(chuàng)建uid taskcount SLAB cache("uid_cache",uidcache_init())
- 創(chuàng)建文件cache("files_cache",filescache_init())
- 創(chuàng)建目錄cache("dentry_cache",dcache_init())
- 創(chuàng)建與虛存相關(guān)的cache("vm_area_struct","mm_struct",vma_init())
- 塊設(shè)備讀寫緩沖區(qū)初始化(同時(shí)創(chuàng)建"buffer_head"cache用戶加速訪問,buffer_init())
- 創(chuàng)建頁(yè)cache(內(nèi)存頁(yè)hash表初始化,page_cache_init())
- 創(chuàng)建信號(hào)隊(duì)列cache("signal_queue",signals_init())
- 初始化內(nèi)存inode表(inode_init())
- 創(chuàng)建內(nèi)存文件描述符表("filp_cache",file_table_init())
- 檢查體系結(jié)構(gòu)漏洞(對(duì)于alpha,此函數(shù)為空,check_bugs())
- SMP機(jī)器其余CPU(除當(dāng)前引導(dǎo)CPU)初始化(對(duì)于沒有配置SMP的內(nèi)核,此函數(shù)為空,smp_init())
- 啟動(dòng)init過程(創(chuàng)建第一個(gè)核心線程,調(diào)用init()函數(shù),原執(zhí)行序列調(diào)用cpu_idle() 等待調(diào)度,init())
至此start_kernel()結(jié)束,基本的核心環(huán)境已經(jīng)建立起來了。
start_kernel最后一項(xiàng)是啟動(dòng)了init函數(shù),接著由它來完成外設(shè)的初始化
- 總線初始化(比如pci_init())
- 網(wǎng)絡(luò)初始化(初始化網(wǎng)絡(luò)數(shù)據(jù)結(jié)構(gòu),包括sk_init()、skb_init()和proto_init()三部分,在proto_init()中,將調(diào)用protocols結(jié)構(gòu)中包含的所有協(xié)議的初始化過程,sock_init())
- 創(chuàng)建bdflush核心線程(bdflush()過程常駐核心空間,由核心喚醒來清理被寫過的內(nèi)存緩沖區(qū),當(dāng)bdflush()由kernel_thread()啟動(dòng)后,它將自己命名為kflushd)
- 創(chuàng)建kupdate核心線程(kupdate()過程常駐核心空間,由核心按時(shí)調(diào)度執(zhí)行,將內(nèi)存緩沖區(qū)中的信息更新到磁盤中,更新的內(nèi)容包括超級(jí)塊和inode表)
- 設(shè)置并啟動(dòng)核心調(diào)頁(yè)線程kswapd(為了防止kswapd啟動(dòng)時(shí)將版本信息輸出到其他信息中間,核心線調(diào)用kswapd_setup()設(shè)置kswapd運(yùn)行所要求的環(huán)境,然后再創(chuàng)建 kswapd核心線程)
- 創(chuàng)建事件管理核心線程(start_context_thread()函數(shù)啟動(dòng)context_thread()過程,并重命名為keventd)
- 設(shè)備初始化(包括并口parport_init()、字符設(shè)備chr_dev_init()、塊設(shè)備 blk_dev_init()、SCSI設(shè)備scsi_dev_init()、網(wǎng)絡(luò)設(shè)備net_dev_init()、磁盤初始化及分區(qū)檢查等等,device_setup())
- 執(zhí)行文件格式設(shè)置(binfmt_setup())
- 啟動(dòng)任何使用__initcall標(biāo)識(shí)的函數(shù)(方便核心開發(fā)者添加啟動(dòng)函數(shù),do_initcalls())
- 文件系統(tǒng)初始化(filesystem_setup())
- 安裝root文件系統(tǒng)(mount_root())
這些步驟結(jié)束后,init()搜索文件系統(tǒng)中的init程序,并創(chuàng)建它,也就是我們通常所說的init進(jìn)程,它是系統(tǒng)所有進(jìn)程的起點(diǎn),進(jìn)程ID=1。
在啟動(dòng)了的Solaris下,利用 "$ps -p 1" 可以查看該進(jìn)程,輸出如下:
PID TTY TIME CMD
1 ? 0:01 init
接下來init進(jìn)程讀取/etc/inittab文件,來決定下一步如何做。
inittab是以行為單位的描述性(非執(zhí)行性)文本,每一個(gè)指令行都具有以下格式:
id:runlevel:action:process 其中id為入口標(biāo)識(shí)符,runlevel為運(yùn)行級(jí)別,action為動(dòng)作代號(hào),process為具體的執(zhí)行程序。
id一般要求4個(gè)字符以內(nèi),runlevel是init所處于的運(yùn)行級(jí)別的標(biāo)識(shí),一般使用0-6以及S或s(S或s表示單用戶模式)。
action字段則告訴init進(jìn)程,如何對(duì)待process字段指定的進(jìn)程:當(dāng)inittab中各行的runlevel值與當(dāng)前運(yùn)行級(jí)別匹配時(shí),指定的action才被執(zhí)行。
但有幾個(gè)特殊的action:
initdefault是一個(gè)特殊的action值,用于標(biāo)識(shí)缺省的啟動(dòng)級(jí)別;當(dāng)init由核心激活以后,它將首先讀取inittab中的initdefault項(xiàng),取得其中的runlevel,并作為當(dāng)前的運(yùn)行級(jí)別。
sysinit、boot、bootwait等action將在系統(tǒng)啟動(dòng)時(shí)無(wú)條件運(yùn)行,而忽略其中的runlevel,即不管當(dāng)前運(yùn)行級(jí)別是什么,它都執(zhí)行,并且是優(yōu)先執(zhí)行。其余的action(不含initdefault)都與某個(gè)runlevel相關(guān)。
我的Solaris9中的/etc/inittab如下
ap::sysinit:/sbin/autopush -f /etc/iu.ap #action=sysinit, 該行不管在什么運(yùn)行級(jí)別下,都運(yùn)行
ap::sysinit:/sbin/soconfig -f /etc/sock2path #同上
fs::sysinit:/sbin/rcS sysinit >/dev/msglog 2<>/dev/msglog
is:3:initdefault: #該行action=initdefault,表明系統(tǒng)的默認(rèn)運(yùn)行級(jí)別是3
p3:s1234:powerfail:/usr/sbin/shutdown -y -i5 -g0 >/dev/msglog 2<>/dev/msglog
sS:s:wait:/sbin/rcS >/dev/msglog 2<>/dev/msglog
s0:0:wait:/sbin/rc0 >/dev/msglog 2<>/dev/msglog
s1:1:respawn:/sbin/rc1 >/dev/msglog 2<>/dev/msglog
s2:23:wait:/sbin/rc2 >/dev/msglog 2<>/dev/msglog
s3:3:wait:/sbin/rc3 >/dev/msglog 2<>/dev/msglog
s5:5:wait:/sbin/rc5 >/dev/msglog 2<>/dev/msglog
s6:6:wait:/sbin/rc6 >/dev/msglog 2<>/dev/msglog
fw:0:wait:/sbin/uadmin 2 0 >/dev/msglog 2<>/dev/msglog
of:5:wait:/sbin/uadmin 2 6 >/dev/msglog 2<>/dev/msglog
rb:6:wait:/sbin/uadmin 2 1 >/dev/msglog 2<>/dev/msglog
sc:234:respawn:/usr/lib/saf/sac -t 300 #在2,3,4運(yùn)行級(jí)別下都執(zhí)行
co:234:respawn:/usr/lib/saf/ttymon -g -h -p "`uname -n` console login: " -T sun -d /dev/console -l console -m ldterm,ttcompat
去man inittab吧,什么都講了 :)
接著看我的inittab文件,當(dāng)action=sysinit的行執(zhí)行完之后(前三行),將執(zhí)行runlevel=3的行,即“ s3:3:wait:/sbin/rc3 ”。查找了一下,/sbin/rc3是一個(gè)shell腳本,用于初始化在運(yùn)行級(jí)別3的系統(tǒng)。因此/etc/inittab中已經(jīng)定義好了在運(yùn)行級(jí)別X下,就運(yùn)行 /sbin/rcX,那/sbin/rcX到底是什么?
cat一下/sbin/rc3,看看,重要的幾行代碼如下:
[ $_INIT_PREV_LEVEL = 2 -o $_INIT_PREV_LEVEL = 4 ] && \
echo 'Changing to state 3.' #如果以前運(yùn)行級(jí)別是2或4,則打印信息“切換到狀態(tài)三”
#如果運(yùn)行級(jí)別!=4而且存在/etc/rc3.d這個(gè)目錄,則停掉所有以K開始的腳本中的服務(wù)或程序,啟動(dòng)所有以S開始的腳本中的服務(wù)或程序
if [ $_INIT_PREV_LEVEL != 4 -a -d /etc/rc3.d ]; then
for f in /etc/rc3.d/K*; do
if [ -s $f ]; then
case $f in
*.sh) . $f ;;
*) /sbin/sh $f stop ;;
esac
fi
done
for f in /etc/rc3.d/S*; do
if [ -s $f ]; then
case $f in
*.sh) . $f ;;
*) /sbin/sh $f start ;;
esac
fi
done
fi
那就再追蹤到/etc/rc3.d下面去,
#cd /etc/rc3.d
K42amserver S13kdc.master S15nfs.server S34dhcp S50apache S52imq S77dmi S81volmgt S89sshd
README S14kdc S16boot.server S42amserver S50san_driverchk S76snmpdx S80mipagent S84appserv S90samba
哦,都是些程序或進(jìn)程的啟動(dòng)腳本,S開頭是啟動(dòng)腳本 K開頭是停止腳本。這正是/sbin/rc3這個(gè)shell腳本中設(shè)定的執(zhí)行方式。
例如:S90samba 代表一個(gè)啟動(dòng)samba服務(wù)的腳本,90表示啟動(dòng)順序編號(hào)。 K42amserver代表結(jié)束服務(wù)的腳本。
rc程序執(zhí)行完畢后,系統(tǒng)環(huán)境已經(jīng)設(shè)置好了,下面就該用戶登錄系統(tǒng)了,終于結(jié)束了。
posted on 2009-07-17 14:10
Bluesea 閱讀(454)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
linux