linux grub 引導啓動過程詳解

     機器加電啓動後,BIOS開始檢測系統參數,如內存的大小,日期和時間,磁盤
設備以及這些磁盤設備用來引導的順序,通常情況下,BIOS都是被配置成首先檢查
軟驅或者光驅(或兩者都檢查),然後再嘗試從硬盤引導。如果在這些可移動的設
備中,沒有找到可引導的介質,那麼BIOS通常是轉向第一塊硬盤最初的幾個扇區,
尋找用於裝載操作系統的指令。裝載操作系統的這個程序就是boot loader.
    linux裏面的boot loader通常是lilo或者grub,從Red Hat Linux 7.2起,GRUB(
GRand Unified Bootloader)取代LILO成爲了默認的啓動裝載程序。那麼啓動的時候
grub是如何被載入的呢
    grub有幾個重要的文件,stage1,stage2,有的時候需要stage1.5.這些文件一般都
在/boot/grub文件夾下面.grub被載入通常包括以下幾個步驟:
1. 裝載基本的引導裝載程序(stage1),stage1很小,網上說是512字節,但是在我的系統上
  用 du  -b  /boot/grub/stage1 顯示的是1024個字節,不知道是不是grub版本不同的
  緣故還是我理解有誤.stage1通常位於主引導扇區裏面,對於硬盤就是MBR了,stage1的
  主要功能就是裝載第二引導程序(stage2).這主要是歸結於在主引導扇區中沒有足夠的
  空間用於其他東西了,我用的是grub 0.93,stage2文件的大小是 107520 bit.
2. 裝載第二引導裝載程序(stage2),這第二引導裝載程序實際上是引出更高級的功能, 
  以允許用戶裝載入一個特定的操作系統。在GRUB中,這步是讓用戶顯示一個菜單或
  是輸入命令。由於stage2很大,所以它一般位於文件系統之中(通常是boot所在的根
  分區).
  上面還提到了stage1.5這個文件,它的作用是什麼呢  你到/boot/grub目錄下看看,
fat_stage_1.5  e2fs_stage_1.5 xfs_stage_1.5等等,很容易猜想stage1.5和文件系統
有關係.有時候基本引導裝載程序(stage1)不能識別stage2所在的文件系統分區,那麼這
時候就需要stage1.5來連接stage1和stage2了.因此對於不同的文件系統就會有不同的
stage1.5.但是對於grub 0.93好像stage1.5並不是很重要,因爲我試過了,在沒有stage1.5
的情況下, 我把stage1安裝在軟盤的引導扇區內,然後把stage2放在格式化成ext2或者
fat格式的軟盤內,啓動的時候照常引導,並不需要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  (進入grub環境)
   grub> install (fd0)/boot/grub/stage1 (fd0)  (fd0)/boot/grub/stage2
p (fd0)/boot/grub/grub.conf
   以上這條命令也可以用下面的兩句代替
   grub>root (fd0)    #grub的根目錄所在的分區
   grub>setup (fd0)   #這一步就相當於上面的install命令
   我在這裏解釋一下
    install (fd0)/boot/grub/stage1 (fd0)  (fd0)/boot/grub/stage2 p
(fd0)/boot/grub/grub.conf 這條命令.
install
   告訴GRUB將(fd0)/boot/grub/grub/stage1
   安裝到軟驅的引導扇區(fd0).
(fd0)/boot/grub/stage2
   告訴grub stage2這個文件所在的位置.
p 參數後面跟着(fd0)/boot/grub/grub.conf 告訴grub的配置文件所在的位置.
    好了,讓BIOS從軟驅啓動,試一下,沒有e2fs_stage_1.5文件照樣能夠進入系統.
其實這就是一個小小的啓動盤啊.(瞭解了grub的運行原理,就簡單多了^_^)
  3. 現在我們已經到grub的開機選單這一步了,接下來grub所需要做的就是裝載在一個特
定分區上的操作系統,如linux內核。一旦GRUB從它的命令行或者配置文件中,接到開始
操作系統的正確指令,它就尋找必要的引導文件,然後把機器的控制權移交給操作系統.
     由於篇幅有限,避免冗長,grub的命令我就不多說了,網上很有多的資料,一個典型
完整的引導linux的命令如下:
     title 51base
           root(hd0,0)
           kernel /bzImage  ro  root=/dev/ram0
           initrd /initrd.img
     這裏有必要注意一下幾個問題:
     (1)grub的磁盤以及分區的命名方式和linux有所區別,第一個磁盤是從0開始,第一
