首页 > 代码库 > 详解 linux中的grub

详解 linux中的grub

grub是什么:


        grub是引导操作系统的程序,它会根据自己的配置文件,去引导内核,当内核被加载到内存以后,

 内核会根据grub配置文件中的配置,找到根分区所使用的文件系统对应的驱动,通过根分区文件系统

 对应的驱动,挂载根分区,从而达到启动操作系统的目的。


   在了解grub以前,请先大体上了解一下centos5/6的启动过程,然后再理解grub就更容易了,

  还记的我们以前总结过的centos5系统启动流程吗,如下图,此处我们重点讨论下图红框中的步骤。


技术分享






    centos5/6中使用grub作为bootloader,也就是说,操作系统想要启动,就要靠它,

 早期的linux中,使用LILOlinux loader)进行操作系统的引导工作,但是因为LILO

    的功能比较简单,随着发展,出现了grub,  GRUB:Grand Unified Bootloader

    

   centos5\6中使用的是grub的0.97版本:grub legacy

   centos7中使用的是grub2

   此处,我们讨论的grub就是grub legacy

 




grub legacy的3个阶段:


grub的代码分三个阶段被加载.

grub stage 1 :

存在启动硬盘的0柱面,0磁道,第一个扇区中,即MBR中,MBR的前446个字节为以引导代码,

也就是grub stage 1,所谓的stage1  ,作用只有一个,就是找到grubstage1.5,然后将其加载的

到内存。

 

            grub stage 1.5 :

        它的作用就是用来识别常见的不同类型的文件系统,从而找到"/boot目录所在的分区"对应的文件

        系统的驱动,驱动多大、存在于哪些扇区中,这些都是在安装操作系统的时候根据用户的设置自

动生成的,我们有了"/boot目录所在分区"的文件系统驱动,那么/boot/grub/stage2这样的比较

大的文件可以直接操作了。

 

            grub stage 2 :

        grub真正的核心程序,能让用户以菜单方式将操作系统加载、新增参数、修改选项,这些全都是

stage2的功用,  前面的grub stage 1和grub stage 1.5所做的事情就是为了运行grub stage 2 ,

然后由stage 2借助grub.conf再去引导系统启动。

 




 与grub相关的文件:


    grub的代码都是二进制代码,我们暂时不做研究,grub是引导操作系统的程序,它会根据自己的

配置文件,去引导内核,当内核被加载到内存以后,内核会根据grub配置文件中的配置,找到根分

区所使用的文件系统对应的驱动,通过根分区文件系统对应的驱动,挂载根分区,从而启动系统,

我们刚才提到了"内核""根分区""文件系统的驱动"这些名词,现在,我们来看看他们都长什么

样子,先来看看"内核",如下图

技术分享

  没错,/boot/目录下的vmlinuz-2.6.32-642.el6.x86_64就是内核文件,2.6.32-642就是内核的版本号,

el6是操作系统的版本,x86_64是内核对应的平台,这个内核文件就是centos6中最最重要的核心

grub就是引导它,从而完成启动操作系统的目的。grub把内核加载到内存以后,内核需要去挂

载根分区,但是,如果要使用根分区,则必须获取到根分区文件系统的驱动,那么,这个驱动放

在哪里呢,其实你已经看到了,如下图

技术分享


  根分区文件系统的驱动就放在initramfs-2.6.32-642.el6.x86_64.img这个文件中,它和内核文件都

/boot目录中。内核通过这个文件,即可获得  根分区所使用的文件系统  对应的驱动,然后即可

挂载根分区,但是,如果有多个分区,内核怎么知道那个分区是根分区呢?或者说,如果有多个

设备,内核怎么知道根文件系统挂载在哪个设备上呢?内核是不知道的,所以,内核需要grub告诉

它,那grub又怎么知道根文件系统在哪里呢?grub需要读取自己的配置文件,配置文件中保存了根

文件系统的位置。





