GRUB是一个多操作系统启动管理器。GRUB全称为GRand Unified Bootloader。他是系统启动后运行的第一个程序,他是用来负载加载,传输控制到操作系统的内核,一旦他把内核挂载,系统引导管理器的任务也就完成。其他部分,比如设定默认启动级别,系统初始化,关闭启动相应的服务等都内核去完成。

 1. grub legacy整个运行分为了三个阶段;

    第一阶段,stage1,它是直接被写入到MBR中去的,这样机器一启动检测完硬件后,就将控制权交给了GRUB的代码。也就是上上图所看到的前446个字节空间中存放的是stage1的代码。BIOS将stage1载入内存中0x7c00处并跳转执行。stage1(/stage1/start.S)的任务非常单纯,仅仅是将硬盘0头0道2扇区读入内存。此时,stage1是没有识别文件系统的能力的。

    stage1主要负责BIOS和GRUB之间的交接,载入存放于各个分区中的开机文件。例如Linux下/boot/grub/..下面的一些文件。这部分才是真正放在MBR中的bootloader。

    stage1文件的大小正好是512字节,事实上stage1文件其实就是MBR中bootloader的备份,而之所以是bootloader而不是MBR, 是因为这个文件的前446字节才是和MBR是一样的

    

    第二阶段,1.5阶段,其存放在mbr之后的扇区,让stage1中的bootloader能识别stage2所在的分区上的文件系统;给grub提供了文件系统的驱动;

    解析:GRUB开始没有OS,也没有文件系统的概念。那么GRUB是从何时开始有文件系统的功能的呢。这就是stage1.5干的事情,stage1.5过后,GRUB就能识别文件系统了,就能在磁盘上识别加载文件了怎么做到的?start.S加载的磁盘上的那些扇区的内容,就是文件系统的代码,(即start.S的汇编代码,有兴趣的筒子可以去了解一下),将其(大概14个扇区)加载到内存,就具备了操作启动设备上面文件的功能了,我们有了文件系统,我们可以直接操作文件了。那么/boot/grub/stage2这样的比较大的文件可以直接操作了。此后grub才有能力去访问/boot分区/boot/grub目录下的 stage2文件,将stage2载入内存并执行。

    

     第三阶段,stage2:他存放磁盘分区上(/boot/grub/)。 

     解析:让用户以选项的方式将操作系统加载、修改选项以及新增参数,平时开机启动的时候看到的Grub选项、信息,还有修改GRUB背景等功能都是stage2提供的,stage2会去读入/boot/grub/grub.conf配置文件。 

    

    总结:

    1) BIOS将控制权交给硬盘的主引导区,即MBR。

    2) MBR中的bootloader(stage1)通过内置的地址加载stage1_5;

    3)bootloader通过stage1_5的内容,将分区中的stage2加载;

    4)stage2此时就可以在文件系统中将grub.conf文件加载,让用户看到选项界面。

 

    grub的配置文件存放在/boot/grub/grub.conf,他还有一个链接文件,为/etc/grub.conf,stage2及内核等通常放置于一个基本磁盘分区。

    grub界面通过开机按C进入,如图:

    grub应用配置及修复_应用配置

 2.整个grub的功能主要有以下几方面:

    (1) 提供菜单、并提供交互式接口

            e: 编辑模式,用于编辑菜单;

            c: 命令模式,交互式接口;

    (2) 加载用户选择的内核或操作系统

            允许传递参数给内核

            可隐藏此菜单

    (3)为菜单提供了保护机制

            为编辑菜单进行认证

            为启用内核或操作系统进行认证

        

