GRUB——系统的引导程序简单介绍

这几天对于操做系统是如何引导启动的特征的感兴趣,已经到了不能自拔的状态了,因此索性好好了解一下;php

前面已经说过了,MBR对于系统启动的重要性,这是很少啰嗦;  如今介绍一个 grub ,启动管理器,它能够用于引导不一样的系统;linux

 

grub 是一个怎么样的引导原理?

经过个人实验,我获得的结论就是: 整个grub启动管理器其实也算是有点大的,引导扇区里是放不开的;  因此,grub会往引导扇区(能够是MBR, 也能够是每个分区里面的引导扇区)里面写入部份内容,对于剩余的部分,它会写入到咱们的硬盘分区里面的;在启动时,首先运行引导扇区里的程序, 而后在运行硬盘分区里的程序,最后引导操做系统;工具

对于引导扇区里的程序是如何找到硬盘分区里的程序与配置的,这个就是细节方面的问题了,咱们能够忽略;不过我也是一个好学习的人,我也查了查相关的资料,有的解释以下:学习

来自:做者:js li
连接:https://www.zhihu.com/question/27652991/answer/37500373
来源:知乎
著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。google

grub的话,确定是要在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 的使用:

第一步:咱们下载 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(简体中文)

相关文章
相关标签/搜索