grub配置文件详解:


 grub的配置文件是什么样子的呢,/boot/grub/grub.conf文件就是grub的配置文件,现在,我们

就来了解一下它,通过了解grub.conf中的配置,来了解grub的工作流程,打开grub.conf文件,

如下图一内容。

技术分享

  我们在前面已经重复解释了grub的作用,它用于引导操作系统启动,先引导内核,由内核去挂载根分

区所以,在配置文件中,我们能够看到kernelrootinitrd等关键字,这些关键字所指定的值,都是系统

引导时所必须的,现在,我们对这些配置项进行编号,并对他们一一进行解释。

 

下面解释的编号对应图一中的编号:

1、从注释可以看出,这个grub.conf是由anaconda程序生成的,anaconda就是我们安装操作系统时候使

用的安装向导。

 

2、注释中有提示我们:你有一个单独boot分区,这意味着kernel文件和initrd文件的路径是相对于/boot

区来说的,因为我们的boot分区对应的设备是/dev/sda1,所以,此处用root(hd0,0)表示,其中,hd0表示第

一块硬盘,逗号后面的0表示第一个分区,也就是说(hd0,0)表示第一块硬盘的第一个分区,也就是我们正

在使用的/dev/sda1, 有的同学会产生疑问,sda1为什么不用(sda,1)表示呢,我把这个问题理解成"历史问

",以前大家习惯了使用这种方式去表示,所以一直没有改变它。

  总之:root (hd0,0)表示kernel文件和initrd文件所在分区,而不是指"根分区"

上图一中的情况是"/boot目录"对应一个单独的分区,此处我们称为boot分区,而且boot分区是第一块盘的

第一个分区,下图二中的情况为"/boot目录"并不是一个单独的分区,所以/boot目录在根分区中,"/"对应

根分区,而且,根分区并不是所在硬盘的第一个分区,所以,我们可以看到,下图二中的root (hd0,1) 的

意思是kernel文件和initrd文件在第一块硬盘的第二个分区上,也就是我们平常使用的/dev/sda2 ,那么,

以此类推,如果kernelinitrd文件存在于第3块硬盘的第2个分区上,我们应该使用root(hd2,1)表示。

技术分享

 

 

3、其中default=0表示有多个grub引导菜单时,选择哪一个作为默认启动引导菜单,也就是说,当有多个

title时,默认选择哪个title中的配置作为默认引导配置,default=0表示默认使用第一个title菜单中的配

置。其中timeout=5表示如果5秒以内,用户没有选择任何一个title,则使用default中指定的title菜单中

的配置进行引导。

 

4、引导时的背景图片,此项不建议设置,因为如果此项配置的背景图片并不存在,那么在引导时会出现

错误,此配置可以对比图一和图二,就可以更加深刻的理解(hd0,0)的含义。

 

5、表示在系统启动时,隐藏所有title菜单,并不让用户直接看到启动菜单,如果用户不做任何干预,则默

认启动default所指定的title

 


为了方便大家对比着解释信息查看,我把图一中的下半部分截取一份。

技术分享


6title直译为"标题",可以理解为一个grub引导的配置列表,可以存在多个title,也就是说可以用不同的

配置去引导系统,title下面配置项都属于当前title,我们可以看到,图一中的titleCentOS 6 (2.6.32-642.el6.x86_64)

也就是说,此title下面的引导配置项,都是属于CentOS 6 (2.6.32-642.el6.x86_64)这个菜单的引导配置项。

 

7、指定这个配置列表中的kernelinitrd所在的分区,这个配置项就是前面编号2中所描述的kernel文件所在

的分区,跟编号2的意思完全一样(具体意思参考编号2),只是编号2是在注释中,编号7CentOS 6 (2.6.32-642.el6.x86_64)的配置项,也就是说,编号7只在CentOS 6 (2.6.32-642.el6.x86_64)这个title的范围内生

效,而且再次强调:

root (hd0,0)表示kernel文件和initrd文件所在分区,而不是指"根分区"

 