3.grub如何识别设备:grub在boot目录下,要看boot的目录所在处。

       格式:(hd#,#)第几个磁盘的第几个分区;

        hd#: 磁盘编号,用数字表示;从0开始编号

        #: 分区编号,用数字表示; 从0开始编号

        一般情况为(hd0,0):第一个磁盘的第一个主分区

4.grub有自己的命令行接口,选项如下:

    help: 获取帮助列表

    help KEYWORD: 详细帮助信息

    find (hd#,#)/PATH/TO/SOMEFILE:定位某文件是否存在

    root (hd#,#)把哪一个磁盘分区设为根设备

    kernel /PATH/TO/KERNEL_FILE: 设定本次启动时用到的内核文件;额外还可以添加许多内核支持使用的cmdline参数;指明内核文件的路径;z表示压缩格式

        例如:init=/path/to/init, selinux=0

    initrd /PATH/TO/INITRAMFS_FILE: 设定为选定的内核提供额外文件的ramdisk;

    boot: 引导启动选定的内核;

如图:

grub应用配置及修复_应用配置_02

上面的一些命令可以帮助我们在开机查询有关grub相关信息。

我们可以假设以下几种情况:

1)假设一个系统的grub设置出现问题(原因:不正确地修改grub 配置文件,安装另一个操作系统,硬件上或 BIOS内的改动引致设置的排序不相同),导致grub不能找到它的配置文件,你可能会面对 grub 的开机提示符而无从着手。一般来说,第一步是要找出grub配置文件的位置。

grub的 find 指令可以为你效劳

grub> find /grub/grub.conf
find /grub/grub.conf 
(hd0,2) (hd1,2)

这里告诉我们我们有两个boot分区,有可能源自不同的操作系统。头一个位于第一个硬盘的第三个分区,另一个位于第二个硬盘的第三个分区,假若要将第一个项目的grub设置重新安装到MBR;方法如下:

grub> root (hd0,2)
grub> setup (hd0)


2)或者直接去查找stage1所在也可,如图所示:

grub> find /boot/grub/stage1
 (hd0,5)

grub> root (hd0,5)
grub> kernel /boot/vmlinuz-2.6.18-238.19.1.el5.centos.plusPAE ro root=/dev/sda6
grub> initrd /boot/initrd-2.6.18-238.19.1.el5.centos.plusPAE.img
grub> boot



3)如果你安装了其它 Linux 版本,比如说Ubuntu,它只有 menu.lst配置而没有grub.conf,但由于 CentOS利用连结把 menu.lst指向 grub.conf,因此在这两个系统上寻找 menu.lst也是可以的:

grub> find /grub/grub.conf
find /grub/grub.conf 
(hd0,0)
grub> find /grub/menu.lst
find /grub/menu.lst 
(hd0,0) (hd0,1)

由此可见,这里有两个/boot分区,第一位于硬盘的第一个分区,很可能是centos,而另一个linux的唯一第一个硬盘的的第二个分区;

这时候要查看grub.conf及menu.1st的内容,可以使用cat,

grub> cat (hd0,0)/grub/grub.conf 
... 显示文件内容 ...
grub> cat (hd0,1)/grub/menu.lst 
... 显示文件内容 ...


4)要是第一次尝试找不到文件,很可能/boot 分区并不存在,而grub被安装在主目录内。可以尝试:

grub> find /boot/grub/grub.conf 
(hd0,0) (hd1,4)

如上所示,这个例子里有两个grub。第一个在第一个硬盘的第一个分区,而另一个在第二个硬盘的第五个分区 —— 亦即首个扩展分区。

如果要撤消第二个项目并将GRUB的开机程序安装在第一个硬盘的 MBR 上:

grub> root (hd1,4)
grub> setup (hd0


4)如果不清楚主目录的位置时,可以尝试寻找 /etc 内的一个文件。例如:

grub> find /etc/fstab 
(hd0,1)

由此我们得知 / 位于第一个硬盘的第二个分区上 —— 采用 SCSI 或 SATA 等于 /dev/sda2,而采用 PATA 等于/dev/hda2。


   

 

手动在grub命令行接口启动系统:

    grub> root (hd#,#)

    grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE 

    grub> initrd /initramfs-VERSION-RELEASE.img

    grub> boot

    以上几个完成grub的配置。

如下图:

grub应用配置及修复_grub_03

如上图:内核与init的路径指定与/boot目录是否被单独分区有关;

    1)如boot单独分区,同时安装在第一块硬盘,那么可以入上图填写;

    2)如boot不是单独分区,前面需要指定boot路径, 如/boot/...等;

    3)如不是第一块硬盘,或许是(hd#,#);

    4)因centos6,7版本 /默认被安装为LVM格式,建议boot单独分区。

举例:/boot 的分区是 /dev/sda1,或 hd(0,0)。/ 的分区是 /dev/sda2,或hd(0,1),那么/boot/grub/grub.conf必须如下设置:

title CentOS 6.7 i686  
root (hd0,0)  
kernel /vmlinuz-2.6.32-573.el6.x86_64 ro root=/dev/sda2  
initrd /initramfs-2.6.32-573.el6.x86_64.img





5.再看看grub的配置文件/boot/grub/grub.conf

