久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

linux 啟動詳解

 mrjbydd 2011-09-04
linux 啟動詳解
2009-10-29 11:11
機器加電啟動后,BIOS開始檢測參數(shù),如內(nèi)存的大小,日期和時間,磁盤
設(shè)備以及這些磁盤設(shè)備用來引導(dǎo)的順序,通常情況下,,BIOS都是被配置成首先檢查
軟驅(qū)或者光驅(qū)(或兩者都檢查),,然后再嘗試從硬盤引導(dǎo)。如果在這些可移動的設(shè)
備中,,沒有找到可引導(dǎo)的介質(zhì),,那么BIOS通常是轉(zhuǎn)向第一塊硬盤最初的幾個扇區(qū),
尋找用于裝載
操作系統(tǒng)的指令,。裝載操作系統(tǒng)的這個程序就是boot loader.
里面的boot loader通常是lilo或者grub,從RedHatLinux 7.2起,,GRUB(
GRand Unified Bootloader)取代LILO成為了默認(rèn)的啟動裝載程序。那么啟動的時候
grub是如何被載入的呢
grub有幾個重要的文件,stage1,stage2,有的時候需要stage1.5.這些文件一般都
在/boot/grub文件夾下面.grub被載入通常包括以下幾個步驟:
1. 裝載基本的引導(dǎo)裝載程序(stage1),stage1很小,網(wǎng)上說是512字節(jié),但是在我的系統(tǒng)上
   用 du   -b   /boot/grub/stage1 顯示的是1024個字節(jié),不知道是不是grub版本不同的
   緣故還是我理解有誤.stage1通常位于主引導(dǎo)扇區(qū)里面,對于硬盤就是MBR了,stage1的
   主要功能就是裝載第二引導(dǎo)程序(stage2).這主要是歸結(jié)于在主引導(dǎo)扇區(qū)中沒有足夠的
   空間用于其他東西了,我用的是grub 0.93,stage2文件的大小是 107520 bit.
2. 裝載第二引導(dǎo)裝載程序(stage2),這第二引導(dǎo)裝載程序?qū)嶋H上是引出更高級的功能, 
   以允許用戶裝載入一個特定的操作系統(tǒng),。在GRUB中,,這步是讓用戶顯示一個菜單或
   是輸入。由于stage2很大,所以它一般位于文件系統(tǒng)之中(通常是boot所在的根
   分區(qū)).
   上面還提到了stage1.5這個文件,它的作用是什么呢   你到/boot/grub目錄下看看,
