首页 > 代码库 > 详解 linux中的grub
详解 linux中的grub
grub是什么:
grub是引导操作系统的程序,它会根据自己的配置文件,去引导内核,当内核被加载到内存以后,
内核会根据grub配置文件中的配置,找到根分区所使用的文件系统对应的驱动,通过根分区文件系统
对应的驱动,挂载根分区,从而达到启动操作系统的目的。
在了解grub以前,请先大体上了解一下centos5/6的启动过程,然后再理解grub就更容易了,
还记的我们以前总结过的centos5系统启动流程吗,如下图,此处我们重点讨论下图红框中的步骤。
centos5/6中使用grub作为bootloader,也就是说,操作系统想要启动,就要靠它,
早期的linux中,使用LILO(linux 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的作用,它用于引导操作系统启动,先引导内核,由内核去挂载根分
区所以,在配置文件中,我们能够看到kernel、root、initrd等关键字,这些关键字所指定的值,都是系统
引导时所必须的,现在,我们对这些配置项进行编号,并对他们一一进行解释。
下面解释的编号对应图一中的编号:
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 ,那么,
以此类推,如果kernel和initrd文件存在于第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。
为了方便大家对比着解释信息查看,我把图一中的下半部分截取一份。
6、title直译为"标题",可以理解为一个grub引导的配置列表,可以存在多个title,也就是说可以用不同的
配置去引导系统,title下面配置项都属于当前title,我们可以看到,图一中的title是CentOS 6 (2.6.32-642.el6.x86_64),
也就是说,此title下面的引导配置项,都是属于CentOS 6 (2.6.32-642.el6.x86_64)这个菜单的引导配置项。
7、指定这个配置列表中的kernel和initrd所在的分区,这个配置项就是前面编号2中所描述的kernel文件所在
的分区,跟编号2的意思完全一样(具体意思参考编号2),只是编号2是在注释中,编号7是CentOS 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的配置搞混淆了。
而红框以外还有很多参数,很多都是启动内核时使用的参数,所以暂时不解释了。
9、initrd/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