個分區也是從0開始.譬如第一個硬盤的第5分區在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的關係,root (hd0,0)中的root是grub命令,它用來指定
boot所在的分區作爲grub的根目錄.而root=/dev/ram0是kernel的參數,它告訴操作系統
內核加載完畢之後,真實的文件系統所在的設備.要注意grub的根目錄和文件系統的根
目錄的區別.
     再回到上面的幾行命令.
     kernel命令用來指定內核所在的位置,"/"代表(hd0,0),也就是grub的根目錄
     initrd命令用來指定初始化ram的img文件所在位置.
    grub載入內核bzImage並展開到指定位置(應該是0x100000這個地方),同時載入
initrd.img到內存(不知道是什麼地方).
ps:
    grub的任務至此就結束了,下面grub將機器的控制權轉交給操作系統(linux).
   操作系統接到控制權之後,開始start_kernel,接着內核將initrd.img展開到/dev/ram0
爲臨時根文件系統,執行裏面的linuxrc文件.
    P.這裏有必要說一下initrd的作用特別是它裏面的核心文件linuxrc的作用.
   initrd是inital ram disk的宿寫.
   當存在initrd的時候,機器啓動的過程大概是以下幾個步驟(當initrd這一行用
noinitrd 命令代替後,就不存在initrd了)
    1)boot loader(grub)加載內核和initrd.img
    2)內核將壓縮的initrd.img解壓成正常的ram disk並且釋放initrd所佔的內存空間
    3)initrd作爲根目錄以讀寫方式被掛載
    4)initrd裏面的文件linuxrc被執行
    5)linuxrc掛載新的文件系統
    6)linuxrc使用pivot_root系統調用指定新的根目錄並將現有的根目錄place到指定
位置.
    7)在新的文件系統下正式init
    8)initrd被卸載.
    爲了便於理解,我將red hat linnux9 裏面的initrd-2.4.20-8.img拿出來分析一下.
    這其實是一個壓縮了的文件,是以gz結尾的.
[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可執行
腳本設計的,因此你有必要看一看nash的man文檔.
1-10行是加載一些必要的模快.11-12行加載proc內核文件系統,13-14行利用nash內建的
命令mkdevices創建塊設備,mkdevices是根據/proc/partitions文件創建裏面列出的所有
塊設備.15-16行利用nash內建的命令mkrootdev,mkrootdev使它後面的參數/dev/root成
爲一個塊節點從而使得根分區設備被掛載,其中根分區設備由grub.conf裏面的kernel命
令後面所帶的參數root=決定,如果root=參數沒有被指定,/proc/sys/kernel/real-root-
dev文件將提供根分區設備號.17行將數字256寫入到後面的文件裏面去.18-19行掛載根文
件系統到/sysroot目錄下,/dev/root裏面的內容就是root=參數所指定的設備裏面的內容
20行調用pivot_root改變根目錄所在地並place舊的根目錄到指定的位置.21行卸載舊的
根目錄裏面的proc內核文件系統.
從這裏面我們總結一下linuxrc的作用:  (參考/usr/src/linux-2.4/Documenta
tion/initrd.txt文檔)
    2)/linuxrc文件決定在掛載真正的文件系統之前所需完成的事情(譬如加載必要的網
絡驅動或者加載ext3文件系統).
    3)/linuxrc加載必要的模塊.
    4)/linuxrc掛載根文件系統
    5)/linuxrc調用pivot_root來改變根目錄
    關於initrd的用途可以查考上面提到的文檔,想知道linux系統是如何安裝的嗎 那裏
面由答案.
    既然linuxrc的主要目的是加載模快用的,那如果我們的內核沒有動態的模塊而所需
的功能都是靜態編譯進內核的,那麼是不是可以不用linuxrc文件呢
    答案是可以不用,在普通的linux操作系統裏面可以加入noinitrd選項以告知boot
loader 不使用initrd.如果我們做網關,因爲ram是我們的文件系統的載體,所以initrd
一行當然不能去掉,但是我們可以不用linuxrc文件,sysroot文件夾和initrd文件夾.
    不信的話,試試看吧.
    好了,initrd(linuxrc)已經介紹完了.
    linuxrc執行完畢之後,系統就會以真正的根目錄正式init.
    系統在/bin/或者/sbin目錄下找到init程式,然後根據它的配置文件/etc/fstab進行
初始化,最後調用mingetty程式啓動login完成引導.

                
本文來自ChinaUnix博客,如果查看原文請點:
[url]http://blog.chinaunix.net/u/32475/showart_519239.html[/url]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章