grub应用配置及修复_应用配置_04

    配置项:

        default=#: 设定默认启动的菜单项;落单项(title)编号从0开始;

        timeout=#:指定菜单项等待选项选择的时长;

        splashp_w_picpath=(hd#,#)/PATH/TO/XPM_PIC_FILE:指明菜单背景图片文件路径;

        hiddenmenu:隐藏菜单;

        password [--md5] STRING: 菜单编辑认证;

        title TITLE:定义菜单项“标题”, 可出现多次;

            root (hd#,#):grub查找stage2及kernel文件所在设备分区;为grub的“根”; 

            kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:启动的内核

            initrd /PATH/TO/INITRAMFS_FILE: 内核匹配的ramfs文件;

            password [--md5] STRING: 启动选定的内核或操作系统时进行认证;

 可以使用grub-md5-crypt命令创建密码。示例:

[root@mageedu ~]# grub-md5-crypt 
Password: 
Retype password: 
$1$LduMa$b.xr5xXjzmcTWx/cpqCXa.

然后将密码写在配置文件里

    password --md5$1$LduMa$b.xr5xXjzmcTWx/cpqCXa.  缩进写入配置文件。

可以对菜单进行编辑认证或者对启动的内核进行认证设置。



6.  进入grub的单用户模式可以帮我们修改忘记root之后的密码,进入的单用户模式的方法:

    (1) 编辑grub菜单(选定要编辑的title,而后使用e命令); 

    (2) 在选定的kernel后附加,1, s, S或single都可以;

    (3) 在kernel所在行,键入“b”命令;


7.如果bootloader文件损坏,那么就只能进入救援模式;或者把硬盘拆下来,放到其他的主机上修复。 如果grub损坏,如何重新安装grub?


1)尚未关机

  模拟破坏情况:

#dd if=/dev/zero of=/dev/sda bs=200 coun1=1

方法1:grub-install直接修复安装,可以安装grub的三个阶段,如图:

     grub应用配置及修复_应用配置_05 


    注意:此种方式不要求指定的根下有boot目录,或者有grub目录,会自动创建

 方法2:使用grub命令提示符进行修复

grub应用配置及修复_grub_06  

注意:此种要求必须要指定的root的设备上必要有一个grub目录。stage1,stage1.5 stage2都必须存在才可以,不然无法安装成功。


2)第二种情况,bootloader损坏,并且已经重启主机,主机无法启动,此时需要进入救援模式进行修复。

如下图,重启之后,界面无法引导,

grub应用配置及修复_应用配置_07

一)此时需要使用光盘镜像引导。

grub应用配置及修复_应用配置_08

二)选择救援模式:

   1)使用图像界面,上下移动选择Rescue install sysytem,进入救援模式

grub应用配置及修复_grub_09

  二)按Esc键,命令行模式下,看到boot 输入:linux rescue 回车

grub应用配置及修复_应用配置_10

  三)通过救援模式bash切换到根文件系统,通过grub-install进行修复

   各种设置

#####选择语言设置:

grub应用配置及修复_grub_11

 ##### 键盘设置:

grub应用配置及修复_应用配置_12

#####是否启用网络(不需要,则No,如果选择了Yes将要求选择获取IP地址的方式)

 grub应用配置及修复_应用配置_13

##### 正式进入救援模式,并且尝试原有的环境,并将其根挂到/mnt/sysp_w_picpath目录下

  grub应用配置及修复_grub_14

##### 如何切换到原系统:

    grub应用配置及修复_grub_15

##### 开启一个shell:

    grub应用配置及修复_grub_16

(四)救援模式下的操作

##### 进入shell,切换至磁盘上的文件系统根目录

    grub应用配置及修复_grub_17    

##### 切换到已经找到的根文件系统上,使用grub-install 修复grub

grub应用配置及修复_应用配置_18

####reboot重启系统,检测修复情况

grub应用配置及修复_grub_19  

可见修复成功!    

 


8.关于新版grub2

新版的grub-install命令指定安装目录时不再使用--root-directory选项,改为 --boot-directory选项,安装文件不是安装在指定目录的/boot/grub下,而是安装在指定目录的/grub下,具体用法为:

grub-install --boot-directory=DIR Install-Device

举个例子说明,如果 /boot分区为 sda7,/ 分区为sda8,在使用救援模式修复grub2到mbr时使用的命令为:

# 如果是以前的grub2,必须先挂载系统的 / 分区,再把系统的 /boot分区挂载到系统 / 分区下
mount /sda8 /mnt
mount /sda7 /mnt/boot
grub-install --boot-directory=/mnt/boot /dev/sda
  
# 而对于只有 / 分区(假设为 /dev/sda7) ,没有 /boot单独分区的,使用命令为
mount /dev/sda7 /mnt
grub-install --boot-directory=/mnt/boot /dev/sda