GRUB——系統的引導程序簡單介紹


這幾天對於操作系統是如何引導啟動的特征的感興趣,已經到了不能自拔的狀態了,所以索性好好了解一下;

前面已經說過了,MBR對於系統啟動的重要性,這是不多啰嗦;  現在介紹一個 grub ,啟動管理器,它可以用於引導不同的系統;

 

grub 是一個怎么樣的引導原理?

通過我的實驗,我得到的結論就是: 整個grub啟動管理器其實也算是有點大的,引導扇區里是放不開的;  所以,grub會往引導扇區(可以是MBR, 也可以是每一個分區里面的引導扇區)里面寫入部分內容,對於剩余的部分,它會寫入到我們的硬盤分區里面的;在啟動時,首先運行引導扇區里的程序, 然后在運行硬盤分區里的程序,最后引導操作系統;

對於引導扇區里的程序是如何找到硬盤分區里的程序與配置的,這個就是細節方面的問題了,我們可以忽略;不過我也是一個好學習的人,我也查了查相關的資料,有的解釋如下:

來自:作者:js li
鏈接:https://www.zhihu.com/question/27652991/answer/37500373
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

grub的話,肯定是要在mbr里寫東西的,但446字節的機器碼也干不了太多東西,只是負責把后續的內容加載到內存在執行而已。這個寫到mbr的是stage1,它加載的是寫在mbr之后62個扇區中的stage1.5(因為過去磁盤是按磁道還划分分區的,一個碰道63個扇區,因為mbr占據了第一個磁道的第一個扇區,所以第一個分區只能從第二個磁道開始,這樣在mbr和第一個分區之間就留下了62個扇區的空間,62*512byte=31KB)。

mbr之前說了容量太小沒法放下識別文件系統的代碼,只能以計算扇區絕對偏移的方法加載stage1.5,但31KB的stage1.5就足夠了(但基本也只夠一種類型的文件系統,所以stage1.5是有好幾個,分別對應ext4,xfs等等,在grub安裝時根據需要寫入,隨便一提,正是因為GPT分區表占用了后62個扇區的相當一部分位置,導致空間不夠寫下stage1.5,所以需要額外分出一個非常小的分區來存放)。 (我的備注:我在寫grub時,沒有設置是ext4,還是xfs, 應該是它自動識別的吧)

stage1.5可以識別文件系統,然后根據安裝時硬寫到里面的系統路徑(hexdump可以看到)找到stage2,然后這個stage2才是真正負責干活的,它會讀取grub.cfg並生成啟動菜單,然后根據你的選擇加載內核並把執行權限轉過去,完成啟動。

 

實驗部分:

先跟着實驗走一遍,然后就會更容易明白grub是如何引導的,來,先折騰起來:

我使用的grub版本分別為 grub-0.97 和 grub-2.02;

 

grub-0.97 的使用:

第一步:我們下載 grub-0.97這個工具,並安裝到 linux系統上      

(注意:這里說的安裝是指的 把這個 grub-0.97 工具安裝到 linux 上,而不是把 grub-0.97的啟動管理器安裝到 硬盤分區上;我們需要使用grub-0.97 這個工具來安裝 grub-0.97 啟動管理器)

方法1:在 linux 上 使用 apt-get install grub 下載下來的為就是 grub-0.97版本的,所以直接 apt-get install grub 就下載下來了;