fat_stage_1.5   e2fs_stage_1.5 xfs_stage_1.5等等,很容易猜想stage1.5和文件系統(tǒng)
有關(guān)系.有時候基本引導(dǎo)裝載程序(stage1)不能識別stage2所在的文件系統(tǒng)分區(qū),那么這
時候就需要stage1.5來連接stage1和stage2了.因此對于不同的文件系統(tǒng)就會有不同的
stage1.5.但是對于grub 0.93好像stage1.5并不是很重要,因為我試過了,在沒有stage1.5
的情況下, 我把stage1安裝在軟盤的引導(dǎo)扇區(qū)內(nèi),然后把stage2放在格式化成ext2或者
fat格式的軟盤內(nèi),啟動的時候照常引導(dǎo),并不需要e2fs_stage_1.5或者fat_stage_1.5.
下面是我的試驗:
#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這幾個啟動的
時候必須的文件拷貝到軟盤的指定目錄下.下面安裝grub到軟盤上.
#grub   (進(jìn)入grub環(huán)境)
grub> install (fd0)/boot/grub/stage1 (fd0)   (fd0)/boot/grub/stage2
p (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這個文件所在的位置.
p 參數(shù)后面跟著(fd0)/boot/grub/grub.conf 告訴grub的配置文件所在的位置.
好了,讓BIOS從軟驅(qū)啟動,試一下,沒有e2fs_stage_1.5文件照樣能夠進(jìn)入系統(tǒng).
其實這就是一個小小的啟動盤啊.(了解了grub的運行
,就簡單多了^_^)

   3. 現(xiàn)在我們已經(jīng)到grub的開機選單這一步了,接下來grub所需要做的就是裝載在一個特
定分區(qū)上的操作系統(tǒng),,如linux內(nèi)核,。一旦GRUB從它的命令行或者配置文件中,接到開始
操作系統(tǒng)的正確指令,,它就尋找必要的引導(dǎo)文件,,然后把機器的控制權(quán)移交給操作系統(tǒng).
    由于篇幅有限,避免冗長,grub的命令我就不多說了,網(wǎng)上很有多的
資料,一個典型
完整的引導(dǎo)linux的命令如下:
    title 51base
          root(hd0,0)
          kernel /bzImage   ro   root=/dev/ram0
          initrd /initrd.img
    這里有必要注意一下幾個問題:
    (1)grub的磁盤以及分區(qū)的命名方式和linux有所區(qū)別,第一個磁盤是從0開始,第一
個分區(qū)也是從0開始.譬如第一個硬盤的第5分區(qū)在linux下面是/dev/hda5 ,而在grub里面
是(hd0,4).再如/dev/fd0在grub里面是(fd0,0).(最后一句如有錯誤望提醒)
    (2)不管是IDE硬盤hda,hdb還是SCSI硬盤sda,sdb在grub里面都是以hd方式命名.
譬如虛擬機里面的/dev/sda2在grub里面是(hd0,1),再如/dev/hdb7在grub里面以(hd1,6)
命名.
    (3)要搞清楚上面兩個root的關(guān)系,root (hd0,0)中的root是grub命令,它用來指定
boot所在的分區(qū)作為grub的根目錄.而root=/dev/ram0是kernel的參數(shù),它告訴操作系統(tǒng)
內(nèi)核加載完畢之后,真實的文件系統(tǒng)所在的設(shè)備.要注意grub的根目錄和文件系統(tǒng)的根
目錄的區(qū)別.
    再回到上面的幾行命令.
    kernel命令用來指定內(nèi)核所在的位置,"/"代表(hd0,0),也就是grub的根目錄
    initrd命令用來指定初始化ram的img文件所在位置.

grub載入內(nèi)核bzImage并展開到指定位置(應(yīng)該是0x100000這個地方),同時載入
initrd.img到內(nèi)存(不知道是什么地方).
ps:
grub的任務(wù)至此就結(jié)束了,下面grub將機器的控制權(quán)轉(zhuǎn)交給操作系統(tǒng)(linux).
操作系統(tǒng)接到控制權(quán)之后,開始start_kernel,接著內(nèi)核將initrd.img展開到/dev/ram0
為臨時根文件系統(tǒng),執(zhí)行里面的linuxrc文件.
P.這里有必要說一下initrd的作用特別是它里面的核心文件linuxrc的作用.
initrd是inital ram disk的宿寫.
當(dāng)存在initrd的時候,機器啟動的過程大概是以下幾個步驟(當(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拿出來分析一下.
這其實是一個壓縮了的文件,是以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]#ls
bin dev etc lib linuxrc loopfs   proc sbin sysroot
[root@localhost ram]#ls bin
insmod modprobe nash
[root@localhost ram]#ls lib
Buslogic.o   ext3.o   jbd.o   scsi_mod.o sd_mod.o
[root@localhost ram]ls   dev
console   null   ram   systty   tty1   tty2   tty3   tty4
sbin目錄是指向bin目錄的一個連接,其他目錄是空的.
[root@localhost ram]cat   linuxrc
#!/bin/nash
1.echo "Loading scsi_mod.o module"
2.insmod /lib/scsi_mod.o
3.echo "Loading sd_mod.o module"
4.insmod /lib/sd_mod.o
5.echo "Loading BusLogic.o module"
6.insmod /lib/BusLogic.o
7.echo "Loading jbd.o module"
8.insmod /lib/jbd.o
9.echo "Loading ext3.o module"
10.insmod /lib/ext3.o
11.echo Mounting /proc filesystem
12.mount -t proc /proc /proc
13.echo Creating block devices
14.mkdevices /dev
15.echo Creating root device
16.mkrootdev /dev/root
17.echo 0x0100 > /proc/sys/kernel/real-root-dev
18.echo Mounting root filesystem
19.mount -o defaults --ro -t ext3 /dev/root /sysroot
20.pivot_root /sysroot /sysroot/initrd
21.umount /initrd/proc
上面的編號是我為了下面好說明加上去的.
首先我們必須注意的是這里使用的shell是nash而不是bash,nash是專門為linuxrc可執(zhí)行
腳本設(shè)計的,因此你有必要看一看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成
為一個塊節(jié)點從而使得根分區(qū)設(shè)備被掛載,其中根分區(qū)設(shè)備由grub.conf里面的kernel命
令后面所帶的參數(shù)root=決定,如果root=參數(shù)沒有被指定,/proc/sys/kernel/real-root-
dev文件將提供根分區(qū)設(shè)備號.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/Documenta
tion/initrd.txt文檔)
2)/linuxrc文件決定在掛載真正的文件系統(tǒng)之前所需完成的事情(譬如加載必要的網(wǎng)
絡(luò)驅(qū)動或者加載ext3文件系統(tǒng)).
3)/linuxrc加載必要的模塊.
4)/linuxrc掛載根文件系統(tǒng)
5)/linuxrc調(diào)用pivot_root來改變根目錄
關(guān)于initrd的用途可以查考上面提到的文檔,想知道linux系統(tǒng)是如何安裝的嗎 那里
面由答案.
既然linuxrc的主要目的是加載??煊玫?那如果我們的內(nèi)核沒有動態(tài)的模塊而所需
的功能都是靜態(tài)編譯進(jìn)內(nèi)核的,那么是不是可以不用linuxrc文件呢
答案是可以不用,在普通的linux操作系統(tǒng)里面可以加入noinitrd選項以告知boot
loader 不使用initrd.如果我們做網(wǎng)關(guān),因為ram是我們的文件系統(tǒng)的載體,所以initrd
一行當(dāng)然不能去掉,但是我們可以不用linuxrc文件,sysroot文件夾和initrd文件夾.
不信的話,試試看吧.
好了,initrd(linuxrc)已經(jīng)介紹完了.
linuxrc執(zhí)行完畢之后,系統(tǒng)就會以真正的根目錄正式init.
系統(tǒng)在/bin/或者/sbin目錄下找到init程式,然后根據(jù)它的配置文件/etc/fstab進(jìn)行
初始化,最后調(diào)用mingetty程式啟動login完成引導(dǎo).
    ps:init這一部分網(wǎng)上有很多的詳細(xì)資料所以我在這里并沒有展開來說.

