主題: 請(qǐng)問(wèn)在busybox 中 linuxrc 與 /sbin/init 的不同處linuxrc 是 busybox make install 產(chǎn)生出來(lái)的/sbin/init 也是busybox 用來(lái)初始開(kāi)機(jī)的程式我分別用來(lái)開(kāi)機(jī) 都可正常運(yùn)作那請(qǐng)問(wèn)兩者的差別在哪裡 還是這兩個(gè)東西其實(shí)都是一樣的 ^^"以下為摘自linux kernel Documentation應(yīng)該可以解決你的疑問(wèn)。When using initrd, the system typically boots as follows: 1) the boot loader loads the kernel and the initial RAM disk 2) the kernel converts initrd into a "normal" RAM disk and frees the memory used by initrd 3) initrd is mounted read-write as root 4) /linuxrc is executed (this can be any valid executable, including shell scripts; it is run with uid 0 and can do basically everything init can do) 5) linuxrc mounts the "real" root file system 6) linuxrc places the root file system at the root directory using the pivot_root system call 7) the usual boot sequence (e.g. invocation of /sbin/init) is performed on the root file system
the initrd file system is removedlinuxrc常見(jiàn)錯(cuò)誤2008年09月04日 星期四 下午 04:161> linuxrc不具備可執(zhí)行屬性2> linuxrc的解釋shell不在首行3> linuxrc的解釋shell不存在一般都出不了上面三個(gè)原因.linuxrc腳本kernel啟動(dòng)后,執(zhí)行/root_china/linuxrc腳本文件,接下來(lái)執(zhí)行/root_china/usr/etc/rc.local腳本文件。這兩個(gè)文件我以前沒(méi)去管是什么意思,起到什么作用,直到今天。/root_china/linuxrc:#!/bin/shecho "mount /etc as ramfs"/bin/mont -n -t ramfs ramfs /etc //將/etc目錄mount成可寫的ramfs文件系統(tǒng)/bin/cp -a /mnt/etc/* /etc //將/mnt/etc目錄下的文件拷貝到/etc目錄下echo "re-create the /etc/mtab entries"#re-create the /etc/mtab entries/bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/2 / //將/dev/mtdblock/2 mount成根文件系統(tǒng)/bin/mount -f -t ramfs ramfs /etcexec /sbin/init //執(zhí)行腳本檔 /usr/etc/rc.local1. /bin/mount -n -t ramfs ramfs /etc 這句話的作用加載一個(gè)ramfs作為/etc目錄。這樣/etc就是一個(gè)可寫目錄??催@個(gè)腳本,得出根文件系統(tǒng)是一個(gè)cramfs(只讀可壓縮文件系統(tǒng)),而/etc作為系統(tǒng)運(yùn)行配置文件的存放地點(diǎn),可能會(huì)寫一些運(yùn)行狀態(tài)在這里,linuxrc第一件事情就是將一個(gè)ramfs mount到/etc只讀目錄中,使得/etc/目錄可寫,指定參數(shù)-n的目的是告訴mount不要寫/etc/mtab(這個(gè)文件存放當(dāng)前系統(tǒng)mount了的所有文件系統(tǒng))。因?yàn)楝F(xiàn)在/etc/目錄還是只讀,所以這次mount不要寫這個(gè)文件,否則會(huì)失敗。ramfs在哪里?在 /etc/fstab文件中應(yīng)該有ramfs一項(xiàng),mount會(huì)去找這項(xiàng),如果沒(méi)有,mount會(huì)失敗。后面就執(zhí)行不下去。2. /bin/cp -a /mnt/etc/* /etc/etc成為可寫目錄后,將所有/mnt/etc中的配置文件拷貝到/etc/中,這說(shuō)明ramfs可能是一個(gè)空的ramfs,沒(méi)有配置文件,或者配置文件比較老。 同時(shí)也說(shuō)明這個(gè)系統(tǒng)是一個(gè)只讀系統(tǒng),每次系統(tǒng)運(yùn)行中寫入的配置不會(huì)保留。將以前mount的那些信息重新寫到/etc/mtab中,命令就是下面這些。3. /bin/mount -f -t cramfs -o remount,ro /dev/bon/2 //bin/mount -f -t ramfs ramfs /etc這些命令只是將這些mount信息寫到/etc/mtab中,不會(huì)實(shí)際去mount這些block device,說(shuō)明你的根文件系統(tǒng)依然是以前的那個(gè)/dev/bon/24. exec /sbin/init執(zhí)行根文件系統(tǒng)中的init執(zhí)行程序,使其成為1號(hào)進(jìn)程。shell正式運(yùn)行l(wèi)inux啟動(dòng)過(guò)程詳解2008-01-12 00:43這幾天看了很多文檔,算是對(duì)linux的啟動(dòng)過(guò)程有了比較細(xì)致的了解. 網(wǎng)上有很多文章談到這方面的內(nèi)容,但總覺(jué)得沒(méi)有一篇完全的解析linux啟動(dòng)的細(xì)節(jié),下面是我小弟在學(xué)習(xí)的過(guò)程中總結(jié)出來(lái)的一些東東.這個(gè)是完整的linux啟動(dòng)過(guò)程,不涉及內(nèi)核,但是我覺(jué)得比較詳細(xì)哦. (由于本人比較懶,這一段是從網(wǎng)上抄的) 機(jī)器加電啟動(dòng)后,BIOS開(kāi)始檢測(cè)系統(tǒng)參數(shù),如內(nèi)存的大小,日期和時(shí)間,磁盤設(shè)備以及這些磁盤設(shè)備用來(lái)引導(dǎo)的順序,通常情況下,BIOS都是被配置成首先檢查軟驅(qū)或者光驅(qū)(或兩者都檢查),然后再嘗試從硬盤引導(dǎo)。如果在這些可移動(dòng)的設(shè)備中,沒(méi)有找到可引導(dǎo)的介質(zhì),那么BIOS通常是轉(zhuǎn)向第一塊硬盤最初的幾個(gè)扇區(qū),尋找用于裝載操作系統(tǒng)的指令。裝載操作系統(tǒng)的這個(gè)程序就是boot loader. linux里面的boot loader通常是lilo或者grub,從Red Hat Linux 7.2起,GRUB(GRand Unified Bootloader)取代LILO成為了默認(rèn)的啟動(dòng)裝載程序。那么啟動(dòng)的時(shí)候grub是如何被載入的呢? grub有幾個(gè)重要的文件,stage1,stage2,有的時(shí)候需要stage1.5.這些文件一般都在/boot/grub文件夾下面.grub被載入通常包括以下幾個(gè)步驟:1. 裝載基本的引導(dǎo)裝載程序(stage1),stage1很小,網(wǎng)上說(shuō)是512字節(jié),但是在我的系統(tǒng)上用 du -b /boot/grub/stage1 顯示的是1024個(gè)字節(jié),不知道是不是grub版本不同的緣故還是我理解有誤.stage1通常位于主引導(dǎo)扇區(qū)里面,對(duì)于硬盤就是MBR了,stage1的主要功能就是裝載第二引導(dǎo)程序(stage2).這主要是歸結(jié)于在主引導(dǎo)扇區(qū)中沒(méi)有足夠的空間用于其他東西了,我用的是grub 0.93,stage2文件的大小是 107520 bit.2. 裝載第二引導(dǎo)裝載程序(stage2),這第二引導(dǎo)裝載程序?qū)嶋H上是引出更高級(jí)的功能, 以允許用戶裝載入一個(gè)特定的操作系統(tǒng)。在GRUB中,這步是讓用戶顯示一個(gè)菜單或是輸入命令。由于stage2很大,所以它一般位于文件系統(tǒng)之中(通常是boot所在的根分區(qū)).上面還提到了stage1.5這個(gè)文件,它的作用是什么呢? 你到/boot/grub目錄下看看,fat_stage_1.5 e2fs_stage_1.5 xfs_stage_1.5等等,很容易猜想stage1.5和文件系統(tǒng)有關(guān)系.有時(shí)候基本引導(dǎo)裝載程序(stage1)不能識(shí)別stage2所在的文件系統(tǒng)分區(qū),那么這時(shí)候就需要stage1.5來(lái)連接stage1和stage2了.因此對(duì)于不同的文件系統(tǒng)就會(huì)有不同的stage1.5.但是對(duì)于grub 0.93好像stage1.5并不是很重要,因?yàn)槲以囘^(guò)了,在沒(méi)有stage1.5的情況下, 我把stage1安裝在軟盤的引導(dǎo)扇區(qū)內(nèi),然后把stage2放在格式化成ext2或者fat格式的軟盤內(nèi),啟動(dòng)的時(shí)候照常引導(dǎo),并不需要e2fs_stage_1.5或者fat_stage_1.5.下面是我的試驗(yàn): #mkfs.ext2 /dev/fd0 #mount -t ext2 /dev/fd0 /mnt/floppy #cd /mnt/floppy #mkdir boot #cd boot #mkdir grub (以上三步可用mkdir -p boot/grub命令完成) #cd grub #cp /boot/grub/{stage1,stage2,grub.conf} ./ #cd; umount /mnt/floppy 以上幾步把軟盤格式化成ext2格式,然后把stage1,stage2,grub.conf這幾個(gè)啟動(dòng)的時(shí)候必須的文件拷貝到軟盤的指定目錄下.下面安裝grub到軟盤上. #grub (進(jìn)入grub環(huán)境) grub> install (fd0)/boot/grub/stage1 (fd0) (fd0)/boot/grub/stage2p (fd0)/boot/grub/grub.conf 以上這條命令也可以用下面的兩句代替 grub>root (fd0) #grub的根目錄所在的分區(qū) grub>setup (fd0) #這一步就相當(dāng)于上面的install命令 我在這里解釋一下 install (fd0)/boot/grub/stage1 (fd0) (fd0)/boot/grub/stage2 p(fd0)/boot/grub/grub.conf 這條命令.install 告訴GRUB將(fd0)/boot/grub/grub/stage1 安裝到軟驅(qū)的引導(dǎo)扇區(qū)(fd0).(fd0)/boot/grub/stage2 告訴grub stage2這個(gè)文件所在的位置.p 參數(shù)后面跟著(fd0)/boot/grub/grub.conf 告訴grub的配置文件所在的位置. 好了,讓BIOS從軟驅(qū)啟動(dòng),試一下,沒(méi)有e2fs_stage_1.5文件照樣能夠進(jìn)入系統(tǒng).其實(shí)這就是一個(gè)小小的啟動(dòng)盤啊.(了解了grub的運(yùn)行原理,就簡(jiǎn)單多了^_^)3. 現(xiàn)在我們已經(jīng)到grub的開(kāi)機(jī)選單這一步了,接下來(lái)grub所需要做的就是裝載在一個(gè)特定分區(qū)上的操作系統(tǒng),如linux內(nèi)核。一旦GRUB從它的命令行或者配置文件中,接到開(kāi)始操作系統(tǒng)的正確指令,它就尋找必要的引導(dǎo)文件,然后把機(jī)器的控制權(quán)移交給操作系統(tǒng). 由于篇幅有限,避免冗長(zhǎng),grub的命令我就不多說(shuō)了,網(wǎng)上很有多的資料,一個(gè)典型完整的引導(dǎo)linux的命令如下: title 51base root(hd0,0) kernel /bzImage ro root=/dev/ram0 initrd /initrd.img 這里有必要注意一下幾個(gè)問(wèn)題: (1)grub的磁盤以及分區(qū)的命名方式和linux有所區(qū)別,第一個(gè)磁盤是從0開(kāi)始,第一個(gè)分區(qū)也是從0開(kāi)始.譬如第一個(gè)硬盤的第5分區(qū)在linux下面是/dev/hda5 ,而在grub里面是(hd0,4).再如/dev/fd0在grub里面是(fd0,0).(最后一句如有錯(cuò)誤望提醒) (2)不管是IDE硬盤hda,hdb還是SCSI硬盤sda,sdb在grub里面都是以hd方式命名.譬如虛擬機(jī)里面的/dev/sda2在grub里面是(hd0,1),再如/dev/hdb7在grub里面以(hd1,6)命名. (3)要搞清楚上面兩個(gè)root的關(guān)系,root (hd0,0)中的root是grub命令,它用來(lái)指定boot所在的分區(qū)作為grub的根目錄.而root=/dev/ram0是kernel的參數(shù),它告訴操作系統(tǒng)內(nèi)核加載完畢之后,真實(shí)的文件系統(tǒng)所在的設(shè)備.要注意grub的根目錄和文件系統(tǒng)的根目錄的區(qū)別. 再回到上面的幾行命令. kernel命令用來(lái)指定內(nèi)核所在的位置,"/"代表(hd0,0),也就是grub的根目錄 initrd命令用來(lái)指定初始化ram的img文件所在位置. grub載入內(nèi)核bzImage并展開(kāi)到指定位置(應(yīng)該是0x100000這個(gè)地方),同時(shí)載入initrd.img到內(nèi)存(不知道是什么地方).ps: grub的任務(wù)至此就結(jié)束了,下面grub將機(jī)器的控制權(quán)轉(zhuǎn)交給操作系統(tǒng)(linux). 操作系統(tǒng)接到控制權(quán)之后,開(kāi)始start_kernel,接著內(nèi)核將initrd.img展開(kāi)到/dev/ram0為臨時(shí)根文件系統(tǒng),執(zhí)行里面的linuxrc文件. P.這里有必要說(shuō)一下initrd的作用特別是它里面的核心文件linuxrc的作用. initrd是inital ram disk的宿寫. 當(dāng)存在initrd的時(shí)候,機(jī)器啟動(dòng)的過(guò)程大概是以下幾個(gè)步驟(當(dāng)initrd這一行用noinitrd 命令代替后,就不存在initrd了) 1)boot loader(grub)加載內(nèi)核和initrd.img 2)內(nèi)核將壓縮的initrd.img解壓成正常的ram disk并且釋放initrd所占的內(nèi)存空間 3)initrd作為根目錄以讀寫方式被掛載 4)initrd里面的文件linuxrc被執(zhí)行 5)linuxrc掛載新的文件系統(tǒng) 6)linuxrc使用pivot_root系統(tǒng)調(diào)用指定新的根目錄并將現(xiàn)有的根目錄place到指定位置. 7)在新的文件系統(tǒng)下正式init 8)initrd被卸載. 為了便于理解,我將red hat linnux9 里面的initrd-2.4.20-8.img拿出來(lái)分析一下. 這其實(shí)是一個(gè)壓縮了的文件,是以gz結(jié)尾的.[root@localhost root]#cp /boot/initrd-2.4.20-8.img /mnt/initrd-2.4.20-8.gz[root@localhost root]#gunzip /mnt/initrd-2.4.20-8.gz[root@localhost root]#mount -o loop /mnt/initrd-2.4.20-8 /mnt/ram[root@localhost root]#cd /mnt/ram[root@localhost ram]#lsbin dev etc lib linuxrc loopfs proc sbin sysroot[root@localhost ram]#ls bininsmod modprobe nash[root@localhost ram]#ls libBuslogic.o ext3.o jbd.o scsi_mod.o sd_mod.o[root@localhost ram]ls devconsole null ram systty tty1 tty2 tty3 tty4sbin目錄是指向bin目錄的一個(gè)連接,其他目錄是空的.[root@localhost ram]cat linuxrc#!/bin/nash1.echo "Loading scsi_mod.o module"2.insmod /lib/scsi_mod.o3.echo "Loading sd_mod.o module"4.insmod /lib/sd_mod.o5.echo "Loading BusLogic.o module"6.insmod /lib/BusLogic.o7.echo "Loading jbd.o module"8.insmod /lib/jbd.o9.echo "Loading ext3.o module"10.insmod /lib/ext3.o11.echo Mounting /proc filesystem12.mount -t proc /proc /proc13.echo Creating block devices14.mkdevices /dev15.echo Creating root device16.mkrootdev /dev/root17.echo 0x0100 > /proc/sys/kernel/real-root-dev18.echo Mounting root filesystem19.mount -o defaults --ro -t ext3 /dev/root /sysroot20.pivot_root /sysroot /sysroot/initrd21.umount /initrd/proc上面的編號(hào)是我為了下面好說(shuō)明加上去的.首先我們必須注意的是這里使用的shell是nash而不是bash,nash是專門為linuxrc可執(zhí)行腳本設(shè)計(jì)的,因此你有必要看一看nash的man文檔.1-10行是加載一些必要的模快.11-12行加載proc內(nèi)核文件系統(tǒng),13-14行利用nash內(nèi)建的命令mkdevices創(chuàng)建塊設(shè)備,mkdevices是根據(jù)/proc/partitions文件創(chuàng)建里面列出的所有塊設(shè)備.15-16行利用nash內(nèi)建的命令mkrootdev,mkrootdev使它后面的參數(shù)/dev/root成為一個(gè)塊節(jié)點(diǎn)從而使得根分區(qū)設(shè)備被掛載,其中根分區(qū)設(shè)備由grub.conf里面的kernel命令后面所帶的參數(shù)root=決定,如果root=參數(shù)沒(méi)有被指定,/proc/sys/kernel/real-root-dev文件將提供根分區(qū)設(shè)備號(hào).17行將數(shù)字256寫入到后面的文件里面去.18-19行掛載根文件系統(tǒng)到/sysroot目錄下,/dev/root里面的內(nèi)容就是root=參數(shù)所指定的設(shè)備里面的內(nèi)容20行調(diào)用pivot_root改變根目錄所在地并place舊的根目錄到指定的位置.21行卸載舊的根目錄里面的proc內(nèi)核文件系統(tǒng).從這里面我們總結(jié)一下linuxrc的作用: (參考/usr/src/linux-2.4/Documentation/initrd.txt文檔) 2)/linuxrc文件決定在掛載真正的文件系統(tǒng)之前所需完成的事情(譬如加載必要的網(wǎng)絡(luò)驅(qū)動(dòng)或者加載ext3文件系統(tǒng)). 3)/linuxrc加載必要的模塊. 4)/linuxrc掛載根文件系統(tǒng) 5)/linuxrc調(diào)用pivot_root來(lái)改變根目錄 關(guān)于initrd的用途可以查考上面提到的文檔,想知道linux系統(tǒng)是如何安裝的嗎?那里面由答案. 既然linuxrc的主要目的是加載??煊玫?那如果我們的內(nèi)核沒(méi)有動(dòng)態(tài)的模塊而所需的功能都是靜態(tài)編譯進(jìn)內(nèi)核的,那么是不是可以不用linuxrc文件呢? 答案是可以不用,在普通的linux操作系統(tǒng)里面可以加入noinitrd選項(xiàng)以告知bootloader 不使用initrd.如果我們做網(wǎng)關(guān),因?yàn)閞am是我們的文件系統(tǒng)的載體,所以initrd一行當(dāng)然不能去掉,但是我們可以不用linuxrc文件,sysroot文件夾和initrd文件夾. 不信的話,試試看吧. 好了,initrd(linuxrc)已經(jīng)介紹完了. linuxrc執(zhí)行完畢之后,系統(tǒng)就會(huì)以真正的根目錄正式init. 系統(tǒng)在/bin/或者/sbin目錄下找到init程式,然后根據(jù)它的配置文件/etc/fstab進(jìn)行初始化,最后調(diào)用mingetty程式啟動(dòng)login完成引導(dǎo). ps:init這一部分網(wǎng)上有很多的詳細(xì)資料所以我在這里并沒(méi)有展開(kāi)來(lái)說(shuō). 終于寫完了,希望對(duì)你有所幫助.如有錯(cuò)誤,還望指正.Trackback: http://tb.donews.net/TrackBack.aspx?PostId=731583Linux init詳解2008-12-08 12:25Linux init詳解init是Linux系統(tǒng)操作中不可缺少的程序之一。
所謂的init進(jìn)程,它是一個(gè)由內(nèi)核啟動(dòng)的用戶級(jí)進(jìn)程。
內(nèi)核自行啟動(dòng)(已經(jīng)被載入內(nèi)存,開(kāi)始運(yùn)行,并已初始化所有的設(shè)備驅(qū)動(dòng)程序和數(shù)據(jù)結(jié)構(gòu)等)之后,就通過(guò)啟動(dòng)一個(gè)用戶級(jí)程序init的方式,完成引導(dǎo)進(jìn)程。所以,init始終是第一個(gè)進(jìn)程(其進(jìn)程編號(hào)始終為1)。
內(nèi)核會(huì)在過(guò)去曾使用過(guò)init的幾個(gè)地方查找它,它的正確位置(對(duì)Linux系統(tǒng)來(lái)說(shuō))是/sbin/init。如果內(nèi)核找不到init,它就會(huì)試著運(yùn)行/bin/sh,如果運(yùn)行失敗,系統(tǒng)的啟動(dòng)也會(huì)失敗?!∫?、什么是INIT:
init是Linux系統(tǒng)操作中不可缺少的程序之一。
所謂的init進(jìn)程,它是一個(gè)由內(nèi)核啟動(dòng)的用戶級(jí)進(jìn)程。
內(nèi)核自行啟動(dòng)(已經(jīng)被載入內(nèi)存,開(kāi)始運(yùn)行,并已初始化所有的設(shè)備驅(qū)動(dòng)程序和數(shù)據(jù)結(jié)構(gòu)等)之后,就通過(guò)啟動(dòng)一個(gè)用戶級(jí)程序init的方式,完成引導(dǎo)進(jìn)程。所以,init始終是第一個(gè)進(jìn)程(其進(jìn)程編號(hào)始終為1)。
內(nèi)核會(huì)在過(guò)去曾使用過(guò)init的幾個(gè)地方查找它,它的正確位置(對(duì)Linux系統(tǒng)來(lái)說(shuō))是/sbin/init。如果內(nèi)核找不到init,它就會(huì)試著運(yùn)行/bin/sh,如果運(yùn)行失敗,系統(tǒng)的啟動(dòng)也會(huì)失敗。
二、運(yùn)行級(jí)別
那么,到底什么是運(yùn)行級(jí)呢?
簡(jiǎn)單的說(shuō),運(yùn)行級(jí)就是操作系統(tǒng)當(dāng)前正在運(yùn)行的功能級(jí)別。這個(gè)級(jí)別從1到6 ,具有不同的功能。
不同的運(yùn)行級(jí)定義如下:(可以參考Red Hat Linux 里面的/etc/inittab)
# 0 - 停機(jī)(千萬(wàn)不能把initdefault 設(shè)置為0 )
# 1 - 單用戶模式
# 2 - 多用戶,沒(méi)有 NFS
# 3 - 完全多用戶模式(標(biāo)準(zhǔn)的運(yùn)行級(jí))
# 4 - 沒(méi)有用到
# 5 - X11 (xwindow)
# 6 - 重新啟動(dòng) (千萬(wàn)不要把initdefault 設(shè)置為6 )
這些級(jí)別在/etc/inittab 文件里指定。這個(gè)文件是init 程序?qū)ふ业闹饕募?,最先運(yùn)行的服務(wù)是放在/etc/rc.d 目錄下的文件。在大多數(shù)的Linux 發(fā)行版本中,啟動(dòng)腳本都是位于 /etc/rc.d/init.d中的。這些腳本被用ln 命令連接到 /etc/rc.d/rcn.d 目錄。(這里的n 就是運(yùn)行級(jí)0-6)
三、運(yùn)行級(jí)別的配置
運(yùn)行級(jí)別的配置是在/etc/inittab行內(nèi)進(jìn)行的,如下所示:
12 : 2 : wait : / etc / init.d / rc 2
第一個(gè)字段是一個(gè)任意指定的標(biāo)簽;
第二個(gè)字段表示這一行適用于運(yùn)行那個(gè)級(jí)別(這里是2);
第三個(gè)字 段表示進(jìn)入運(yùn)行級(jí)別時(shí),init應(yīng)該運(yùn)行第四個(gè)字段內(nèi)的命令一次,而且init應(yīng)該等待該命令結(jié)束。/etc/init.d/rc命令運(yùn)行啟動(dòng)和終止輸入以便進(jìn)入運(yùn)行級(jí)別2時(shí)所需的任何命令。
第四個(gè)字段中的命令執(zhí)行設(shè)置運(yùn)行級(jí)別時(shí)的一切“雜活”。它啟動(dòng)已經(jīng)沒(méi)有運(yùn)行的服務(wù),終止不應(yīng)該再在新運(yùn)行級(jí)別內(nèi)運(yùn)行的服務(wù)。根據(jù)Linux版本的不同,采用的具體命令也不同,而且運(yùn)行級(jí)別的配置也是有差別的。
init啟動(dòng)時(shí),它會(huì)在/etc/inittab內(nèi)查找一個(gè)代碼行,這一行指定了默認(rèn)的運(yùn)行級(jí)別:
id : 2 : initdefault :
你可以要求init在啟動(dòng)時(shí),進(jìn)入非默認(rèn)運(yùn)行級(jí)別,這是通過(guò)為內(nèi)核指定一個(gè)“single”或“emergency” 命令行參數(shù)來(lái)實(shí)現(xiàn)的。比如說(shuō),內(nèi)核命令行參數(shù)的指定可通過(guò)LILO來(lái)執(zhí)行。這樣一來(lái),你就可以選擇單用戶模式了(即運(yùn)行級(jí)別1)。
系統(tǒng)正在運(yùn)行時(shí),telinit命令可更改運(yùn)行級(jí)別。運(yùn)行級(jí)別發(fā)生變化時(shí), init 就會(huì)從/etc/inittab運(yùn)行相應(yīng)的命令。
四、/etc/inittab中的特殊配置
/etc/inittab中,有幾個(gè)特殊的特性,允許init重新激活特殊事件。這些特殊特性都是用第三個(gè)字段中的特殊關(guān)鍵字標(biāo)記出來(lái)的。比如:
1. powerwait
允許init在電源被切斷時(shí),關(guān)閉系統(tǒng)。其前提是具有U P S和監(jiān)視U P S并通知init電源已被切斷的軟件。
2. ctrlaltdel
允許init在用戶于控制臺(tái)鍵盤上按下C t r l + A l t + D e l組合鍵時(shí),重新啟動(dòng)系統(tǒng)。注意,如果該系統(tǒng)放在一個(gè)公共場(chǎng)所,系統(tǒng)管理員可將C t r l + A l t + D e l組合鍵配置為別的行為,比如忽略等。
3. sysinit
系統(tǒng)啟動(dòng)時(shí)準(zhǔn)備運(yùn)行的命令。比如說(shuō),這個(gè)命令將清除/tmp。
上面列出的特殊關(guān)鍵字尚不完整。其他的關(guān)鍵字及其使用詳情,可參考你的inittab手冊(cè)頁(yè)。
五、在單用戶模式下引導(dǎo)
一個(gè)重要的運(yùn)行級(jí)別就是單用戶模式(運(yùn)行級(jí)別1),該模式中,只有一個(gè)系統(tǒng)管理員使用特定的機(jī)器,而且盡可能少地運(yùn)行系統(tǒng)服務(wù),其中包含登錄。單用戶模式對(duì)少數(shù)管理任務(wù)(比如在/usr分區(qū)上運(yùn)行fsck)而言,是很有必要的,因?yàn)檫@需要卸載分區(qū),但這是不可能的,除非所有的服務(wù)系統(tǒng)已被殺死。
一個(gè)正在運(yùn)行的系統(tǒng)可以進(jìn)入單用戶模式,具體做法是利用init,請(qǐng)求運(yùn)行級(jí)別1。內(nèi)核啟動(dòng)時(shí),在內(nèi)核命令行指定single或emergency關(guān)鍵字,就可進(jìn)入運(yùn)行級(jí)別1了。內(nèi)核同時(shí)也為init指定命令行, init從關(guān)鍵字得知自己不應(yīng)該采用默認(rèn)的運(yùn)行級(jí)別(內(nèi)核命令行的輸入方式和你啟動(dòng)系統(tǒng)的方式有關(guān))。
有時(shí),以單用戶模式進(jìn)行啟動(dòng)是必要的,這樣一來(lái),用戶在裝入分區(qū)之前,或至少在裝入分散的/usr分區(qū)之前,能手工運(yùn)行fsck(在分散的文件系統(tǒng)上,任何活動(dòng)都可能使其更為分散,所以應(yīng)該盡可能地運(yùn)行fsck)。
如果自動(dòng)化的fsck在啟動(dòng)時(shí)失敗了,啟動(dòng)腳本init的運(yùn)行將自動(dòng)進(jìn)入單用戶模式。這樣做是為了防止系統(tǒng)使用不連貫的文件系統(tǒng),這個(gè)文件系統(tǒng)是f s c k不能自動(dòng)修復(fù)的。文件系統(tǒng)不連貫的現(xiàn)象極為少見(jiàn),而且通常會(huì)導(dǎo)致硬盤的不連貫或?qū)嶒?yàn)性的內(nèi)核釋放,但最好能做到防患于未然。
由于安全上的考慮,在單用戶模式下,啟動(dòng)外殼腳本之前,配置得當(dāng)?shù)南到y(tǒng)會(huì)要求用戶提供root密碼。否則,它會(huì)簡(jiǎn)單地為L(zhǎng) I L O輸入合適的一行代碼,以r o o t的身份登錄(當(dāng)然,如果/etc/passwd已經(jīng)由于文件系統(tǒng)的問(wèn)題而不連貫了,就不適合這里的原則了,為對(duì)付這種情況,你最好隨時(shí)準(zhǔn)備一張啟動(dòng)盤)。
不同的運(yùn)行級(jí)有不同的用處,也應(yīng)該根據(jù)自己的不同情形來(lái)設(shè)置。
例如,如果丟失了root口令,那么可以讓機(jī)器啟動(dòng)進(jìn)入單用戶狀態(tài)。在啟動(dòng)后的 lilo 提示符下輸入:
init=/bin/sh rw 使機(jī)器進(jìn)入運(yùn)行級(jí)1 ,并把 root 文件系統(tǒng)掛為讀寫。他會(huì)跳過(guò)所有系統(tǒng)認(rèn)證,讓你可以使用passwd 程序來(lái)改變r(jià)oot口令,然后啟動(dòng)到一個(gè)新的運(yùn)行級(jí)。Linux操作系統(tǒng)中/sbin/init程序的執(zhí)行過(guò)程2007-09-02 00:28來(lái)自:http://linux.ccidnet.com/art/2583/20070821/1184763_1.html當(dāng)init啟動(dòng)后,它通過(guò)執(zhí)行 各種啟動(dòng)事務(wù)來(lái)繼續(xù)引導(dǎo)進(jìn)程(檢查并監(jiān)視文件系統(tǒng),啟動(dòng)后臺(tái)程序daemons,等等),直至完成用戶所有操作環(huán)境的設(shè)置工作。這里主要涉及4個(gè)程序: init、getty(agetty)、login和shell程序。這4個(gè)程序之間的關(guān)系見(jiàn)下圖所示。init進(jìn)程的主要任務(wù)是根據(jù)/etc/rc文件中設(shè)置的信息,執(zhí)行其中設(shè)置的命 令,然后根據(jù)/etc/inittab文件中的信息,為每一個(gè)允許登錄的終端設(shè)備使用fork()創(chuàng)建一個(gè)子進(jìn)程,并在每個(gè)新創(chuàng)建的子進(jìn)程中運(yùn)行 agetty (getty)程序。而init進(jìn)程則調(diào)用wait(),進(jìn)入等待子進(jìn)程結(jié)束狀態(tài)。每當(dāng)它的一個(gè)子進(jìn)程結(jié)束退出,它就會(huì)根據(jù)wait()返回的pid號(hào)知 道是哪個(gè)對(duì)應(yīng)終端的子進(jìn)程結(jié)束了,因此就會(huì)為相應(yīng)終端設(shè)備再創(chuàng)建一個(gè)新的子進(jìn)程,并在該子進(jìn)程中重新執(zhí)行agetty程序。這樣,每個(gè)被允許的終端設(shè)備都 始終有一個(gè)對(duì)應(yīng)的進(jìn)程為其等待處理。在正常的操作下,init確定agetty正在工作著以允許用戶登錄,并且收取孤 立進(jìn)程。孤立進(jìn)程是指那些其父輩進(jìn)程已結(jié)束的進(jìn)程;在Linux中所有的進(jìn)程必須屬于單棵進(jìn)程樹(shù),所以孤立進(jìn)程必須被收取。當(dāng)系統(tǒng)關(guān)閉時(shí),init負(fù)責(zé)殺 死所有其它的進(jìn)程,卸載所有的文件系統(tǒng)以及停止處理器的工作,以及任何它被配置成要做的工作。getty程序的主要任務(wù)是設(shè)置終端類型、屬性、速度和線路規(guī)程。它打開(kāi)并初始化一 個(gè)tty端口,顯示提示信息,并等待用戶鍵入用戶名。該程序只能由超級(jí)用戶執(zhí)行。通常,若/etc/issue文本文件存在,則getty會(huì)首先顯示其中 的文本信息,然后顯示登錄提示信息(例如:plinux login: ),讀取用戶鍵入的登錄名,并執(zhí)行l(wèi)ogin程序。為了能讓init程序運(yùn)行g(shù)etty,/etc/inittab文件中必須含有g(shù)etty(agetty)命令。/etc/inittab文件中有關(guān)agetty的內(nèi)容例子見(jiàn)如下所示。列表 3.1 poeigl-1.2中的inittab文件# inittab for linux, poeigl 1.2# format:# ttyline:termcap-entry:getty-commandtty1:con80x60:/bin/agetty 9600 tty1tty2:con80x60:/bin/agetty 9600 tty2tty3:con80x60:/bin/agetty 9600 tty3tty4:con80x60:/bin/agetty 9600 tty4# tty5:con80x60:/bin/agetty 9600 tty5# tty64:dumb:/bin/agetty 9600 tty64# tty65:dumb:/bin/agetty -m -t60 2400 tty65每個(gè)終端都有自己的getty命令。其中列出了tty1—tty4對(duì)應(yīng)的登錄項(xiàng)信 息。以’#’開(kāi)始的是注釋行。第1列是所用終端設(shè)備名稱,第2列是指定終端的類型,這里指定了終端類型是con80x60。第3列是所執(zhí)行的命令及其參 數(shù)。最后兩行中的tty64和tty65對(duì)應(yīng)連接在串行端口上的終端。對(duì)于使用串行端口與主機(jī)直接相連的終端以及通過(guò)modem撥號(hào)連接的終端, Linux的agetty程序還有其它一些屬性。如在讀取登錄名時(shí)自動(dòng)調(diào)整tty的設(shè)置信息,例如奇偶校驗(yàn)位、檫除字符、行結(jié)束字符以及上檔鍵字符等???選擇地從鏈接的Hayes兼容modem信息中檢測(cè)出傳輸波特率。/dev/inittab中每一項(xiàng)的參數(shù)格式與具體使用哪一種getty程序有關(guān)。目前一般常用的getty程序有如下幾種:1.agetty(有時(shí)直接稱為getty):容易設(shè)置,無(wú)須配置文件。適用于直接連接的終端;2.getty(getty_ps的一部分):適用于直接連接的終端;3.mgetty:最適合于通過(guò)modem連接,也可用于直連;4.uugetty:僅用于通過(guò)modem連接終端,是getty_ps軟件包的部分;5.mingetty:簡(jiǎn)單的getty。適用于控制臺(tái)終端或虛擬終端;6.fbgetty:適用于控制臺(tái)或虛擬終端。Redhat 9系統(tǒng)默認(rèn)配置中帶有mingetty和agetty兩個(gè)程序??刂婆_(tái)或虛擬終端使用的是mingetty。對(duì)于實(shí)際的字符終端則一般使用agetty。因此在Redhat 9系統(tǒng)的/etc/inittab文件中會(huì)看到以下的信息。列表 3.2 RedHat 9系統(tǒng)的/etc/inittab文件中有關(guān)getty的信息# Run gettys in standard runlevels1:2345:respawn:/sbin/mingetty tty12:2345:respawn:/sbin/mingetty tty23:2345:respawn:/sbin/mingetty tty34:2345:respawn:/sbin/mingetty tty45:2345:respawn:/sbin/mingetty tty56:2345:respawn:/sbin/mingetty tty6其中第1列表示名稱tty后的數(shù)字,2345表示該mingetty的運(yùn)行層。respawn表示如果該mingetty被終止,則mingetty將再次自動(dòng)執(zhí)行。/sbin/mingetty是命令。ttyn代表/dev/ttyn(n表示數(shù)字1—5)。在登錄到Linux系統(tǒng)中之后,你會(huì)發(fā)現(xiàn)(使用”top”或”ps –ax”命令)自己終端原來(lái)的getty進(jìn)程已經(jīng)找不到了。因?yàn)間etty進(jìn)程執(zhí)行了login程序,被替換成了login進(jìn)程,并且最后被替換成你的登錄shell進(jìn)程。當(dāng)你在”login: “提示符下鍵入了你的用戶名后,getty會(huì)讀取用戶名并且去執(zhí)行l(wèi)ogin程序,也把用戶名信息傳給了它。因此getty進(jìn)程被替換成了login進(jìn) 程。此時(shí)login進(jìn)程會(huì)接著要求你輸入口令。在口令檢查通過(guò)后就會(huì)去執(zhí)行/etc/passwd文件中對(duì)應(yīng)你用戶名項(xiàng)中記錄的程序。通常這個(gè)程序是 bash shell程序。因此原來(lái)的getty進(jìn)程最終被替換成了bash進(jìn)程,對(duì)應(yīng)的這三個(gè)程序也就都具有相同的進(jìn)程ID。當(dāng)注銷登錄(log out)時(shí),則該終端上的所有進(jìn)程都會(huì)被終止(killed),包括登錄shell進(jìn)程bash。因此,對(duì)于在/etc/inittab文件中列出的 getty程序,一旦其被替換執(zhí)行的bash程序被終止或退出,init進(jìn)程就會(huì)為對(duì)應(yīng)終端重新創(chuàng)建一個(gè)getty進(jìn)程。login程序則主要用于要求登錄用戶輸入密碼。根據(jù)用戶輸入的用戶名,它從口令文 件passwd中取得對(duì)應(yīng)用戶的登錄項(xiàng),然后調(diào)用getpass()以顯示”password:”提示信息,讀取用戶鍵入的密碼,然后使用加密算法對(duì)鍵入 的密碼進(jìn)行加密處理,并與口令文件中該用戶項(xiàng)中pw_passwd字段作比較。如果用戶幾次鍵入的密碼均無(wú)效,則login程序會(huì)以出錯(cuò)碼1退出執(zhí)行,表 示此次登錄過(guò)程失敗。此時(shí)父進(jìn)程(進(jìn)程init)的wait()會(huì)返回該退出進(jìn)程的pid,因此會(huì)根據(jù)記錄下來(lái)的信息再次創(chuàng)建一個(gè)子進(jìn)程,并在該子進(jìn)程中 針對(duì)該終端設(shè)備再次執(zhí)行agetty程序,重復(fù)上述過(guò)程。login程序也可以被用戶在運(yùn)行過(guò)程中在shell下當(dāng)作一個(gè)命令執(zhí)行。此時(shí)它可 以被用隨時(shí)從一個(gè)用戶切換成另一個(gè)用戶。如果執(zhí)行時(shí)沒(méi)有給出參數(shù),則login就會(huì)顯示輸入用戶名的提示信息。如果用戶不是超級(jí)用戶(root),并且 /etc/目錄下存在一個(gè)名為nologin的文件,那么該文件中的信息就會(huì)被顯示出來(lái),此次登錄過(guò)程也隨即被終止。如果在/etc/usertty文件中對(duì)該用戶指定了特殊的訪問(wèn)限制,那么這些限制要求必須滿足。如果是一個(gè)超級(jí)用戶,那么所使用的登錄tty設(shè)備必須是在/etc/securetty文件中指定的。在所有這些條件滿足之后,login同樣也會(huì)要求用戶輸入密碼并對(duì)其進(jìn)行檢查。如 果.hushlogin存在的話,login就會(huì)執(zhí)行一個(gè)“安靜”的登錄過(guò)程,也即不檢查是否有郵件,也不顯示上次登錄時(shí)間和motd文件中的信息。否則 如果/var/log/lastlog文件存在的話,就會(huì)顯示其中的最后登錄時(shí)間。如果用戶鍵入的密碼正確,則login就會(huì)把當(dāng)前工作目錄(Currend Work Directory)修改成口令文件中指定的該用戶的起始工作目錄。并把對(duì)該終端設(shè)備的訪問(wèn)權(quán)限修改成用戶讀/寫和組寫,設(shè)置進(jìn)程的組ID。然后利用所得 到的信息初始化環(huán)境變量信息,例如起始目錄(HOME=)、使用的shell程序(SHELL=)、用戶名(USER=和LOGNAME=)和系統(tǒng)執(zhí)行程 序的默認(rèn)路徑序列(PATH=)。接著顯示/etc/motd文件(message-of-the-day)中的文本信息,并檢查并顯示該用戶是否有郵件 的信息。最后login程序改變成登錄用戶的用戶ID并執(zhí)行口令文件中該用戶項(xiàng)中指定的shell程序,如bash或csh等。如果口令文件/etc/passwd中該用戶項(xiàng)中沒(méi)有指定使用哪個(gè)shell程序, 系統(tǒng)則會(huì)使用默認(rèn)的/bin/sh程序。如果口令文件中也沒(méi)有為該用戶指定用戶起始目錄的話,系統(tǒng)就會(huì)使用默認(rèn)的根目錄/。有關(guān)login程序的一些執(zhí)行 選項(xiàng)和特殊訪問(wèn)限制的說(shuō)明,請(qǐng)參見(jiàn)Linux系統(tǒng)中的在線手冊(cè)頁(yè)(man 8 login)。Shell程序是一個(gè)復(fù)雜的命令行解釋程序,是當(dāng)用戶登錄系統(tǒng)進(jìn)行交互操作時(shí)執(zhí)行的 程序。它是用戶與計(jì)算機(jī)進(jìn)行交互操作的地方。它獲取用戶輸入的信息,然后執(zhí)行命令。用戶可以在終端上向shell直接進(jìn)行交互輸入,也可以使用shell 腳本文件向shell解釋程序輸入。在Linux系統(tǒng)中,目前常用的shell有:Bourne Again Shell,/bin/bashC shell,/bin/csh(或tcsh)BSD shell/bin/ash(或bsh)在登錄過(guò)程中,系統(tǒng)(login)會(huì)從口令文件用戶對(duì)應(yīng)登錄項(xiàng)的最后一個(gè)字段知道應(yīng)該為用戶執(zhí)行哪個(gè)shell程序。shell程序中實(shí)現(xiàn)了一個(gè)具有流控制結(jié)構(gòu)的語(yǔ)言,使用相當(dāng)廣泛。目前這些 shell程序都朝著與IEEE POSIX 1003.2兼容的方向發(fā)展,因此它們各自雖然各自有自己的特點(diǎn),但基本功能已經(jīng)越來(lái)越相象。本書主要介紹bash的工作原理和實(shí)現(xiàn)機(jī)制,其它幾種 shell的實(shí)現(xiàn)機(jī)制與之類似。在登錄過(guò)程中l(wèi)ogin開(kāi)始執(zhí)行shell時(shí),所帶參數(shù)argv[0]的第一個(gè)字符 是’-’,表示該shell是作為一個(gè)登錄shell被執(zhí)行。此時(shí)該shell程序會(huì)根據(jù)該字符,執(zhí)行某些與登錄過(guò)程相應(yīng)的操作。登錄shell會(huì)首先從 /etc/profile文件以及.profile文件(若存在的話)讀取命令并執(zhí)行。如果在進(jìn)入shell時(shí)設(shè)置了ENV環(huán)境變量,或者在登錄 shell的.profile文件中設(shè)置了該變量,則shell下一步會(huì)從該變量命名的文件中讀去命令并執(zhí)行。因此用戶應(yīng)該把每次登錄時(shí)都要執(zhí)行的命令放 在.profile文件中,而把每次運(yùn)行shell都要執(zhí)行的命令放在ENV變量指定的文件中。設(shè)置ENV環(huán)境變量的方法是把下列語(yǔ)句放在你起始目錄的. profile文件中。ENV=$HOME/.anyfilename; export ENV在執(zhí)行shell時(shí),除了一些指定的可選項(xiàng)以外,如果還指定了命令行參數(shù),則shell會(huì)把第一個(gè)參數(shù)看作是一個(gè)腳本文件名并執(zhí)行其中的命令,而其余的參數(shù)則被看作是shell的位置參數(shù)($1、$2等)。否則shell程序?qū)钠錁?biāo)準(zhǔn)輸入中讀取命令。在執(zhí)行shell程序時(shí)可以有很多選項(xiàng),請(qǐng)參見(jiàn)Linux系統(tǒng)中的有關(guān)sh的在線手冊(cè)頁(yè)中的說(shuō)明。Linux 的 initrd (linuxrc,init)2008-10-19 17:18Linux 的 initrd 技術(shù)是一個(gè)非常普遍使用的機(jī)制,linux2.6 內(nèi)核的 initrd 的文件格式由原來(lái)的文件系統(tǒng)鏡像文件轉(zhuǎn)變成了 cpio 格式,變化不僅反映在文件格式上, linux 內(nèi)核對(duì)這兩種格式的 initrd 的處理有著截然的不同。本文首先介紹了什么是 initrd 技術(shù),然后分別介紹了 Linux2.4 內(nèi)核和 2.6 內(nèi)核的 initrd 的處理流程。最后通過(guò)對(duì) Linux2.6 內(nèi)核的 initrd 處理部分代碼的分析,使讀者可以對(duì) initrd 技術(shù)有一個(gè)全面的認(rèn)識(shí)。為了更好的閱讀本文,要求讀者對(duì) Linux 的 VFS 以及 initrd 有一個(gè)初步的了解。1.什么是 Initrdinitrd 的英文含義是 boot loader initialized RAM disk,就是由 boot loader 初始化的內(nèi)存盤。在 linux內(nèi)核啟動(dòng)前, boot loader 會(huì)將存儲(chǔ)介質(zhì)中的 initrd 文件加載到內(nèi)存,內(nèi)核啟動(dòng)時(shí)會(huì)在訪問(wèn)真正的根文件系統(tǒng)前先訪問(wèn)該內(nèi)存中的 initrd 文件系統(tǒng)。在 boot loader 配置了 initrd 的情況下,內(nèi)核啟動(dòng)被分成了兩個(gè)階段,第一階段先執(zhí)行 initrd 文件系統(tǒng)中的"某個(gè)文件",完成加載驅(qū)動(dòng)模塊等任務(wù),第二階段才會(huì)執(zhí)行真正的根文件系統(tǒng)中的 /sbin/init 進(jìn)程。這里提到的"某個(gè)文件",Linux2.6 內(nèi)核會(huì)同以前版本內(nèi)核的不同,所以這里暫時(shí)使用了"某個(gè)文件"這個(gè)稱呼,后面會(huì)詳細(xì)講到。第一階段啟動(dòng)的目的是為第二階段的啟動(dòng)掃清一切障愛(ài),最主要的是 加載根文件系統(tǒng)存儲(chǔ)介質(zhì)的驅(qū)動(dòng)模塊。我們知道根文件系統(tǒng)可以存儲(chǔ)在包括IDE、SCSI、USB在內(nèi)的多種介質(zhì)上,如果將這些設(shè)備的驅(qū)動(dòng)都編譯進(jìn)內(nèi)核,可 以想象內(nèi)核會(huì)多么龐大、臃腫。Initrd 的用途主要有以下四種:1. linux 發(fā)行版的必備部件linux 發(fā)行版必須適應(yīng)各種不同的硬件架構(gòu),將所有的驅(qū)動(dòng)編譯進(jìn)內(nèi)核是不現(xiàn)實(shí)的,initrd 技術(shù)是解決該問(wèn)題的關(guān)鍵技術(shù)。Linux 發(fā)行版在內(nèi)核中只編譯了基本的硬件驅(qū)動(dòng),在安裝過(guò)程中通過(guò)檢測(cè)系統(tǒng)硬件,生成包含安裝系統(tǒng)硬件驅(qū)動(dòng)的 initrd,無(wú)非是一種即可行又靈活的解決方案。2. livecd 的必備部件同 linux 發(fā)行版相比,livecd 可能會(huì)面對(duì)更加復(fù)雜的硬件環(huán)境,所以也必須使用 initrd。3. 制作 Linux usb 啟動(dòng)盤必須使用 initrdusb 設(shè)備是啟動(dòng)比較慢的設(shè)備,從驅(qū)動(dòng)加載到設(shè)備真正可用大概需要幾秒鐘時(shí)間。如果將 usb 驅(qū)動(dòng)編譯進(jìn)內(nèi)核,內(nèi)核通常不能成功訪問(wèn) usb 設(shè)備中的文件系統(tǒng)。因?yàn)樵趦?nèi)核訪問(wèn) usb 設(shè)備時(shí), usb 設(shè)備通常沒(méi)有初始化完畢。所以常規(guī)的做法是,在 initrd 中加載 usb 驅(qū)動(dòng),然后休眠幾秒中,等待 usb設(shè)備初始化完畢后再掛載 usb 設(shè)備中的文件系統(tǒng)。4. 在 linuxrc 腳本中可以很方便地啟用個(gè)性化 bootsplash。2.Linux2.4內(nèi)核對(duì) Initrd 的處理流程為了使讀者清晰的了解Linux2.6內(nèi)核initrd機(jī)制的變化,在重點(diǎn)介紹Linux2.6內(nèi)核initrd之前,先對(duì)linux2.4內(nèi)核的 initrd進(jìn)行一個(gè)簡(jiǎn)單的介紹。Linux2.4內(nèi)核的initrd的格式是文件系統(tǒng)鏡像文件,本文將其稱為image-initrd,以區(qū)別后面介紹 的linux2.6內(nèi)核的cpio格式的initrd。 linux2.4內(nèi)核對(duì)initrd的處理流程如下:1. boot loader把內(nèi)核以及/dev/initrd的內(nèi)容加載到內(nèi)存,/dev/initrd是由boot loader初始化的設(shè)備,存儲(chǔ)著initrd。2. 在內(nèi)核初始化過(guò)程中,內(nèi)核把 /dev/initrd 設(shè)備的內(nèi)容解壓縮并拷貝到 /dev/ram0 設(shè)備上。3. 內(nèi)核以可讀寫的方式把 /dev/ram0 設(shè)備掛載為原始的根文件系統(tǒng)。4. 如果 /dev/ram0 被指定為真正的根文件系統(tǒng),那么內(nèi)核跳至最后一步正常啟動(dòng)。5. 執(zhí)行 initrd 上的 /linuxrc 文件,linuxrc 通常是一個(gè)腳本文件,負(fù)責(zé)加載內(nèi)核訪問(wèn)根文件系統(tǒng)必須的驅(qū)動(dòng), 以及加載根文件系統(tǒng)。6. /linuxrc 執(zhí)行完畢,真正的根文件系統(tǒng)被掛載。7. 如果真正的根文件系統(tǒng)存在 /initrd 目錄,那么 /dev/ram0 將從 / 移動(dòng)到 /initrd。否則如果 /initrd 目錄不存在, /dev/ram0 將被卸載。8. 在真正的根文件系統(tǒng)上進(jìn)行正常啟動(dòng)過(guò)程 ,執(zhí)行 /sbin/init。 linux2.4 內(nèi)核的 initrd 的執(zhí)行是作為內(nèi)核啟動(dòng)的一個(gè)中間階段,也就是說(shuō) initrd 的 /linuxrc 執(zhí)行以后,內(nèi)核會(huì)繼續(xù)執(zhí)行初始化代碼,我們后面會(huì)看到這是 linux2.4 內(nèi)核同 2.6 內(nèi)核的 initrd 處理流程的一個(gè)顯著區(qū)別。3.Linux2.6 內(nèi)核對(duì) Initrd 的處理流程linux2.6 內(nèi)核支持兩種格式的 initrd,一種是前面第 3 部分介紹的 linux2.4 內(nèi)核那種傳統(tǒng)格式的文件系統(tǒng)鏡像-image-initrd,它的制作方法同 Linux2.4 內(nèi)核的 initrd 一樣,其核心文件就是 /linuxrc。另外一種格式的 initrd 是 cpio 格式的,這種格式的 initrd 從 linux2.5 起開(kāi)始引入,使用 cpio 工具生成,其核心文件不再是 /linuxrc,而是 /init,本文將這種 initrd 稱為 cpio-initrd。盡管 linux2.6 內(nèi)核對(duì) cpio-initrd和 image-initrd 這兩種格式的 initrd 均支持,但對(duì)其處理流程有著顯著的區(qū)別,下面分別介紹 linux2.6 內(nèi)核對(duì)這兩種 initrd 的處理流程。cpio-initrd 的處理流程1. boot loader 把內(nèi)核以及 initrd 文件加載到內(nèi)存的特定位置。2. 內(nèi)核判斷initrd的文件格式,如果是cpio格式。3. 將initrd的內(nèi)容釋放到rootfs中。4. 執(zhí)行initrd中的/init文件,執(zhí)行到這一點(diǎn),內(nèi)核的工作全部結(jié)束,完全交給/init文件處理。image-initrd的處理流程1. boot loader把內(nèi)核以及initrd文件加載到內(nèi)存的特定位置。2. 內(nèi)核判斷initrd的文件格式,如果不是cpio格式,將其作為image-initrd處理。3. 內(nèi)核將initrd的內(nèi)容保存在rootfs下的/initrd.image文件中。4. 內(nèi)核將/initrd.image的內(nèi)容讀入/dev/ram0設(shè)備中,也就是讀入了一個(gè)內(nèi)存盤中。5. 接著內(nèi)核以可讀寫的方式把/dev/ram0設(shè)備掛載為原始的根文件系統(tǒng)。6. .如果/dev/ram0被指定為真正的根文件系統(tǒng),那么內(nèi)核跳至最后一步正常啟動(dòng)。7. 執(zhí)行initrd上的/linuxrc文件,linuxrc通常是一個(gè)腳本文件,負(fù)責(zé)加載內(nèi)核訪問(wèn)根文件系統(tǒng)必須的驅(qū)動(dòng), 以及加載根文件系統(tǒng)。8. /linuxrc執(zhí)行完畢,常規(guī)根文件系統(tǒng)被掛載9. 如果常規(guī)根文件系統(tǒng)存在/initrd目錄,那么/dev/ram0將從/移動(dòng)到/initrd。否則如果/initrd目錄不存在, /dev/ram0將被卸載。10. 在常規(guī)根文件系統(tǒng)上進(jìn)行正常啟動(dòng)過(guò)程 ,執(zhí)行/sbin/init。通過(guò)上面的流程介紹可知,Linux2.6內(nèi)核對(duì)image-initrd的處理流程同linux2.4內(nèi)核相比并沒(méi)有顯著的變化, cpio-initrd的處理流程相比于image-initrd的處理流程卻有很大的區(qū)別,流程非常簡(jiǎn)單,在后面的源代碼分析中,讀者更能體會(huì)到處理的 簡(jiǎn)捷。4.cpio-initrd同image-initrd的區(qū)別與優(yōu)勢(shì)沒(méi)有找到正式的關(guān)于cpio-initrd同image-initrd對(duì)比的文獻(xiàn),根據(jù)筆者的使用體驗(yàn)以及內(nèi)核代碼的分析,總結(jié)出如下三方面的區(qū)別,這些區(qū)別也正是cpio-initrd的優(yōu)勢(shì)所在:cpio-initrd的制作方法更加簡(jiǎn)單cpio-initrd的制作非常簡(jiǎn)單,通過(guò)兩個(gè)命令就可以完成整個(gè)制作過(guò)程#假設(shè)當(dāng)前目錄位于準(zhǔn)備好的initrd文件系統(tǒng)的根目錄下bash# find . cpio -c -o > ../initrd.imgbash# gzip ../initrd.img而傳統(tǒng)initrd的制作過(guò)程比較繁瑣,需要如下六個(gè)步驟#假設(shè)當(dāng)前目錄位于準(zhǔn)備好的initrd文件系統(tǒng)的根目錄下bash# dd if=/dev/zero of=../initrd.img bs=512k count=5bash# mkfs.ext2 -F -m0 ../initrd.imgbash# mount -t ext2 -o loop ../initrd.img
/mntbash# cp -r
* /mntbash# umount /mntbash# gzip -9 ../initrd.img本文不對(duì)上面命令的含義作細(xì)節(jié)的解釋,因?yàn)楸疚闹饕榻B的是linux內(nèi)核對(duì)initrd的處理,對(duì)上面命令不理解的讀者可以參考相關(guān)文檔。cpio-initrd的內(nèi)核處理流程更加簡(jiǎn)化通過(guò)上面initrd處理流程的介紹,cpio-initrd的處理流程顯得格外簡(jiǎn)單,通過(guò)對(duì)比可知cpio-initrd的處理流程在如下兩個(gè)方面得到了簡(jiǎn)化:1. cpio-initrd并沒(méi)有使用額外的ramdisk,而是將其內(nèi)容輸入到rootfs中,其實(shí)rootfs本身也是一個(gè)基于內(nèi)存的文件系統(tǒng)。這樣就省掉了ramdisk的掛載、卸載等步驟。2. cpio-initrd啟動(dòng)完/init進(jìn)程,內(nèi)核的任務(wù)就結(jié)束了,剩下的工作完全交給/init處理;而對(duì)于image-initrd,內(nèi)核在執(zhí)行完 /linuxrc進(jìn)程后,還要進(jìn)行一些收尾工作,并且要負(fù)責(zé)執(zhí)行真正的根文件系統(tǒng)的/sbin/init。通過(guò)圖1可以更加清晰的看出處理流程的區(qū)別:圖1內(nèi)核對(duì)cpio-initrd和image-initrd處理流程示意圖cpio-initrd的職責(zé)更加重要如圖1所示,cpio-initrd不再象image-initrd那樣作為linux內(nèi)核啟動(dòng)的一個(gè)中間步驟,而是作為內(nèi)核啟動(dòng)的終點(diǎn),內(nèi)核將控 制權(quán)交給cpio-initrd的/init文件后,內(nèi)核的任務(wù)就結(jié)束了,所以在/init文件中,我們可以做更多的工作,而不比擔(dān)心同內(nèi)核后續(xù)處理的銜 接問(wèn)題。當(dāng)然目前l(fā)inux發(fā)行版的cpio-initrd的/init文件的內(nèi)容還沒(méi)有本質(zhì)的改變,但是相信initrd職責(zé)的增加一定是一個(gè)趨勢(shì)。Linux init詳解2008-10-19 16:05一、什么是INIT:
init是Linux系統(tǒng)操作中不可缺少的程序之一。
所謂的init進(jìn)程,它是一個(gè)由內(nèi)核啟動(dòng)的用戶級(jí)進(jìn)程。
內(nèi)核自行啟動(dòng)(已經(jīng)被載入內(nèi)存,開(kāi)始運(yùn)行,并已初始化所有的設(shè)備驅(qū)動(dòng)程序和數(shù)據(jù)結(jié)構(gòu)等)之后,就通過(guò)啟動(dòng)一個(gè)用戶級(jí)程序init的方式,完成引導(dǎo)進(jìn)程。所以,init始終是第一個(gè)進(jìn)程(其進(jìn)程編號(hào)始終為1)。
內(nèi)核會(huì)在過(guò)去曾使用過(guò)init的幾個(gè)地方查找它,它的正確位置(對(duì)Linux系統(tǒng)來(lái)說(shuō))是/sbin/init。如果內(nèi)核找不到init,它就會(huì)試著運(yùn)行/bin/sh,如果運(yùn)行失敗,系統(tǒng)的啟動(dòng)也會(huì)失敗。
二、運(yùn)行級(jí)別
那么,到底什么是運(yùn)行級(jí)呢?
簡(jiǎn)單的說(shuō),運(yùn)行級(jí)就是操作系統(tǒng)當(dāng)前正在運(yùn)行的功能級(jí)別。這個(gè)級(jí)別從1到6 ,具有不同的功能。
不同的運(yùn)行級(jí)定義如下:(可以參考Red Hat Linux 里面的/etc/inittab)
# 0 - 停機(jī)(千萬(wàn)不能把initdefault 設(shè)置為0 )
# 1 - 單用戶模式
# 2 - 多用戶,沒(méi)有 NFS
# 3 - 完全多用戶模式(標(biāo)準(zhǔn)的運(yùn)行級(jí))
# 4 - 沒(méi)有用到
# 5 - X11 (xwindow)
# 6 - 重新啟動(dòng) (千萬(wàn)不要把initdefault 設(shè)置為6 )
這些級(jí)別在/etc/inittab 文件里指定。這個(gè)文件是init 程序?qū)ふ业闹饕募钕冗\(yùn)行的服務(wù)是放在/etc/rc.d 目錄下的文件。在大多數(shù)的Linux 發(fā)行版本中,啟動(dòng)腳本都是位于 /etc/rc.d/init.d中的。這些腳本被用ln 命令連接到 /etc/rc.d/rcn.d 目錄。(這里的n 就是運(yùn)行級(jí)0-6)三、運(yùn)行級(jí)別的配置
運(yùn)行級(jí)別的配置是在/etc/inittab行內(nèi)進(jìn)行的,如下所示:
12 : 2 : wait : / etc / init.d / rc 2
第一個(gè)字段是一個(gè)任意指定的標(biāo)簽;
第二個(gè)字段表示這一行適用于運(yùn)行那個(gè)級(jí)別(這里是2);
第三個(gè)字 段表示進(jìn)入運(yùn)行級(jí)別時(shí),init應(yīng)該運(yùn)行第四個(gè)字段內(nèi)的命令一次,而且init應(yīng)該等待該命令結(jié)束。/etc/init.d/rc命令運(yùn)行啟動(dòng)和終止輸入以便進(jìn)入運(yùn)行級(jí)別2時(shí)所需的任何命令。
第四個(gè)字段中的命令執(zhí)行設(shè)置運(yùn)行級(jí)別時(shí)的一切“雜活”。它啟動(dòng)已經(jīng)沒(méi)有運(yùn)行的服務(wù),終止不應(yīng)該再在新運(yùn)行級(jí)別內(nèi)運(yùn)行的服務(wù)。根據(jù)Linux版本的不同,采用的具體命令也不同,而且運(yùn)行級(jí)別的配置也是有差別的。
init啟動(dòng)時(shí),它會(huì)在/etc/inittab內(nèi)查找一個(gè)代碼行,這一行指定了默認(rèn)的運(yùn)行級(jí)別:id : 2 : initdefault :
你可以要求init在啟動(dòng)時(shí),進(jìn)入非默認(rèn)運(yùn)行級(jí)別,這是通過(guò)為內(nèi)核指定一個(gè)“single”或“emergency” 命令行參數(shù)來(lái)實(shí)現(xiàn)的。比如說(shuō),內(nèi)核命令行參數(shù)的指定可通過(guò)LILO來(lái)執(zhí)行。這樣一來(lái),你就可以選擇單用戶模式了(即運(yùn)行級(jí)別1)。
系統(tǒng)正在運(yùn)行時(shí),telinit命令可更改運(yùn)行級(jí)別。運(yùn)行級(jí)別發(fā)生變化時(shí), init 就會(huì)從/etc/inittab運(yùn)行相應(yīng)的命令。
四、/etc/inittab中的特殊配置
/etc/inittab中,有幾個(gè)特殊的特性,允許init重新激活特殊事件。這些特殊特性都是用第三個(gè)字段中的特殊關(guān)鍵字標(biāo)記出來(lái)的。比如:
1. powerwait
允許init在電源被切斷時(shí),關(guān)閉系統(tǒng)。其前提是具有U P S和監(jiān)視U P S并通知init電源已被切斷的軟件。
2. ctrlaltdel
允許init在用戶于控制臺(tái)鍵盤上按下C t r l + A l t + D e l組合鍵時(shí),重新啟動(dòng)系統(tǒng)。注意,如果該系統(tǒng)放在一個(gè)公共場(chǎng)所,系統(tǒng)管理員可將C t r l + A l t + D e l組合鍵配置為別的行為,比如忽略等。3. sysinit
系統(tǒng)啟動(dòng)時(shí)準(zhǔn)備運(yùn)行的命令。比如說(shuō),這個(gè)命令將清除/tmp。
上面列出的特殊關(guān)鍵字尚不完整。其他的關(guān)鍵字及其使用詳情,可參考你的inittab手冊(cè)頁(yè)。
五、在單用戶模式下引導(dǎo)
一個(gè)重要的運(yùn)行級(jí)別就是單用戶模式(運(yùn)行級(jí)別1),該模式中,只有一個(gè)系統(tǒng)管理員使用特定的機(jī)器,而且盡可能少地運(yùn)行系統(tǒng)服務(wù),其中包含登錄。單用戶模式對(duì)少數(shù)管理任務(wù)(比如在/usr分區(qū)上運(yùn)行fsck)而言,是很有必要的,因?yàn)檫@需要卸載分區(qū),但這是不可能的,除非所有的服務(wù)系統(tǒng)已被殺死。
一個(gè)正在運(yùn)行的系統(tǒng)可以進(jìn)入單用戶模式,具體做法是利用init,請(qǐng)求運(yùn)行級(jí)別1。內(nèi)核啟動(dòng)時(shí),在內(nèi)核命令行指定single或emergency關(guān)鍵字,就可進(jìn)入運(yùn)行級(jí)別1了。內(nèi)核同時(shí)也為init指定命令行, init從關(guān)鍵字得知自己不應(yīng)該采用默認(rèn)的運(yùn)行級(jí)別(內(nèi)核命令行的輸入方式和你啟動(dòng)系統(tǒng)的方式有關(guān))。
有時(shí),以單用戶模式進(jìn)行啟動(dòng)是必要的,這樣一來(lái),用戶在裝入分區(qū)之前,或至少在裝入分散的/usr分區(qū)之前,能手工運(yùn)行fsck(在分散的文件系統(tǒng)上,任何活動(dòng)都可能使其更為分散,所以應(yīng)該盡可能地運(yùn)行fsck)。
如果自動(dòng)化的fsck在啟動(dòng)時(shí)失敗了,啟動(dòng)腳本init的運(yùn)行將自動(dòng)進(jìn)入單用戶模式。這樣做是為了防止系統(tǒng)使用不連貫的文件系統(tǒng),這個(gè)文件系統(tǒng)是f s c k不能自動(dòng)修復(fù)的。文件系統(tǒng)不連貫的現(xiàn)象極為少見(jiàn),而且通常會(huì)導(dǎo)致硬盤的不連貫或?qū)嶒?yàn)性的內(nèi)核釋放,但最好能做到防患于未然。
由于安全上的考慮,在單用戶模式下,啟動(dòng)外殼腳本之前,配置得當(dāng)?shù)南到y(tǒng)會(huì)要求用戶提供root密碼。否則,它會(huì)簡(jiǎn)單地為L(zhǎng) I L O輸入合適的一行代碼,以r o o t的身份登錄(當(dāng)然,如果/etc/passwd已經(jīng)由于文件系統(tǒng)的問(wèn)題而不連貫了,就不適合這里的原則了,為對(duì)付這種情況,你最好隨時(shí)準(zhǔn)備一張啟動(dòng)盤)。
不同的運(yùn)行級(jí)有不同的用處,也應(yīng)該根據(jù)自己的不同情形來(lái)設(shè)置。
例如,如果丟失了root口令,那么可以讓機(jī)器啟動(dòng)進(jìn)入單用戶狀態(tài)。在啟動(dòng)后的 lilo提示符下輸入:init=/bin/sh rw 使機(jī)器進(jìn)入運(yùn)行級(jí)1 ,并把 root 文件系統(tǒng)掛為讀寫。他會(huì)跳過(guò)所有系統(tǒng)認(rèn)證,讓你可以使用passwd 程序來(lái)改變r(jià)oot口令,然后啟動(dòng)到一個(gè)新的運(yùn)行級(jí)。
聯(lián)系客服