8、此处我们只说明红框中的内容,红框中的内容也是grub配置文件中的核心,它指明了kernel文件的位置,

我们说过grub需要将内核加载到内存,所以grub需要知道kernel文件到底在哪里,图一中,此项的配置为

kernel /vmlinuz-2.6.32-642.el6.x86_64,而我们说过,vmlinuz-2.6.32-642.el6.x86_64文件存在于/boot/目录中,

而图一中,/boot目录为一个单独的分区,也就是说在图一中,此项可以写成kernel (hd0,0)/vmlinuz-2.6.32-642.el6.x86_64

但是,因为我们在编号7中已经指定了root(hd0,0),所以,图一中,此项写成kernel /vmlinuz-2.6.32-642.el6.x86_64

同样的道理,我们看看图二,图二中,/boot目录并不是对应一个单独的分区,也就是说/boot目录在"/"

录下,而"/"目录对应的分区为(hd0,1), 所以,图二中,此项写成kernel /boot/vmlinuz-2.6.32-642.el6.x86_64 ,

么,也就是说,到底怎样配置这些参数,都是非常灵活的,如果我们手动对这些参数进行配置,必须根据

实际情况进行配置,而不能死记硬背,我们可以套用这些格式,但是不能被这些格式"套住"。其中,ro

示以只读的方式挂载根分区,此配置是为了安全,并不是必须这样配置,不写ro不会影响启动。

root=UUID=488de085-08b9-4554-917e-4bc78059a998指明了根分区所对应的设备,此处使用了UUID的语法表

示分区,我们也可以使用设备名的表示方法,表示根分区的所在位置,比如,图一中,"/boot"对应的分区是

/dev/sda1, "/"对应的分区是/dev/sda2, 那么,root=UUID=488de085-08b9-4554-917e-4bc78059a998则可以使用

另一种表达方式,root=/dev/sda2,其实它的作用就是告诉内核,根分区的位置在哪里,明白了吗?那么,

我们来想一个问题,如果根文件系统创建在逻辑卷上,而没有使用分区,这个时候,我们应该怎么指定呢?

没错,指定对应的逻辑卷即可,比如root=/dev/mapper/vg0-root,当然,也可以设置为root=UUID=逻辑卷的UUID

其实,如果根文件系统在一个分区上,我们最好还是使用UUID的写法比较好,因为,在添加或删除分区时,

分区对应的设备名称有可能发生改变,所以,使用UUID表示根的位置,是最保险的做法。

注意:这个配置项的root才表示根分区,或者表示根文件系统对应的逻辑卷,不要跟编号7的配置搞混淆了。

而红框以外还有很多参数,很多都是启动内核时使用的参数,所以暂时不解释了。

 

9initrd/initramfs-2.6.32-642.el6.x86_64.img 这个设置是什么意思呢,我们在一开始就解释过,如果内核想

要挂载根分区,内核必须能够驱动根分区,所以,内核必须获取到根分区所使用的文件系统的驱动,initramfs-2.6.32-642.el6.x86_64.img这个文件中就包含了内核所需要寻找的驱动。

initrd就是关键字,它指定了initramfs文件的位置,而在centos5中,此文件的文件名就叫initrd-2.6.18-194.el5.img

centos6中,initrd文件才改名为initramfs,细心的你应该已经发现,图一和图二中的此项配置不是完全一样的,

图一中,此项配置为initrd /initramfs-2.6.32-642.el6.x86_64.img

图二中,此项配置为initrd /boot/initramfs-2.6.32-642.el6.x86_64.img

你肯定知道我要说什么了,没错,我又要开始啰嗦了,它们的配置之所以不同,是因为,图一中"/boot"目录对

应的是一个单独的分区,图二中"/boot"目录并没有对应一个单独的分区,而是在"/"目录中,

所以,再次强调,具体的配置要根据实际情况而定,一定不要生搬硬套。


本文出自 “学思行知” 博客,谢绝转载!

详解 linux中的grub