一、什么是grub
GRand Unified Bootloader,由名字就能看出,这是一个多重开机管理系统。目前在centos 6.x等linux发行版上使用的是0.97版本,在centos 7系列用的是grub2。这里先讨论一下grub0.97版本,grub2的机制已经变了,后续讨论。
二、grub引导的三个阶段
Centos 6.8中在/boot/grub目录下,有如下文件:
其中,有stage1,stage2以及若干个stage1.5。
看字面意思,其启动顺序就是stage1àstage1.5àstage2
stage1执行系统启动,其目的是加载stage2,并将控制权转移到stage2中。stage1.5的作用是连接stage1与stage2。
在stage2阶段,将会读取grub.conf配置文件,根据配置进行设置和显示操作系统选择界面。Stage2包含了除自引导之外的所有功能,是整个grub引导的核心。
首先说stage1,stage1可以看作是booloader的备份,但是又不尽相同,注意,千万不可以将stage1直接覆盖bootloader。
磁盘的第一个扇区,大小为512B,bootloader安装在这个扇区中,占用前446B。然后64B是分区表,接着2B是Magic Number。也就是446+64+2=512
使用dd命令导出磁盘第一个扇区:
dd if=/dev/sda of=./mbr bs=512 count=1
用hexdump打开
红色部分为bootloader,蓝色部分为partation table分区表,黄色部分为Magic Number。
备份bootloader
dd if=/dev/sda of=./mbr.img bs=446 count=1
恢复bootloader
dd if=./mbr.img of=/dev/sda bs=446 count=1
资料中显示,stage1.S被放在0面0道的第1扇区,start.S被放在0面0道的第2扇区,而与boot分区相关的文件系统的xxfs_stage1_5被放在0面0道第3扇区开始的扇区里,其占据的扇区数目与该stage1_5文件的大小有关。而其余的stage1_5以及stage2都作为文件被存放在boot分区里。
可是我在测试环境中第二个扇区、第三个扇区一直到第64个扇区,都是空的。可以认为,stage2在磁盘中的位置被写死到stage1中,stage1无需识别文件系统,直接从磁盘指定位置读取指定长度的段。
这里是个疑问,会在以后的学习中注意。
三、grub的安装与修复
grub的安装有两种方式,分别适应两钟不同的情况。
1、 mbr损坏,但是/boot/grub下所有文件都正常,我们只需要修复mbr。
进入救援模式之后,启动grub shell
grub> root (hd0,0) //根据个人启动分区的不同进行设置。 root(hd0,0) Filesystem type is ext2fs, partition type 0x83 grub> setup (hd0) setup(hd0) Checking if "/boot/grub/stage1"exists... no Checking if "/grub/stage1" exists...yes Checking if "/grub/stage2" exists...yes Checking if "/grub/e2fs_stage1_5"exists... yes Running "embed /grub/e2fs_stage1_5(hd0)"... 27 sectors are embedded. succeeded Running "install /grub/stage1 (hd0)(hd0)1+27 p (hd0,0)/grub/stage2 /grub/grub.conf"... succeeded Done.
2、 替换引导。比如,linux在安装时就没有安装引导,或者以前用的是lilo,而现在想用grub。
使用grub-install命令即可。
grub-install /dev/sda //选定你要安装bootloader的磁盘或者分区。
这个命令会自动创建/boot/grub目录,并自动生成stage1 stage1.5和stage2,然后将stage1写入mbr。
四、grub的设置
在这里,首先可以了解一下grub.conf的结构。
default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.32-642.4.2.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-642.4.2.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=autord_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-642.4.2.el6.x86_64.img title CentOS (2.6.32-431.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-431.el6.x86_64.img
default=0 //指定默认的启动项,也就是第几个title。这里是编号为0的title。
timeout=5 //超时时间,5秒钟。5秒钟内不进行选择,那么将会自动启动default所指定的title。
splashimage=(hd0,0)/grub/splash.xpm.gz //背景图片。这个没有什么实质性的功能hiddenmenu //隐藏菜单,这个没啥实质性功能,就是一个定制性的。
pasword zhou //但是这种方式是明文密码,任何人打开grub.conf都能看到。
password --md5$1$jWNz8/$aqDO19NluYIX1zkc1SVGp. //这种是密文密码,虽然可以修改,但是不可以被简单破解。
下面将要开始指定title,这里所写出的title都会在grub的启动列表中显示出来。每个title即指定一个启动,每个启动必须包括三个元素:
1、root元素:其实就是/boot分区所在位置。有些不寻常的时候,安装系统时,安装介质的识别导致磁盘顺序在系统中错误,root 元素的值在移除安装介质后与系统/boot分区所在的位置不一致。
2、kernel元素:指定Linux的kernel文件,同时指定各属性。具体属性参照扩展区域,这里实质性意义也不大,不太常用到修改kernel的参数。
3、initrd元素:指定initramfs所在的位置(6.x系列),initramfs有系统安装时根据系统硬件选择性编译的驱动,所以它不具备通用性,大部分情况下安装时产生的initramfs只能在当前系统中使用。
title CentOS (2.6.32-642.4.2.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-642.4.2.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS.UTF-8 rd_NO_MDrd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-642.4.2.el6.x86_64.img
password --md5$1$jWNz8/$aqDO19NluYIX1zkc1SVGp. //把密码设置在这里,意义完全不同。这里的作用是启动密码,如果要启动该内核,必须输入密码。这个也是拿来玩的东西。
title CentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 roroot=/dev/mapper/VolGroup-lv_root rd_NO_LUKS.UTF-8 rd_NO_MDrd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-431.el6.x86_64.img
综上所述,如果我们要写一个最简化的grub.conf,格式可以如下:
timeout 5 //这个选项最好有,否则重启linux后不会自动进入系统,而是等待启动项选择。 title linux root (hd0,0) kernel /vmlinuz-2.6.32-642.4.2.el6.x86_64 ro root=/dev/sda3 initrd /initramfs-2.6.32-642.4.2.el6.x86_64.img
五、grub的排错
linux偶尔会遇到开机无法启动的情况,无法启动的原因有很多,这里简单写一下常见的。
1、 开机直接显示grub shell。
其实这种是最为容易解决的。因为能出现grub shell说明正常进入了stage2,但是由于grub.conf无法找到或者grub.conf中所写入的配置不正确,导致grub无法引导启动。
如果是grub.conf文件的位置被修改而无法找到了,那么在进入grub shell后可以手动查找grub.conf文件,然后
grub>configfile /grub/grub.conf.bak
如果是grub.conf配置出错,或者不存在了。
针对这种问题,可以手动指定grub.conf中title模块的3个元素进行启动。
grub>root (hd0,0) grub>kernel / vmlinuz-2.6.32-431.el6.x86_64 roroot=/dev/sda3 grub>initrd /initramfs-2.6.32-431.el6.x86_64.img grub>boot
这样就可以直接进入系统,然后针对grub.conf进行修改即可。