方法2:當然也可以下載源碼,自己編譯(下載地址:ftp://alpha.gnu.org/gnu/grub/):別忘了給 root 權限:

// 假設應該下載完畢,,位置目錄 grub 下:

tar xzvf grub-0.97.tar,gz
./configure --prefix=/usr                 // prefix 指定了安裝的位置,當然也可以放在其它地方,不過需要添加一下環境變量,
                                                 // 如果不過添加環境變量,就到安裝的目錄下去運行也可以;
make
make install

 

第二步:安裝grub 引導管理器到硬盤分區:

方法1:是通過命令一步步的安裝,輸入 grub 會出來 grub的交互窗口如下圖,這時可以輸入命令進行安裝; 至於命令吧,我沒有研究啊,用第二個方法方便;

image

方法2: 用自帶的 grub-install 腳本安裝: 這個腳本其實也是調用 grub 的命令進行安裝的:

首先 使用help 來看看grub的用法,輸入 grub-install –help:

image

所以,我們知道了 grub-install 的用法啦.我們僅僅使用下面的命令格式就可以了,其它的就不用管了: 

sudo grub-install --root-directory=DIR install_device 

// DIR指的是grub的安裝到硬盤的那一部分的目錄位置;其實這個不重要,寫到哪里都可以,反正 grub 的第一部分都可以找到的;只要你記住就可以了,因為可以在里面加入配置文件的;
                                                                  // 不過有一點要求:那就是把交叉硬盤,即不能把grub的第一部分與第二部分寫在不同的硬盤上,我試過,會報錯的;
// install_device 表示了安裝到引導扇區的那一部分的到底的安裝到哪一個引導扇區;
          // 例如:一塊硬盤為sda, 如果 install_device 為 /dev/sda,則表示安裝到了這個硬盤的MBR上;
                 //                     如果 install_device 為 /dev/sda1,則表示安裝到了這個硬盤的第一個主分區的引導扇區上;
                 // 當然如果安裝到第MBR上, grub啟動管理器可以正常運行,如果安裝到分區的引導扇區上,則需要使用到 chainloader(下面會說到)

安裝完成以后,我們在 sdb1的分區下面應有了一個 /boot/grub/ 目錄了;里面有相關的內容;

 

舉個兩個例子:

我給虛擬機加了一塊硬盤sdb,並且已經分區、格式化完成了,如下:

image

例子1:把 grub的 引導程序的第一部分寫到硬盤的MBR上, 至於grub的剩余部分安裝到哪,都行,我就安裝到第一個分區里吧,過程如下:(我要先創建一個空目錄 sdb1,然后把硬盤的第一個分區掛載到上面)

image

這時,開機把啟動項選擇從硬盤 sdb啟動, 就會出現  grub> 窗口了,如下:(由於sdb硬盤上 grub,並沒有配置信息: menu.lst,所以它自己找不到sda硬盤上的系統上,所以需要進行手動引導,見下面)

image

 

例子2:把 grub的 引導程序的第一部分寫到硬盤第一分區的引導扇區上, 至於grub的剩余部分同樣的安裝到哪,都行,我就安裝到第一個分區里吧,過程如下:(我要先創建一個空目錄 sdb1,然后把硬盤的第一個分區掛載到上面)

方法與上面相同:只需要把sdb 改為 sdb1就可以了;

image

 

補充:(這一小段來自:http://blog.csdn.net/zzqhost/article/details/5935317

    grub-install 是一個腳本,它完成以下任務:                     
    * 調用 grub-mkdevicemap 創建設備映像文件 /boot/grub/device.map
    * 復制 *.mod *.lst *.img 文件到 /boot/grub/
    * 調用 grub-probe 自動偵測文件系統類型
    * 調用 grub-mkimage 生成grub2內核文件 /boot/grub/core.img
    * 調用 grub-setup 安裝引導記錄到mbr或分區-

 

第三步:grub> 命令窗口下如何手動啟動 linux 系統:

由於sdb硬盤上 grub,並沒有配置信息: menu.lst,所以它自己找不到sda硬盤上的系統上,所以進行手動引導:

說明: 1.在 grub-0.97中,會把硬盤識別為 hd0,hd1,hd2, ……; 分區也是從0標志開始的,如第一分區(hd0,0), 第二分區(hd0,1),……; 

        2. grub 會把啟動盤作為 hd0盤,其它盤為hd1, hd2等;

        3. 記得用 tab 補全;

命令如下:

image

解釋: 1. 第一行 root (hd1,0),  表示設置一個 linux 系統的 /boot 目錄的分區,在這個 /boot 目錄下有 內核文件與啟動的鏡像文件;又由於 這個分區是 grub 看到的,所以用grub的格式表示,那為什么為(dh1,0)呢??因為現在的啟動盤為 sdb,而linux的系統在sda的第一個分區上,所以為(dh1,0);  如果省略這個 root (hd1,0) 也可以,后面找內核與鏡像文件時再指明也行,只是會麻煩一些;

       2.  第二行的命令是加核 linux 的內核文件,  對於后面的 root=/dev/sda1是什么?? 它指明了 linux 系統的  /  目錄所在的分區,因為需要把很多東西mount到  / 目錄下的目錄名字下; 這個分區的路徑是 linux 系統看到的,所以為 /dev/sda1;

      3. 加載映像文件;(什么是initrd.img,百度或google)

      4. 啟動;

第四步: 配置 grub-0.97的配置文件,讓它自動引導:

在 grub-0.97的 配置文件名字為:menu.lst 文件;至於配置文件的內容的書寫方式,不多說,網上有很多,再說 現在都用grub2了,它的配置文件變了,所以研究也沒有用了;我怎么做的呢?我先用 linux 上的grub-0.97 來自動自成一下 配置文件(命令:udpdate-grub),然后把它復制到 sdb1下的 /boot/grub/ 目錄下(這個是我們上面生成的), 然后修改一下:  添加了一行命令: root  (hd1,0)  :

修改前:

image

修改后:

image

此時,我們重新從 硬盤 sdb里啟動電腦,就可以啟動了:

image

image

完成;

 

grub-2.02 的使用:

整個過程與grub-0.97 是相同的,說說不一樣的地方 :

1. grub-2.02 可以在這里下載:ftp://ftp.gnu.org/gnu/grub/ftp://alpha.gnu.org/gnu/grub/

    或者: ap-get install grub2-common;

2. grub-2.02支持更多的命令;

3. grub-2.02的 grub-install 的參數不一樣了,同樣可以通過 grub-install –help查看,部分如下:

image

在使用時,這么用:

sudo grub-install --boot-directory=DIR install_device 

// 例如: sudo grub-install --boot-directory=/sdb1/ /dev/sdb
 // 它指的是 boot的目錄 , 而不是root的目錄了;

4.  在 grub-2.02中,會把硬盤識別為 hd0,hd1,hd2, ……; 而分區也是從msdos1標志開始的,如第一分區(hd0,msdos1), 第二分區(hd0,msdos2),……; 

5. 在grub-2.02中的配置文件變成了 grub.cfg;

6. 當我把 grub-2.02安裝到 sdb的MBR時, 把 linux系統下的 grub.cfg 文件復制到 sdb1分區上的 /grub/ 目錄下時, 修改如下:

把 grub.cfg 里面的 hd0 全部替換為 hd1;  最后,在sdb硬盤啟動時, sda上的 linux 系統啟動成功;

7. 我發現使用在grub-2.02里,使用grub-install 寫入到分區的引導記錄時,會出問題,而使用grub-0.97則不會再現問題;

8.grub-2.02的命令有所不同:

set root=(hd1,msdos1)
linux /boot/ vm**** boot=/dev/sda1
initrd /boot/initrd.img***
boot

 

當把grub 沒有安裝到硬盤的 MBR里面,而是安裝到了 第一分區,或第二分區時,怎么辦?

使用 chainloader 命令( 它屬於 grub的命令),它可以調用另一個啟動器,如:在grub中,輸入命令例如:

root (hd0, 0)             // 為安裝grub 的分區,這是為第一分區;

chainloader +1          // 將指定的文件作為一個鏈式裝載程序載入。為了獲取在一個指定分區第一 扇區內的文件,使用+1作為文件名。

boot

這時,就會從硬盤的第一分區進行啟動了;

 

完;

另外:可以看看相關的:GRUB(簡體中文)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM