GRUB(Boot Loader):
grub:GRand Unified Bootloader
grub 0.x:grub legacy
grub 1.x:grub2
grub主要有2個版本,傳統型版本0系列的為grub legacy,1系列的版本為grub2是完全重寫的,隻在工作特性上相容grub legacy,但在實作上有了巨大差别;
grub legacy
stage1:mbr
stage1_5:mbr之後的扇區,上stage1中的bootloader能識别stage2所在的分區上的檔案系統;
stage2:磁盤分區(/boot/grub/)
配置檔案:/boot/grub/grub.conf <-- /etc/grub.conf
stage2及核心等通常放置于一個基本磁盤分區;
功用:
(1)提供菜單、并提供互動式接口
e:編輯模式,用于比較菜單;
c:指令模式,互動式接口;
(2)加載使用者選擇的核心或作業系統
允許傳遞參數給核心
可隐藏此菜單
(3)為菜單提供了保護機制
為編輯菜單進行認證
為啟動核心或作業系統進行認證
以CentOS 5,6說明,grub legacy的應用;
grub legacy整個運作大體分3個運作階段,第一階段是安裝在mbr中的;
第二階段為stage1.5階段,存放在mbr之後的扇區中,主要作用是讓stage1中的bootloader能識别第三階段(stage2)所在分區上的檔案系統;
第三階段才是真正的stage2,這才提供菜單和編輯時能夠看到的界面,叫stage2是存放在磁盤分區上的,一般是挂載至/boot/grub/目錄下;grub也有自己的配置檔案:/boot/grub/grub.conf且通常有個符号連結檔案:/etc/grub.conf;
當系統啟動時,加載grub所在磁盤時,會讀取磁盤上的MBR,從此能加載到stage1,加載後會嘗試讀取随後扇區中的stage1.5階段,讀取1.5階段以後進而就能驅動真正第二階段stage2所在的磁盤分區了,加載的這個磁盤分區上不但有grub的第二階段,還包括了核心檔案及ramdisk等都在這個分區上存放的;是以這就是為什麼grub随後就能夠加載核心檔案的原因;
注意:目前硬體平台,主機闆BIOS必須能識别硬碟,然後BIOS才能加載硬碟中的Bootloader,磁盤中的Bootloader自身加載完以後,就能夠識别目前主機上的硬碟裝置了;但硬碟裝置能識别,并不代表硬碟上的檔案系統能識别,因為檔案系統是額外附加的一層軟體組織的檔案結構,是以要能夠對接一種檔案系統,必須要用到檔案系統驅動;
對應的應用程式必須能識别和了解這樣的檔案系統才可以,這種程式就稱為檔案系統驅動;grub的1.5階段就是給gurb提供了檔案系統驅動的,進而就能夠通路對應的第二階段和核心所在的分區了,這通常是一個基本磁盤分區;是以grub第二階段以及核心和ramdisk檔案通常都會放在一個基本磁盤分區上;因為grub驅動不了邏輯卷,除非給它提供一個特别複雜的接口,才能通路邏輯卷;如果把stage2放在邏輯卷上,就意味着沒法被grub1階段或1.5階段所加載的;
grub第二階段的功用或稱grub的功用:
第一:提供菜單或互動式接口,例如e編輯菜單,c指令模式,對應grub完全不用讀取配置檔案,能允許打開内置的指令行提示符,在鍵入的指令支援下,完成某些操作,這才是真正的互動式接口;
在虛拟機啟動時輸入任意鍵,可以進入grub内置指令行接口,輸入:c鍵,顯示grub>提示符;例如:
顯示幫助指令:grub> help
設定基本磁盤分區裝置所在位置:grub> root (hd0,0)
也可手動指明核心:grub> kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=/dev/mapper/vg0-root
還可指明initrd就跟菜單顯示的一樣:grub> initrd /initramfs-2.6.32-504.el.x86_64.img
然後使用boot指令啟動即可:grub> boot
這就正常啟動了;
第二:能加載使用者選擇的核心或作業系統;加載使用者選擇的核心時,允許使用者通過編輯菜單,傳遞參數給核心,還可以隐藏此菜單,在打開CentOS 6時就隐藏了;
第三:為菜單通過了保護機制,使用者如果想啟動核心,有2種機制,第一種是如果要編輯菜單需要輸入密碼,第二種要啟用核心或作業系統要輸入密碼;
如何裝置裝置:
(hd#,#)
hd#:磁盤編号,用數字表示,從0開始編号;
#:分區編号,用數字表示,從0開始編号;
(hd0,0)
grub的指令行接口
help:擷取幫助清單;
help KEYWORD:擷取詳細幫助資訊;
find (hd#,#)/PATH/TO/SOMEFILE:查找檔案;
root (hd#,#):設定指定磁盤分區為grub根;
kernel /PATH/TO/KERNEL_FILE:設定本次啟動時用到的核心檔案;額外還可添加許多核心支援使用的指令行(command line)參數;
例如:init=/path/to/init, selinux=0, init=1
initrd /PATH/TO/INITRANFS_FILE:設定我標明的核心提供額外檔案的ramdisk;
boot:引導啟動標明的核心;
檢視指定指令的幫助:
grub> help root
root指令是設定目前使用的根裝置,對于啟動時grub根裝置,不是檔案系統的根裝置,而是第二階段所在的磁盤分區才是根,這是設定grub的根裝置的;
grub是在boot目錄下的,而boot是否為單獨分區,也就是說根檔案系統下有boot目錄,這個boot目錄是否為單獨分區;
在系統啟動以後,看到的boot目錄有2種可能:boot目錄就是grub所在位置,第一種可能是,如果有2個分區,一個為boot分區1(boot單獨分區),一個為根分區2:
任何一個儲存設備要能通路到,前提是在目前根檔案系統上某個路徑下必須挂載這個裝置并作為其入口;也就是說在分區2的根檔案系統上必須有個目錄是boot,而boot沒作為單獨使用的存儲空間,而是把它當做另外一個分區(分區1)的通路入口這叫挂載;
是以通過boot所通路的檔案,例如要通路/boot/grub檔案,這個grub檔案是直接存在分區1上的,再例如要找/boot/vmlinuz檔案,則vmlinuz檔案是直接存在分區1上的;如果作業系統沒啟動,即grub剛啟動時,作業系統還沒有啟動,就是說bootloader剛加載,核心還沒加載根檔案系統更不可能加載呢;那麼,分區2的根檔案系統沒加載,就不能通過分區2的根檔案系統通路分區1上的/boot/vmlinuz檔案,但是,要需要通路分區1上的這個vmlinuz檔案,是以對于grub的通路路徑就是把分區1當做grub的根分區,是以grub是直接通路自己根下的vmlinuz檔案,grub有個root指令就是用來設定grub的根所在磁盤分區的;
是以grub要在第二階段要去找分區1上的vmlinuz檔案,就要把分區1設為grub的根;此時grub繞過了根系統,因為核心都還沒啟動更别說根檔案系統也不可能存在;而由于grub有檔案系統驅動,是以能夠直接通路分區1,而把這個分區設定為根以後,就可以直接通路這裡面的檔案了,如vmlinuz檔案,就是/vmlinuz,如果通路grub目錄下的grub.conf檔案,就是/grub/grub.conf;這就是所謂如果boot目錄單獨分區,grub就可把這個單獨分區設定為根,它的通路路徑與系統啟動後在檔案系統上看到的路徑是不一樣的;
第二種可能,就是boot(grub)不單獨分區,還是在分區2根檔案上有boot目錄,在系統啟動前還是沒有裝載這個根檔案系統的,grub的第一階段加載以後,要去通路grub第二階段或要找到vmlinuz檔案時,此時grub隻能把分區2設為自己的根,而boot目錄又沒有單獨分區,這樣grub的通路路徑是/boot/vmlinuz,例如通路grub目錄下的grub.conf檔案,路徑就是/boot/grub/grub.conf;
boot目錄是否為單獨的分區或這個引導分區是否為獨立的分區,決定了在grub中通路的路徑可能是不一樣的;
對于grub裡的root指令而言,就是用來指明這個根分區是哪的,如果boot目錄的單獨分區則直接指明這個分區為grub根分區,通路路徑就把這個boot路徑去了,如果boot目錄沒有單獨挂載分區,就在根分區上的,那麼就加上boot路徑即可,這與其是否被挂載沒有關系,隻是要注意,grub要通路某一分區,這一分區必須是基本磁盤分區;
因為grub裡面不能提供非常複雜的啟動程式(軟raid,邏輯卷,btree檔案系統);基于軟體的裝置,grub就不要放上去了;這也就是為什麼boot要單獨分區的原因,有時要把根做的很複雜,比如把根放在邏輯卷上,将來可以擴充空間,但是如果把boot也放在根(邏輯卷)上,grub就沒辦法找到grub第二階段了,是以隻能把boot放在基本磁盤分區上;不使用邏輯卷boot可是不單獨分區的;在CentOS 5,6上邏輯卷都是官方預設采用的根分區的分區類型,是以建立分區時總是把boot單獨建立一個分區;
對于grub legacy來說,識别識别時都以hd開頭,标記磁盤時第個一個數字表示第幾個磁盤,第二數字表示磁盤的第幾分區;例如(hd0,0)表示第一塊磁盤的第一個分區(從0開始編号的,grub2就從1開始編号了);
find指令,查找磁盤分區上的檔案;例如:
grub> find (hd0,0)/vmlinuz--2.6.32-504.el6.x86_64
指定檔案路徑,如果有此檔案,可使用Tab鍵補全檔案路徑或檔案名的,可通過find可定位檔案位置;
root指令,設定grub的根位置:
grub> root (hd0,0)
kernel指令,指明核心檔案的路徑,核心檔案名中的z表示壓縮格式,要先使用root指令指明根後再使用kernel指令;
initrd指令,用來指明ramdisk檔案或initrd檔案,對CentOS 6是initramfs檔案;ramdisk檔案版本号必須與核心版本号完全比對,否則ramdisk中的檔案,即子產品版本與核心版本不一緻,将無法被核心裝載;
手動在grub指令行接口啟動系統(centos 6):
grub> root (hd#,#)
grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE
grub> initrd /initramfs-VERSION-RELEASE.img
(centos 5是initrd檔案)
grub> boot
示範完整過程:(見截圖)
e鍵進入grub編輯模式,c鍵進入指令模式,然後指的根,指明核心,可以加上quiet,表示為靜默模式,;指明initrd檔案,最後使用boot啟動;
虛拟機開機時,按任意鍵,進入GRUB界面;
鍵入c,輸入help指令

鍵入e
鍵入c
指定grub根所在位置和核心檔案
指定initrd後開始引導啟動
配置檔案:/boot/grub/grub.conf,或連結檔案:/etc/grub.conf
常用配置項:
default=#:設定預設啟動的菜單項,菜單項(title)編号從0開始;
timeout=#:指定菜單項等待使用者選擇的等待時長,要鍵入回車确定;
splashp_w_picpath=(hd#,#)/PATH/TO/XPM_PIC_FILE:指明菜單背景圖檔檔案路徑;
hiddenmenu:隐藏菜單;
password [--md5] STRING:菜單編輯認證;
titile TITLE:定義菜單項的“标題”,可出現多次;
(縮進)root (hd#,#):grub查找stage2即kernel檔案所在裝置分區;為grub的“根”;
kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:啟動的核心;
initrd /PATH/TO/INITRAMFS_FILE:核心比對的ramfs檔案;
password [--md5] STRING:啟用標明的核心或作業系統時進行認證;
opsenssl指令;
grub-md5-crypt指令;
配置檔案内容:
default=0
timeout=5
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS 6 (2.6.32-573.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-573.el6.x86_64 ro root=UUID=74c3491c-52c8-46f1-8e7f-84cd079620e3 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-573.el6.x86_64.img
title後面設定的内容就是菜單顯示的内容;下面縮進的内容,就是子菜單所顯示的内容;
可以添加title,指明多個核心,能改變菜單顯示;
default是指明預設啟動的核心;而titile就是從上至下開始從0編号的;
splashp_w_picpath設定使用的啟動背景圖檔;格式為xpm格式且要壓縮,色深很高分辨率就很高逼真細膩,此處的圖檔隻支援色深14位色,代表隻能顯示2^14次方種顔色;
使用openssl指令生成grub加密時的密碼串,使用比較麻煩;可使用grub-md5-crypt指令;例如:
~]# grub-md5-crypt
Password:
Retype password:
$1$/dqoi$rYUKkuBwaYsq/DFarMf/t1
輸入密碼後,計算出密文密碼;這樣就可以在grub配置檔案中,設定grub中的密碼了,如:
password --md5 $1$/dqoi$rYUKkuBwaYsq/DFarMf/t1
自定義grub配置檔案内容:
root (hd0,0)
kernel /vmlinuz-2.6.32-573.el6.x86_64 ro root=UUID=74c3491c-52c8-46f1-8e7f-84cd079620e3 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-573.el6.x86_64.img
title CentOS 6 (my linux)
password --md5 $1$/dqoi$rYUKkuBwaYsq/DFarMf/t1
隻要title标題不一樣就可以,其它都可以一樣;
進入單使用者模式:
(1)編輯grub菜單(標明要編輯的title,然後使用“e”指令);
(2)在標明的kernel後附加
1,s,S或singel都可以;
(3)在kernel所在行,鍵入“b”指令;
安裝grub:
(1)grub-install
grub-install --root-directory=ROOT /dev/DISK
(2)grub
grub> setup (hd#)
如果grub配置檔案被删了,隻是沒有提示菜單了,可在指令上手動啟動,啟動後在手動編輯一個grub配置檔案即可;如果grub中的檔案損壞,例如mbr中的bootloader損壞,就要修複bootloader,隻有一個辦法,進入救援模式,或把硬碟拆下來放到其它主機上修複;
使用grub指令可以重新安裝和修複grub的,第一種情況,如果目前系統啟動完好,那麼如果有兩塊硬碟,想把第二塊硬碟安裝grub此時就用到grub指令;
第二種情況,如果目前系統沒有grub但能借助CD光牒上的grub來啟動,隻有能看到grub提示符就能啟動硬碟上的系統;
還有一種情況,雙系統共存時,windows和linux系統,要先裝windows系統,然後在裝linux系統才能雙系統共存;因為windows不引導其它系統,假如重裝了windows系統後,開機linux系統就不能啟動了,此時就可借助U盤或其它盤上的grub,啟動linux,然後在linux啟動後,在linux系統中重裝一遍grub,依然會安裝系統一樣,把windows啟動項重新進行編輯,而後把自己的bootloader安裝在mbr中去,以後開機就能啟動linux了;
使用grub-install指令安裝grub,它是完整安裝包括grub第一階段,1.5階段和第二階段;第二階段是在磁盤分區上的boot目錄下裝一個grub目錄;是以必須要找到boot目錄之後再此目錄下建立一個grub;如果boot目錄是一個單獨分區,沒有與根在同一分區上,面對這種情況,如果有第二塊硬碟,要給第二塊硬碟安裝grub,安裝完後boot是在單獨分區上的;以後可以把這塊硬碟拆下來,拿到啟動主機上來啟動系統,用虛拟機實作:
例如,再給虛拟機centos 6系統上加一塊硬碟并建立分區,以便為boot(grub)單獨分區使用,(指令過程省略);建立磁盤分區完成後,就需要挂載,grub要找boot目錄,而目前系統的boot在使用,是以可在其它目錄下建立一個boot目錄就行,例如/mnt/boot/,然後把分區挂載這個boot目錄下即可(指令過程省略)例如把/dev/sdb1挂載至/mnt/boot/;然後就可以把grub安裝在sdb上:
]# mount /dev/sdb1 /mnt/boot/
注意:sdb1的以後要當做grub的根的;
]# grub-install --root-directory=/mnt /dev/sdb
注意:是以要指定grub根在/mnt下,指定根目錄時不要寫boot,隻有/mnt就行因為它會自動找boot目錄的;此時檢視/mnt/boot/grub/目錄下,就已經安裝好了grub檔案;但配置檔案需要自己寫;還需要把核心檔案,initramfs檔案複制一份;如下:
]# cp /boot/vmlinuz-2.6.32-573.el6.x86_64 /mnt/boot/vmlinuz
]# cp /boot/initramfs-2.6.32-573.el6.x86_64.img /mnt/boot/initramfs.img
]# vim /mnt/boot/grub/gurb.conf
title CentOS (Express)
kernel /vmlinuz ro root=/dev/sda3(相當于目前主機的sdb3) selinux=0 init=/bin/bash(限定init為bash,而不是/sbin/init了)
initrd /initramfs.img
還有建立根檔案系統目錄結構:
]# mkdir /mnt/sysroot
]# mount /dev/sdb3 /mnt/sysroot/
]# mkdir -pv etc bin sbin lib lib64 dev proc sys tmp var usr home root mnt media
就複制一個bash檔案,以便啟動程式做示範,使用init環境比較複雜;
]# cp /bin/bash /mnt/sysroot/bin/
在檢視bash依賴哪些庫,也要把依賴檔案複制過來,否則bash是無法運作的;
]# ldd /bin/bash
]# cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64
]# cp /lib64/libdl.so.2 /mnt/sysroot/lib64
]# cp /lib64/libc.so.6 /mnt/sysroot/lib64
]# cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64
測試bash是否能用,要切換根測試;
]# chroot /mnt/sysroot/
此時要把grub配置檔案中,加入init=/bin/bash;然後同步一下;
]# sync
然後再建立一個虛拟機,裝載剛才制作grub的那塊硬碟,此時就可以啟動系統了,但沒有什麼指令可用;要想用指令,找二進制程式檔案、庫檔案、配置檔案;
修複grub的方法:
例如,手動破壞bootloader,再建立grub,提前備份bootloader:
]# dd if=/dev/sda of=/root/mbr.bak count=1 bs=512
]# dd if=/dev/zero of=/dev/sda bs=200 count=1
]# grub-install --root-directory=/ /dev/sda
完成修複;
注意:指定根下--root-directory=并不要求有boot、grub目錄;
另一種修複grub的方法:
進入grub:
]# grub
grub> root (hd0,0):設定根所在裝置;
grub> setup (hd0):安裝grub第一階段,指明硬碟即可;
grub> exit
]# reboot
注意:指定的根目錄下root (hd0,0)必須要有boot、grub目錄且裡面要有stage1、stage1.5等檔案才行;
用緊急救援模式,修複grub:
比如系統啟動不起來了,此時要載入系統安裝CD光牒,進入緊急救援模式;選擇Rescue installed system;在指令行提示符下,輸入:
boot:linux rescue
啟動緊急救援模式了,類似于windows中的winPE;
插入安裝CD光牒讀取安裝:
見截圖;
選擇Rescue installed system救援模式,或敲Esc鍵,進入救援模式輸入linux rescue
選擇語言
選擇鍵盤類型
選擇啟動網絡
查找作業系統,自動挂載至/mnt/sysp_w_picpath目錄下,選擇Continue
搜尋磁盤上安裝的系統
找到磁盤上的系統且挂載至/mnt/sysp_w_picpath下
确定
啟動shell
輸入grub-install或直接切換根
執行grub-install等指令
根就是目前系統的根,裝置為目前硬碟sda
安裝完成後,退回rescue模式