引导加载程序grub详解
上一章讲到,常见的boot loader(引导加载程序)有LILO和grub,LILO有一大缺点,它只能识别0-1023范围内的柱面构成的分区的内核文件,故已逐渐被grub取代。
Grub(GRand Unified Bootloader)是一个来自GNU项目的多操作系统引导程序,它负责加载内核并移交控制权
1、Grub版本:
CentOS 5、6 Grub 0.97
CentOS 7 Grub2 1.96
2、grub程序由三段组成:
stage1: MBR(0柱面 0磁道 1扇区)中
stage1_5: MBR随后的扇区
stage2: 读取grub.conf配置文件,并实现引导功能的扩展
MBR所给予的空间毕竟太小,容不下较大的引导程序,因此grub程序被分为三段:"stage 1" 被装入磁盘的MBR中;特殊的"stage 1.5"被装入MBR随后的扇区,它能够识别内核和"stage 2"所在分区的文件系统格式并帮助引导"stage 2",它是"stage 1"和"stage 2"之间的纽带;"stage 2"位于文件系统上。stage 2程序和grub.conf可以与内核文件处于不同的分区上(但必须位于同一磁盘),只要"stage 1.5"能够驱动它们各自所在的分区。
在linux中,与启动相关的文件(grub、vmlinuz、initramfs)均位于boot目录下
3、grub的功能
①提供菜单,并提供交互式接口
e: 进入编辑模式
②选择要启动的内核或系统
允许传递引导参数给内核
选择界面可隐藏
③为编辑功能提供保护机制
启用内核文件:
选择运行指定的内核得先输入密码
传递参数:
使用e命令得先输入密码
开机后有三秒种的过渡页面,按任意键可进入菜单页面。在菜单页面可用上下键选择所要启动的内核或内核,按e键进入内核编辑模式,按c键进入grub命令行模式
4、grub命令行接口:
help:查看帮助,即列出命令列表
root (DEVICE):指定哪个分区为接下来要启动的系统或内核文件所在的分区,例如root (hd0,0)
所有硬盘都被识别为hd,
不同的硬盘基于数字标识,从0开始:如hd0, hd1等
同一个硬盘上的不同分区,也使用数字标识,从0开始:如hd0,0 hd1,5
find (DEVICE)/path/to/file:查找文件。当我们不确定内核文件位于哪个分区上时,可使用该命令;提示:grub支持tab补全
kernel /path/to/kernel_file:指定要运行的内核文件,如kernel /vmlinuz-2.6.32-431.el6.x86_64。
【注】:这里的文件路径是相对于内核文件所在分区而言,其开头的“/”不是指操作系统的根,而是指内核所在的分区,因为grub是直接以该分区为入口找寻内核的。若有单独的boot分区,则不能写成kernel /boot/vmlinuz-2.6.32-431.el6.x86_64;在指定的内核位置后通常还指明要挂载的根分区
initrd /path/to/kernel_file:为要运行的内核指定其可用的ramdisk文件,其版本必须与内核版本保持一致
【注】:grub无法识别逻辑卷,因此kernel与initramfs一定不能放于逻辑卷上
boot: 启动此前配置好的内核或系统
5、grub.conf
通过grub命令行接口接入系统比较麻烦,为此,grub提供了一个配置文件/boot/grub/grub.conf(它有一个软链接/etc/grub.conf),grub会读取这个配置文件并按配置参数引导系统
参数:
default=:默认选择第几个title配置的内核或系统,各title从0开始编号
timeout=#:过渡页面显示的超时时长;
splashp_w_picpath=/path/to/some_p_w_picpath_file:指定菜单的背景图片;此图片只能为14bits色,xpm格式,gzip压缩;
hiddenmenu:隐藏菜单
title TILTE STRING:显示于菜单中的标题
root
kernel
initrd
■若由于grub.conf文件错误或丢失而无法自动进入系统,可通过grub命令行引导系统后再手动更改或创建这个文件
[root@node2~]#cat/boot/grub/grub.conf#grub.confgeneratedbyanaconda##Notethatyoudonothavetorerungrubaftermakingchangestothisfile#NOTICE:Youhavea/bootpartition.Thismeansthat#allkernelandinitrdpathsarerelativeto/boot/,eg.#root(hd0,0)#kernel/vmlinuz-versionroroot=/dev/sda2#initrd/initrd-[generic-]version.img#boot=/dev/sdadefault=0timeout=5splashp_w_picpath=(hd0,0)/grub/splash.xpm.gzhiddenmenutitleCentOS(2.6.32-431.el6.x86_64)root(hd0,0)kernel/vmlinuz-2.6.32-431.el6.x86_64roroot=UUID=aa0330af-3681-428c-98e2-ccf2e6f0f686rd_NO_LUKSrd_NO_LVMLANG=en_US.UTF-8rd_NO_MDSYSFONT=latarcyrheb-sun16crashkernel=autoKEYBOARDTYPE=pcKEYTABLE=usrd_NO_DMrhgbquietinitrd/initramfs-2.6.32-431.el6.x86_64.img[root@node2~]#ll/etc/grub/confls:cannotaccess/etc/grub/conf:Nosuchfileordirectory[root@node2~]#ll/etc/grub.conflrwxrwxrwx.1rootroot22Aug604:44/etc/grub.conf->../boot/grub/grub.conf[root@node2~]#cp/boot/{vmlinuz-2.6.32-431.el6.x86_64,initramfs-2.6.32-431.el6.x86_64.img}/#将boot目录下的内核和临时根文件复制一份到根分区下[root@node2~]#ls/bindevhomeliblost+foundmiscnetprocsbinsrvtmpvarbootetcinitramfs-2.6.32-431.el6.x86_64.imglib64mediamntoptrootselinuxsysusrvmlinuz-2.6.32-431.el6.x86_64[root@node2~]#vim/etc/grub.conf...default=0timeout=5splashp_w_picpath=(hd0,0)/grub/splash.xpm.gzhiddenmenutitleCentOS(2.6.32-431.el6.x86_64)root(hd0,0)kernel/vmlinuz-2.6.32-431.el6.x86_64roroot=UUID=aa0330af-3681-428c-98e2-ccf2e6f0f686rd_NO_LUKSrd_NO_LVMLANG=en_US.UTF-8rd_NO_MDSYSFONT=latarcyrheb-sun16crashkernel=autoKEYBOARDTYPE=pcKEYTABLE=usrd_NO_DMrhgbquietinitrd/initramfs-2.6.32-431.el6.x86_64.img#添加如下几行,构成一个新的启动项titletestCentos#新的标题root(hd0,1)#现在根分区下也有内核和临时根文件,根分区为sda2,故写成(hd0,1)kernel/vmlinuz-2.6.32-431.el6.x86_64roroot=/dev/sda2initrd/initramfs-2.6.32-431.el6.x86_64.img
6、grub保护机制:可防止恶意用户随意进入单用户模式修改root密码
①生成密码:
grub-md5-crypt
②保护所有内核,需要在title之外添加
password --md5 密码串
③保护使用某内核,则需要在内核对应的title之下添加
password --md5 密码串
[root@node2~]#grub-md5-crypt#生成密码Password:Retypepassword:$1$oWUbV$Sb/PsrhmkE5bUJPMJGn871[root@node2~]#vim/etc/grub.conf...default=0timeout=5splashp_w_picpath=(hd0,0)/grub/splash.xpm.gzhiddenmenupassword--md5$1$oWUbV$Sb/PsrhmkE5bUJPMJGn871#添加于title之外可保护所有内核titleCentOS(2.6.32-431.el6.x86_64)root(hd0,0)kernel/vmlinuz-2.6.32-431.el6.x86_64roroot=UUID=aa0330af-3681-428c-98e2-ccf2e6f0f686rd_NO_LUKSrd_NO_LVMLANG=en_US.UTF-8rd_NO_MDSYSFONT=latarcyrheb-sun16crashkernel=autoKEYBOARDTYPE=pcKEYTABLE=usrd_NO_DMrhgbquietinitrd/initramfs-2.6.32-431.el6.x86_64.imgtitletestCentospassword--md5$1$oWUbV$Sb/PsrhmkE5bUJPMJGn871#可保护使用指定内核root(hd0,1)kernel/vmlinuz-2.6.32-431.el6.x86_64roroot=UUID=aa0330af-3681-428c-98e2-ccf2e6f0f686initrd/initramfs-2.6.32-431.el6.x86_64.img
7、安装grub的方式:
方法1:使用grub-install命令
grub-install [--root-directory=DIR] DEVICE
DEVICE:针对哪个磁盘安装
--root-directory=DIR:指定grub映像文件(主要是“stage 2”)的存放位置,默认为当前系统根目录。grub-install会在指定的目录下创建boot/grub/的层级目录,并将生成的“stage 2”置于DIR/boot/grub/下。因为内核与initramfs文件通常位于boot目录下,故一般将DIR指定为boot目录的父目录;当然,我们也可以指定为其它目录,但要手动编辑grub.conf文件重新指明内核文件的位置。
例如 mount /dev/sdb1 /mnt/boot
grub-install --root-directory=/mnt/ /dev/sdb
方法2:输入grub命令进入grub命令行
root (hd0,0):相当于上面的--root-directory=DIR
setup (hd0):为哪个磁盘安装
quit:退出
情景1:grub损坏但系统还未关闭或重启,此时可直接使用上面的两种方法修复
[root@node2~]#ddif=/dev/zeroof=/dev/sdabs=400count=1#将MBR中的引导加载程序冲刷掉,注意不能殃及分区表1+0recordsin1+0recordsout400bytes(400B)copied,0.000324129s,1.2MB/s[root@node2~]#rm-f/boot/grub/stage2#将"stage2"也删除[root@node2~]#grub-install/dev/sda#使用grub-install的方式安装grubInstallationfinished.Noerrorreported.Thisisthecontentsofthedevicemap/boot/grub/device.map.Checkifthisiscorrectornot.Ifanyofthelinesisincorrect,fixitandre-runthescript`grub-install'.#thisdevicemapwasgeneratedbyanaconda(hd0)/dev/sda[root@node2~]#ll/boot/grub/stage2#已重新生成"stage2"-rw-r--r--1rootroot126100Oct2822:19/boot/grub/stage2[root@node2~]#ddif=/dev/zeroof=/dev/sdabs=400count=11+0recordsin1+0recordsout400bytes(400B)copied,0.000368562s,1.1MB/s[root@node2~]#grubProbingdevicestoguessBIOSdrives.Thismaytakealongtime.GNUGRUBversion0.97(640Klower/3072Kuppermemory)[MinimalBASH-likelineeditingissupported.Forthefirstword,TABlistspossiblecommandcompletions.AnywhereelseTABliststhepossiblecompletionsofadevice/filename.]grub>root(hd0,0)root(hd0,0)Filesystemtypeisext2fs,partitiontype0x83grub>setup(hd0)#使用方法二安装grubsetup(hd0)Checkingif"/boot/grub/stage1"exists...noCheckingif"/grub/stage1"exists...yesCheckingif"/grub/stage2"exists...yesCheckingif"/grub/e2fs_stage1_5"exists...yesRunning"embed/grub/e2fs_stage1_5(hd0)"...27sectorsareembedded.succeededRunning"install/grub/stage1(hd0)(hd0)1+27p(hd0,0)/grub/stage2/grub/grub.conf"...succeededDone.grub>quitquit
情景2:grub损坏且系统已关闭,这时候可用如下两种方式修复:
方式一:将故障磁盘挂载于其它正常主机上重装grub
①手动将node1的磁盘的grub损毁并关机
[root@node1~]#ddif=/dev/zeroof=/dev/sdabs=400count=11+0recordsin1+0recordsout400bytes(400B)copied,0.000164892s,2.4MB/s[root@node1~]#shutdown-hnow
②将node1的磁盘移除并添加到node2上(关于 如何在不重启的情况下识别新增硬盘 见末尾补充部分)
③挂载node1的分区并安装grub,安装完后卸载
[root@node2~]#lsblkNAMEMAJ:MINRMSIZEROTYPEMOUNTPOINTsda8:0030G0disk├─sda18:10200M0part/boot├─sda28:2010G0part/└─sda38:302G0part[SWAP]sdb8:16030G0disk#node1的硬盘在node2上被识别为sdb├─sdb18:170200M0part├─sdb28:18010G0part└─sdb38:1902G0partsr011:014.2G0rom[root@node2~]#mkdir/mnt/boot[root@node2~]#mount/dev/sdb1/mnt/boot[root@node2~]#grub-install--root-directory=/mnt/dev/sdb/dev/sdbdoesnothaveanycorrespondingBIOSdrive.#注意:若这里提示找不到相应的BIOS驱动,可使用选项--recheck重新检查磁盘,如下:[root@node2~]#grub-install--root-directory=/mnt--recheck/dev/sdbProbingdevicestoguessBIOSdrives.Thismaytakealongtime.Installationfinished.Noerrorreported.Thisisthecontentsofthedevicemap/mnt/boot/grub/device.map.Checkifthisiscorrectornot.Ifanyofthelinesisincorrect,fixitandre-runthescript`grub-install'.(fd0)/dev/fd0(hd0)/dev/sda(hd1)/dev/sdb[root@node2~]#umount/mnt/boot
④从node2上移除node1的硬盘后再装回node1启动即可
方式二:插入系统光盘进入救援模式修复
①将Linux安装光盘放入光驱。硬盘的MBR损坏后,BIOS会自动从光盘引导,进入菜单页面后,选择进入“救援模式”
②系统会检测硬件,引导光盘上的Linux环境,依次提示选择救援模式下使用的语言、键盘以及是否需要设置网络,可按需选择
③接下来系统会查找根分区,出现挂载提示,硬盘的根分区将被挂载到光盘Linux环境的/mnt/sysp_w_picpath目录下;默认选项“continue”表示挂载权限为读写,“Read-only”为只读,如。此处,因为要对系统进行修复,故需要有读写权限,选择“continue”。
④按提示执行“chroot /mnt/sysp_w_picpath”切换根环境并安装grub,然后退出shell并重启即可
chroot:切换根环境,即以指定的目录作为根
用法:chroot /path/to/directory [SHELL]
例如 chroot /mnt/sysp_w_picpath /bin/tcsh #将sysp_w_picpath作为根目录,并运行其中的tcsh
补充:如何实现不重启linux而识别新增硬盘?
新增硬盘后,使用如下命令识别:
echo "scsi add-single-device w x y z" > /proc/scsi/scsi
其中:
w 是主机适配器标识,第一个适配器为零(0)
x 是主机适配器上的SCSI通道,第一个通道为零(0)
y 是设备的SCSI标识
z 是LUN号,第一个LUN为零(0)
执行上述命令前,要先查看/proc/scsi/scsi,确定新增硬盘的ID
相反,在不重启系统的情况下将硬盘从系统中移除的命令为:
echo "scsi remove-single-device w x y z" > /proc/scsi/scsi
使用该命令前需确保该硬盘已卸载
[root@node2~]#lsblkNAMEMAJ:MINRMSIZEROTYPEMOUNTPOINTsda8:0030G0disk├─sda18:10200M0part/boot├─sda28:2010G0part/└─sda38:302G0part[SWAP]sr011:014.2G0rom[root@node2~]#cat/proc/scsi/scsiAttacheddevices:Host:scsi0Channel:00Id:00Lun:00Vendor:VMware,Model:VMwareVirtualSRev:1.0Type:Direct-AccessANSISCSIrevision:02Host:scsi2Channel:00Id:00Lun:00Vendor:NECVMWarModel:VMwareIDECDR10Rev:1.00Type:CD-ROMANSISCSIrevision:05#可以看到,当前最大ID号为00,因此新增硬盘的ID号应为01[root@node2~]#echo"scsiadd-single-device0010">/proc/scsi/scsi[root@node2~]#lsblkNAMEMAJ:MINRMSIZEROTYPEMOUNTPOINTsda8:0030G0disk├─sda18:10200M0part/boot├─sda28:2010G0part/└─sda38:302G0part[SWAP]sdb8:16030G0disk#新增硬盘已被识别出来├─sdb18:170200M0part├─sdb28:18010G0part└─sdb38:1902G0partsr011:014.2G0rom[root@node2~]#echo"scsiremove-single-device0010">/proc/scsi/scsi#移去该硬盘[root@node2~]#lsblkNAMEMAJ:MINRMSIZEROTYPEMOUNTPOINTsda8:0030G0disk├─sda18:10200M0part/boot├─sda28:2010G0part/└─sda38:302G0part[SWAP]sr011:014.2G0rom
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。