這幾天對於操做系統是如何引導啓動的特徵的感興趣,已經到了不能自拔的狀態了,因此索性好好了解一下;php
前面已經說過了,MBR對於系統啓動的重要性,這是很少囉嗦; 如今介紹一個 grub ,啓動管理器,它能夠用於引導不一樣的系統;linux
經過個人實驗,我獲得的結論就是: 整個grub啓動管理器其實也算是有點大的,引導扇區裏是放不開的; 因此,grub會往引導扇區(能夠是MBR, 也能夠是每個分區裏面的引導扇區)裏面寫入部份內容,對於剩餘的部分,它會寫入到咱們的硬盤分區裏面的;在啓動時,首先運行引導扇區裏的程序, 而後在運行硬盤分區裏的程序,最後引導操做系統;工具
對於引導扇區裏的程序是如何找到硬盤分區裏的程序與配置的,這個就是細節方面的問題了,咱們能夠忽略;不過我也是一個好學習的人,我也查了查相關的資料,有的解釋以下:學習
來自:做者:js li
連接:https://www.zhihu.com/question/27652991/answer/37500373
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。googlegrub的話,確定是要在mbr裏寫東西的,但446字節的機器碼也幹不了太多東西,只是負責把後續的內容加載到內存在執行而已。這個寫到mbr的是stage1,它加載的是寫在mbr以後62個扇區中的stage1.5(由於過去磁盤是按磁道還劃分分區的,一個碰道63個扇區,由於mbr佔據了第一個磁道的第一個扇區,因此第一個分區只能從第二個磁道開始,這樣在mbr和第一個分區之間就留下了62個扇區的空間,62*512byte=31KB)。spa
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並生成啓動菜單,而後根據你的選擇加載內核並把執行權限轉過去,完成啓動。 .net
先跟着實驗走一遍,而後就會更容易明白grub是如何引導的,來,先折騰起來:code
我使用的grub版本分別爲 grub-0.97 和 grub-2.02;blog
(注意:這裏說的安裝是指的 把這個 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
方法1:是經過命令一步步的安裝,輸入 grub 會出來 grub的交互窗口以下圖,這時能夠輸入命令進行安裝; 至於命令吧,我沒有研究啊,用第二個方法方便;
方法2: 用自帶的 grub-install 腳本安裝: 這個腳本其實也是調用 grub 的命令進行安裝的:
首先 使用help 來看看grub的用法,輸入 grub-install –help:
因此,咱們知道了 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,而且已經分區、格式化完成了,以下:
例子1:把 grub的 引導程序的第一部分寫到硬盤的MBR上, 至於grub的剩餘部分安裝到哪,都行,我就安裝到第一個分區裏吧,過程以下:(我要先建立一個空目錄 sdb1,而後把硬盤的第一個分區掛載到上面)
這時,開機把啓動項選擇從硬盤 sdb啓動, 就會出現 grub> 窗口了,以下:(因爲sdb硬盤上 grub,並無配置信息: menu.lst,因此它本身找不到sda硬盤上的系統上,因此須要進行手動引導,見下面)
例子2:把 grub的 引導程序的第一部分寫到硬盤第一分區的引導扇區上, 至於grub的剩餘部分一樣的安裝到哪,都行,我就安裝到第一個分區裏吧,過程以下:(我要先建立一個空目錄 sdb1,而後把硬盤的第一個分區掛載到上面)
方法與上面相同:只須要把sdb 改成 sdb1就能夠了;
補充:(這一小段來自: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或分區-
因爲sdb硬盤上 grub,並無配置信息: menu.lst,因此它本身找不到sda硬盤上的系統上,因此進行手動引導:
說明: 1.在 grub-0.97中,會把硬盤識別爲 hd0,hd1,hd2, ……; 分區也是從0標誌開始的,如第一分區(hd0,0), 第二分區(hd0,1),……;
2. grub 會把啓動盤做爲 hd0盤,其它盤爲hd1, hd2等;
3. 記得用 tab 補全;
命令以下:
解釋: 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的 配置文件名字爲:menu.lst 文件;至於配置文件的內容的書寫方式,很少說,網上有不少,再說 如今都用grub2了,它的配置文件變了,因此研究也沒有用了;我怎麼作的呢?我先用 linux 上的grub-0.97 來自動自成一下 配置文件(命令:udpdate-grub),而後把它複製到 sdb1下的 /boot/grub/ 目錄下(這個是咱們上面生成的), 而後修改一下: 添加了一行命令: root (hd1,0) :
修改前:
修改後:
此時,咱們從新從 硬盤 sdb裏啓動電腦,就能夠啓動了:
完成;
整個過程與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查看,部分以下:
在使用時,這麼用:
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
使用 chainloader 命令( 它屬於 grub的命令),它能夠調用另外一個啓動器,如:在grub中,輸入命令例如:
root (hd0, 0) // 爲安裝grub 的分區,這是爲第一分區;
chainloader +1 // 將指定的文件做爲一個鏈式裝載程序載入。爲了獲取在一個指定分區第一 扇區內的文件,使用+1做爲文件名。
boot
這時,就會從硬盤的第一分區進行啓動了;
完;
另外:能夠看看相關的:GRUB(簡體中文);