關(guān)于linux的啟動流程的筆記

一,、從哪里到哪里
本文旨在描述linux中內(nèi)核如何調(diào)用啟動,然后如何從img的文件系統(tǒng)切換到硬盤的過程,。
描述起于:linux-2.6.11/init/main.c中函數(shù) static int init(void * unused)
描述止于:/etc/rc.d/rc.sysinit文件的被調(diào)用

二,、描寫流程
在linux代碼linux-2.6.11/init/main.c中init這個函數(shù)被調(diào)用時,,初始啟動的文件
系統(tǒng)鏡像:/boot/initrd-2.6.11.12.img(以2.6.11.12內(nèi)核為例)已被grub加載到
內(nèi)存中,并已掛載到根目錄上("/"),。


1,、我們先來看看initrd-2.6.11.12.img到底是個什么東西:
[root@wj-server1 tmp]# cd /tmp
[root@wj-server1 tmp]# cp /boot/initrd-2.6.11.12.img /tmp/initrd-2.6.11.12.gz
[root@wj-server1 tmp]# gunzip initrd-2.6.11.12.gz
解壓縮后的文件為:
[root@wj-server1 tmp]# ls -l initrd-2.6.11.12
-rw-r--r--   1 root root 846848   7月 31 17:01 initrd-2.6.11.12
是一個CPIO格式的文件,該文件格式是種文件鏡像讓我們將它解開到一個目錄中看看
其中的具體內(nèi)容:
[root@wj-server1 tmp]# mkdir initrd
[root@wj-server1 tmp]# cd initrd
[root@wj-server1 initrd]# cpio -i < ../initrd-2.6.11.12
1654 blocks
[root@wj-server1 initrd]# ls
bin   bootsplash   dev   etc   init   lib   loopfs   proc   sbin   sys   sysroot
[root@wj-server1 initrd]# find .
.
./lib
./bin
./bin/nash
./bin/insmod
./bin/modprobe
./bin/hotplug
./etc
./dev
./dev/console
./dev/null
./dev/ram
./dev/systty
./dev/tty1
./dev/tty2
./dev/tty3
./dev/tty4
./loopfs
./proc
./sys
./sysroot
./sbin
./init
./bootsplash

可見該鏡像文件目錄中包括:

/bin 目錄下的四個用于啟動和切換到硬盤上的程序:
nash(用于處理根目錄下的/init腳本),、insmod和modprobe來加載內(nèi)核驅(qū)動,、hotplug用
于外設(shè)的拔插處理。

/dev 目錄下的八個設(shè)備文件

/init 是個nash的啟動腳本文件

/bootsplash 是內(nèi)核打了bootsplash補丁后,,會在對該文件進(jìn)行讀取操作,,然后將該文件
中包含的圖片文件在啟動時顯示。
[root@wj-server1 initrd]# dmesg | grep -i bootsplash
bootsplash 3.1.6-2004/03/31: looking for picture... silentjpeg size 36270 bytes,
...found (1024x768, 19600 bytes, v3).
內(nèi)核的這個裝載信息就是在處理該文件,。(具體的bootsplash的使用和創(chuàng)建這里不細(xì)說),。

附:CPIO文件的打包
[root@wj-server1 initrd]# cd /tmp/initrd
[root@wj-server1 initrd]# rm ../initrd-2.6.11.12
[root@wj-server1 initrd]# find . | cpio -c -o > ../initrd-2.6.11.12
1654 blocks
[root@wj-server1 initrd]# gzip ../initrd-2.6.11.12
[root@wj-server1 initrd]# mv ../initrd-2.6.11.12.gz ../initrd-2.6.11.12.img


2、回到內(nèi)核init函數(shù)中,,看看如何調(diào)用/boot/initrd-2.6.11.12.img中/init腳本的
....
// 這里判斷在grub裝載的/boot/initrd-2.6.11.12.img中是否有"/init"這個文件,?
if (sys_access((const char __user *) "/init", 0) == 0)
execute_command = "/init"
else
....
// 如果有"/init"這個文件就先運行它。
if (execute_command)
run_init_process(execute_command);

run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

panic("No init found. Try passing init= option to kernel");

由代碼我們看到kernel會先判斷并運行/boot/initrd-2.6.11.12.img中的/init文件,,我們
來看看該/boot/initrd-2.6.11.12.img/init文件的內(nèi)容,,我們上面已將該文件展開到目錄
/tmp/initrd中:
[root@wj-server1 initrd]# cat ./init
#!/bin/nash     # 該文件是個nash的腳本文件

# 掛接proc文件系統(tǒng)
mount -t proc /proc /proc

# 不輸出nash調(diào)試信息,由/proc/cmdline決定,cat /proc/cmdline我的啟動參數(shù)
# 輸出ro root=/dev/hda3 vga=791 splash=silent,,如果該命令行中帶了quiet參
# 數(shù),,則不輸出nash提示信息。
setquiet

# 提示信息(這里提示因該放到上面去,,mkinitrd-4.2.17-2mgc.rpm包中原來如是,,
# 筆誤?為什么這里牽涉到mkinitrd這個包類,?因為:/boot/initrd-2.6.11.12.img
# 文件由下面命令生成:mkinitrd /boot/initrd-2.6.11.12.img 2.6.11.12)
echo Mounted /proc filesystem

# 掛接sys文件系統(tǒng)
echo Mounting sysfs
mount -t sysfs /sys /sys

# 創(chuàng)建/dev臨時目錄
echo Creating /dev
mount -o mode=0755 -t tmpfs /dev /dev

# 創(chuàng)建設(shè)備文件(這些設(shè)備文件在切換到硬盤后,,由/etc/rc.sysinit中start_udev
# 重新創(chuàng)建)
mknod /dev/console c 5 1
mknod /dev/null c 1 3
mknod /dev/zero c 1 5

# 新建偽終端目錄
mkdir /dev/pts
# 新建共享內(nèi)存目錄
mkdir /dev/shm

# 這里是調(diào)用的nash中的makedevs指令裝載硬盤等塊設(shè)備,不裝載其他設(shè)備只裝載
# 硬盤等塊設(shè)備
echo Starting udev
# 告訴內(nèi)核當(dāng)發(fā)現(xiàn)新拔插設(shè)備時用"/sbin/hotplug"程序來處理
echo -n "/sbin/hotplug" > /proc/sys/kernel/hotplug
makedevs
makedevs # 這里多搞一次沒必要

echo Creating root device
# 由grub啟動命令行root=/dev/hda3來聯(lián)接設(shè)備/dev/root到root變量所指定的啟動
# 設(shè)備,,見下面我的grub啟動參數(shù):
# kernel /boot/vmlinuz-2.6.11.12   ro root=/dev/hda3 vga=791 splash=silent
mkrootdev /dev/root

# 掛接/dev/root目錄
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot

echo Switching to new root
# 切換根目錄到設(shè)備/dev/root目錄,運行完該命令根目錄"/"->"/dev/hda3"
switchroot --movedev /sysroot



由上面的注釋我們大概能夠明白./init腳本的基本運行流程:
a,、裝載基本的內(nèi)核系統(tǒng)文件和設(shè)備文件
b,、根據(jù)grub的啟動命令行參數(shù),判斷root根文件設(shè)備,,參看/boot/grub/grub.conf文件中制定
的參數(shù),,該參數(shù)在內(nèi)核啟動后可有cat /proc/cmdline顯示出來,nash和其他的一些程序也是通
過讀該系統(tǒng)文件來去內(nèi)核啟動參數(shù)的,。
c,、在將從grub啟動參數(shù)中獲得根設(shè)備并將其與/dev/root設(shè)備聯(lián)接以后,,通過nash的switchroot
指令將/dev/root設(shè)備掛接到根目錄上("/")

看看這樣操作后,留下的痕跡:
[root@wj-server1 initrd]# ls -l /dev/root
lrwxrwxrwx   1 root root 9   7月 31 12:06 /dev/root -> /dev/hda3
[root@wj-server1 initrd]# mount
/dev/hda3 on / type ext3 (rw)

到此為止,,已將硬盤設(shè)備裝載到根目錄下了,,從而取代了原來有initrd.img文件的根位置。



3,、再回頭看看內(nèi)核中main.c中init函數(shù),,看看如何調(diào)用/sbin/init處理/etc/inittab文件
....
// 如果有"/init"這個文件就先運行它。
if (execute_command)
run_init_process(execute_command);

run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

panic("No init found. Try passing init= option to kernel");

我們已經(jīng)運行完run_init_process(execute_command);這里了,,然后繼續(xù)運行:
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");

/sbin/init這個文件在SysVinit-2.85-34mgc.rpm這個包中,,該程序的主要處理代碼在文件:
sysvinit-2.85/src/init.c中,該文件主要查找和處理/etc/inittab文件,,按照該文件的內(nèi)容
依次做處理,。

[root@wj-server1 initrd]# cat /etc/inittab
#
# inittab    This file describes how the INIT process should set up
#             the system in a certain run-level.
#
# Author:    Miquel van Smoorenburg, <[email protected]>
#             Modified for RHS Linux by Marc Ewing and Donnie Barnes
#

# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:5:initdefault:                         # /sbin/init 根據(jù)這里判斷啟動的級別

# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit          # /sbin/init 會最先運行這個系統(tǒng)配置文件

l0:0:wait:/etc/rc.d/rc 0                    # /sbin/init 根據(jù)上面取得的級別運行相應(yīng)
l1:1:wait:/etc/rc.d/rc 1                    # 目錄下的啟動腳本
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6

# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now # 設(shè)置關(guān)機熱鍵

# When our UPS tells us power has failed, assume we have a few minutes
# of power left.   Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"

# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"


# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1       # 建立6個登陸控制終端可以通過CTRL-ALT-F?
2:2345:respawn:/sbin/mingetty tty2       # 切換,'?'表示第幾個登陸控制臺,,比如第1
3:2345:respawn:/sbin/mingetty tty3       # 個為F1,,第2個為F2依次類推。F7為X11控制
4:2345:respawn:/sbin/mingetty tty4       # 臺,,后面就沒有了,,所以在X下可以很靈活
5:2345:respawn:/sbin/mingetty tty5       # 的切換到控制臺下面操作。
6:2345:respawn:/sbin/mingetty tty6

# Run xdm in runlevel 5
x:5nce:/etc/X11/prefdm -nodaemon

通過內(nèi)核中對/sbin/init的調(diào)用現(xiàn)在已經(jīng)執(zhí)行/etc/rc.d/rc.sysinit操作了,。

又記當(dāng)magiclinux中initscripts因為hal升級后bootsplash無法顯示滾動條,,
將[ -x /sbin/start_udev ] && /sbin/start_udev提到startanimate之前,
就可以了,,向這樣:
[ -x /sbin/start_udev ] && /sbin/start_udev

# Graphical bootup...
if [ "$BOOTUP" = "graphical" ]; then
if [ -w /proc/splash -a -e /proc/fb ]; then
   # Initialize bootsplash
   # TODO: Find out runlevel (-> number of startup scripts -> number of steps)
   runlevel=5
   export kscripts=`/bin/ls /etc/rc.d/rc$runlevel.d/K* |/usr/bin/wc |/bin/awk '{ print $1 }'`
   export sscripts=`/bin/ls /etc/rc.d/rc$runlevel.d/S* |/usr/bin/wc |/bin/awk '{ print $1 }'`
   export progress=1
   # HACK: count rc.sysinit stuff as startup scripts...
   sscripts=$(( $sscripts + 19 ))
   startanimate # start the animate
else
   # Kernel doesn't have bootsplash support --> switch to text
   export BOOTUP=color
fi
fi
一直以來,,都認(rèn)為nash僅僅是作為initrd.img當(dāng)中加載驅(qū)動所使用的命令解釋器而已,并沒有對initrd.img當(dāng)中的linuxrc腳本作一個深入的了解,。例如,,Redhat ES3當(dāng)中的initrd.img內(nèi)容(各系統(tǒng)略有不同)如下:

#!/bin/nash
echo "Loading scsi_mod.o module"
insmod /lib/scsi_mod.o
echo "Loading sd_mod.o module"
insmod /lib/sd_mod.o
echo "Loading libata.o module"
insmod /lib/libata.o
echo "Loading ata_piix.o module"
insmod /lib/ata_piix.o
echo "Loading jbd.o module"
insmod /lib/jbd.o
echo "Loading ext3.o module"
insmod /lib/ext3.o
echo Mounting /proc filesystem
mount -t proc /proc /proc
echo Creating block devices
mkdevices /dev
echo Creating root device
mkrootdev /dev/root
echo 0x0100 > /proc/sys/kernel/real-root-dev
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
pivot_root /sysroot /sysroot/initrd
umount /initrd/proc

    前面是加載驅(qū)動部分,而后面是什么用處,,就沒有深究了,。而我自己用的虛擬機里通常會把驅(qū)動和文件系統(tǒng)支持編譯到內(nèi)核,也壓根用不著initrd.img,,所以把這個寶礦放了過去,。今天幾個學(xué)生在Redhat 9的基礎(chǔ)上升級內(nèi)核到2.6.19,并且是驅(qū)動,、文件系統(tǒng)用模塊方式支持,,終于出了問題。該來的還是要來的,,應(yīng)了那句話“出來混,,遲早都是要還的”,。學(xué)生們把前面的硬盤驅(qū)動、文件系統(tǒng)驅(qū)動都替換成2.6的模塊,,后半部分在我的誤導(dǎo)下刪除(當(dāng)然沒有刪除的也多半沒有成功),,結(jié)果死活不能進(jìn)入系統(tǒng),報無法掛載根文件系統(tǒng)的kernel panic錯誤,。查了半天,,發(fā)現(xiàn)所有的驅(qū)動都加載正常,即便是在linuxrc當(dāng)中加入bash獲得一個shell,,檢查設(shè)備和文件系統(tǒng)的狀況也都是正常,,可就是提示找不到根文件系統(tǒng)。
    開始引起我注意的是,,通常在硬盤驅(qū)動和文件系統(tǒng)支持都完備的情況下它并沒有提示說VFS的root=xxxx錯誤,,而直接提示的“VFS: Unable to mount root fs on (0, 0)”。這意味著它并未識別在grub.conf當(dāng)中傳遞給kernel的root=/dev/xxx參數(shù),,因為Linux的設(shè)備主設(shè)備號是不會為0的,。我曾懷疑root=參數(shù)沒有被接受,但卻注意到“Please append a correct "root=" boot option”的提示,。
    為了找出問題,,我在linuxrc中用bash取得了一個shell,然后掛載proc文件系統(tǒng)后檢查/proc/sys/kernel/real_root_dev,,發(fā)現(xiàn)其值為0,。這說明kernel得到的真實root文件系統(tǒng)的設(shè)備號不正確(當(dāng)然有例外,注意后面的解釋),。我試著把正確的設(shè)備值(例如/dev/sda2用0x802)寫入,,退出bash之后啟動果然正常了。這說明kernel解析參數(shù)root=/dev/xxx出現(xiàn)了錯誤,。
    經(jīng)過核對內(nèi)核代碼,,發(fā)現(xiàn)kernel確實從root=這個參數(shù)傳遞中獲得真實的根文件系統(tǒng)的位置,但是這些/dev/xxx會被轉(zhuǎn)換成內(nèi)核可識別的設(shè)備表示形式,。轉(zhuǎn)換的過程中內(nèi)核會試圖檢查傳遞進(jìn)來的/dev/xxx設(shè)備是否存在,,而這一步是kernel初始化過程中完成的。當(dāng)我們把硬盤驅(qū)動編譯為模塊時,,kernel初始化過程中硬盤尚不能被識別(要等到kernel初始化完,,使用initrd.img才能加載硬盤驅(qū)動),于是真實根文件系統(tǒng)的設(shè)備號就不能被正確轉(zhuǎn)換,,使得其保留為初始值0。
    那對于使用硬盤驅(qū)動的情況下如何解決這個問題呢,?那就是initrd.img后半部分的工作,。在加載完硬盤驅(qū)動后,,腳本會用mkrootdev生成設(shè)備/dev/root,通過man nash你會發(fā)現(xiàn)這個命令的作用是根據(jù)內(nèi)核傳遞參數(shù)當(dāng)中的root=來創(chuàng)建對應(yīng)該設(shè)備的節(jié)點,,節(jié)點名就是/dev/root,。之后它會把這個設(shè)備掛載到/sysroot這個位置,然后用pivot_root這個根交換的命令把真正運行的根文件系統(tǒng)切換到/sysroot之下,,而運行l(wèi)inuxrc的initrd的文件系統(tǒng)將被掛載到真正的根系統(tǒng)下的initrd目錄,。至于“echo 0x0100 > /proc/sys/kernel/real-root-dev”這個命令,看起來是告訴內(nèi)核真正的文件系統(tǒng)是/dev/ram0,,其實是利用內(nèi)核判斷使用/dev/ram0為根文件系統(tǒng)時不再mount其他設(shè)備作為根文件系統(tǒng)的分支,,作了一個小小的技巧騙過內(nèi)核。
    整個腳本的關(guān)鍵在于mkrootdev這個命令,。它不僅能夠根據(jù)root=/dev/xxx來生成對應(yīng)的設(shè)備節(jié)點,,還能夠在碰到root=LABEL=/的情況下探測所有的硬盤分區(qū),以便找到對應(yīng)著卷標(biāo)為/的分區(qū),。這也解開了我一直沒弄清楚的為什么root=LABEL=xxx的參數(shù)有些環(huán)境可以用而有些卻不行的謎團(tuán),。這個LABEL=/的解析根本不是內(nèi)核完成的,而是initrd.img當(dāng)中l(wèi)inuxrc腳本的mkrootdev命令來完成的,。腳本的第二個關(guān)鍵在于它負(fù)責(zé)完成了本是由內(nèi)核做的掛載真實根文件系統(tǒng)的動作,,并對當(dāng)前根(即initrd使用的內(nèi)存文件系統(tǒng))和真實根文件系統(tǒng)進(jìn)行根切換,又利用欺騙讓內(nèi)核誤認(rèn)為當(dāng)前使用/dev/ram0作為根文件系統(tǒng)可以不再掛載真實的根文件系統(tǒng),,可謂用心良苦啊 ^_^
    當(dāng)然,,如果完全不用initrd.img的機制,你會發(fā)現(xiàn)/proc/sys/kernel/real_root_dev的值也是0,。這并不是內(nèi)核也弄錯了,,而是只有在使用initrd.img機制時,real_root_dev才反映了內(nèi)核中記錄的真實根文件系統(tǒng)的值,,雖然它不一定準(zhǔn)確,。

    最后,總結(jié)一下:
1,、當(dāng)硬盤驅(qū)動以模塊形式提供時root=xxx傳遞給內(nèi)核的參數(shù)可能不會直接起作用,,內(nèi)核在檢查這個參數(shù)時可能會發(fā)現(xiàn)這個設(shè)備(因為沒有加載驅(qū)動而)不存在,因此導(dǎo)致內(nèi)核沒有接受root=xxx的參數(shù),。
2,、在這種情況下,initrd.img機制的作用不單單是加載驅(qū)動這么簡單,,還肩負(fù)著把正確的真實根的設(shè)備位置告知內(nèi)核的艱巨任務(wù),。不過實現(xiàn)的方法有兩種:
2.1 把正確的根設(shè)備號寫入/proc/sys/kernel/real_root_dev,或者
2.2 自己掛載真正的根設(shè)備,,并進(jìn)行根交換把根系統(tǒng)切換到真實的根系統(tǒng)上,,還要阻止內(nèi)核去掛載它認(rèn)為的真實根系統(tǒng)
對于2.2,,掛載真正的根系統(tǒng)用nash解釋器的內(nèi)置命令mkrootdev完成,它可以根據(jù)傳遞給kernel的參數(shù)(估計讀了/proc/cmdline)獲得/dev/xxx的字符串,,或者得到LABEL=xxx的字符串后查詢各個分區(qū)的卷標(biāo)來得到對應(yīng)的真實根設(shè)備號,。
3、如果沒有使用initrd.img的機制,,/proc/sys/kernel/real_root_dev的值沒有任何處理,,因為它只有在調(diào)用initrd.img的時候才會被同步于內(nèi)核中的操作對象。

    另外,,redhat 9所帶的nash解釋器(版本3.4.42)在處理mkrootdev的流程上是有bug的,。如果傳給kernel的參數(shù)使用root=/dev/xxx的形式,那么nash會從/proc/sys/kernel/real_root_dev里獲取用戶想使用的真實根文件系統(tǒng)位置,,顯然這在我們上面的分析當(dāng)中是0,,也就是錯誤的;而如果參數(shù)傳遞是root=LABEL=/的形式,,那么nash的處理走的另外一個分支,,它會通過解析所有分區(qū)的卷標(biāo)來查找所要的真實根文件系統(tǒng),并不再查詢/proc/sys/kernel/real_root_dev,,這倒讓我們可以得到正確的結(jié)果,。bug呀bug。
    不過FC6所帶的nash 5.1.19已經(jīng)完全不是這個流程了,,應(yīng)當(dāng)不存在這樣的bug,。

本人,聽網(wǎng)上視頻的簡單筆記:

Linux 啟動詳解
1. BIOS 自檢,,根據(jù)BIOS的設(shè)置順序,,如以什么方式硬盤引導(dǎo),軟驅(qū)引導(dǎo)看系統(tǒng)是以什么方式引導(dǎo),,內(nèi)存地

址是從oxfff0開始
對硬件設(shè)備進(jìn)行初媽始化,。
如果是硬盤引導(dǎo),MBR(512字節(jié)的一扇區(qū)),,是磁盤的在0柱面的第一個扇區(qū),。

2.啟動grub, 或lilo,都屬于引導(dǎo)加載程序,都是在linux下的,。
主要區(qū)別:
lilo,沒有交互命令界面,,grub有。
lilo,不支持網(wǎng)絡(luò)引導(dǎo),,grub支持,。

    加密grub:
1)用加密工具:
   /sbin/grub-md5-crypt 用來給grub加密
2)修改/etc/grub.conf 文件
title前加入一行 password: --md5 +已經(jīng)MD5的字符串

3.加載內(nèi)核,linux內(nèi)核影像會被加載到內(nèi)存
加載特定的內(nèi)核,可以用kernel / +tab鍵
kernel /initrd/initrd+tab鍵自動補齊

4.執(zhí)行init 進(jìn)程,,是所有進(jìn)程的發(fā)起者與控制者,,pid號為1,第一個運行的進(jìn)程。
  作用:
1). 是所有進(jìn)程父進(jìn)程
2). 進(jìn)入運行某個特定級別的進(jìn)程程序,,對某個進(jìn)程級別進(jìn)行管理。
  ---- ps -ef 列出所有在執(zhí)行的進(jìn)程
   PPID 指進(jìn)程的父進(jìn)程
  
5. 通過inittab文件進(jìn)行系統(tǒng)的初始化
1)id:3:initdefault:
運行級別:0:關(guān)閉,;
         1:單用戶模式,;
    2:多用戶模式,但不允許使用網(wǎng)絡(luò)
    3:多用戶模式,,允許使用網(wǎng)絡(luò) 
    4:用戶可以自定義級別 
    5:圖形界面,,允許使用網(wǎng)絡(luò)
    6:重新啟動
2)si:sysinit:/etc/rc.d/rc.sysinit 作用很多,如下一博客 /etc/rc.d/rc.sysinit的作用
 
    cd /etc/rc.d/rc3.d
  
   首先結(jié)束k開頭的K(ill),,然后開始s(tart)開頭的,,并是按s后接的數(shù)字大小來決定哪個先開啟
3) 執(zhí)行/etc/rc.d/rc.local文件
4)執(zhí)行l(wèi)ogin程序

 

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多