GRUB介绍
GRUB允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数。
其中CenttOS6用的是GRUB 0.X版本,称作Grub Legacy。CenttOS7用的是GRUB 1.X版本,称作Grub2 。
没有GRUB以前,启动代码只能全部放在bootloader中,但是GRUB把代码分为了两部分:
- 1st stage:第一阶段,是mbr中的bootloader,用来引导加载第二阶段代码
- 1.5 stage:因为stage1功能有限,不能完成很多功能,所以stage1先将stage1.5读入内存,通过stage1.5来识别文件系统,才能加载上stage2;
- 2nd stage:第二阶段,不受MBR太小的限制,可以提供复杂的界面甚至是交互式接口,stage1把stage2读入到内存,并且通过stage2进行引导,stage2存放在磁盘分区(/boot/grub);
stage2的配置文件放在/boot/grub/grub.conf或/etc/grub.conf
stage2及内核等都通常放置于一个基本磁盘分区上;
stage2的功用:
- 提供菜单、并提供交互式接口 ,e是编辑模式,c是命令模式
- 加载用户选择的内核或操作系统 ,允许传递参数给内核,可隐藏此菜单
- 为菜单提供保护机制,为编辑菜单进行认证,为启用内核或操作系统进行认证
GRUB的命令行接口:
- find (hd#,#)/PATH/TO/SOMEFILE
在指定磁盘分区寻找文件,存在就可以自动补全 - root (hd#,#)
表示把哪一个磁盘分区设定为根设备 - kernel /PATH/TO/KERNEL_FILE
设定本次启动时用到的内核文件;额外还可以添加许多内核支持使用的cmdline参数; - initrd /PATH/TO/INITRAMFS_FILE
设定为选定的内核提供额外文件的ramdisk;版本号必须和内核版本号完全匹配 - boot
引导启动选定的内核;
手动在grub命令行接口启动系统:
grub> root (hd#,#)
grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE
grub> initrd /initramfs-VERSION-RELEASE.img
grub> boot
配置文件:/boot/grub/grub.conf
启动时的菜单就是grub的配置文件,菜单中显示的内容就是gurb启动时能读取到的文件,并根据文件中的设置显示出来的。title后面显示的内容就是菜单所显示的东西,每一个菜单隐藏着通过缩进的方式指明的三项,每一个菜单相对于linux而言都有一个跟设备文件,内核文件路径,内核传递的参数,已经补充进的initrd文件路径。
配置项:
default=#
#设定默认启动的菜单项;菜单项(title)编号从0开始;
timeout=#
#指定菜单项等待选项选择的时长;
splashimage=(hd#,#)/PATH/TO/XPM_PIC_FILE
#指明菜单背景图片文件路径;
hiddenmenu
#隐藏菜单;
password [--md5] STRING
#菜单编辑认证;
title TITLE
#定义菜单项“标题”, 可出现多次;
root (hd#,#)
#grub查找stage2及kernel文件所在设备分区;为grub的“根”;
kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]
#启动的内核
initrd /PATH/TO/INITRAMFS_FILE
#内核匹配的ramfs文件;
password [--md5] STRING
#启动选定的内核或操作系统时进行认证;
用一块新硬盘安装grub当作启动盘
先在虚拟机中增加一块20g硬盘
查看硬盘信息,发现sda和sdb两块硬盘
[root@localhost ~]# fdisk -l /dev/sd[a-z]
Disk /dev/sda: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000d25f1
Device Boot Start End Blocks Id System
/dev/sda1 * 1 64 512000 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 64 2611 20458496 8e Linux LVM
Disk /dev/sdb: 21.5 GB, 21474836480 bytes
255 heads, 63 sectors/track, 2610 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
创建三个分区,1为启动分区,2为swap交换区,3为根分区
[root@localhost ~]# fdisk /dev/sdb
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0xfbd3997c.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.
Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)
WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
switch off the mode (command 'c') and change display units to
sectors (command 'u').
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-2610, default 1):
Using default value 1
Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +100M
#新建分区1,容量100M,当作启动分区
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (15-2610, default 15):
Using default value 15
Last cylinder, +cylinders or +size{K,M,G} (15-2610, default 2610): +2G
Command (m for help): t
Partition number (1-4): 2
Hex code (type L to list codes): 82
Changed system type of partition 2 to 82 (Linux swap / Solaris)
#新建分区2,容量2G,类型改为swap分区
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 3
First cylinder (277-2610, default 277):
Using default value 277
Last cylinder, +cylinders or +size{K,M,G} (277-2610, default 2610): +5G
#创建分区3,容量5G,当作根分区
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
查看sdb1,2,3挂载成功
[root@localhost ~]# partx -a /dev/sdb
BLKPG: Device or resource busy
error adding partition 1
BLKPG: Device or resource busy
error adding partition 2
BLKPG: Device or resource busy
error adding partition 3
[root@localhost ~]# cat /proc/partitions
major minor #blocks name
8 0 20971520 sda
8 1 512000 sda1
8 2 20458496 sda2
8 16 20971520 sdb
8 17 112423 sdb1
8 18 2104515 sdb2
8 19 5253255 sdb3
253 0 18423808 dm-0
253 1 2031616 dm-1
格式化三个分区
[root@localhost ~]# mke2fs -t ext4 /dev/sdb1
[root@localhost ~]# mke2fs -t ext4 /dev/sdb3
[root@localhost ~]# mkswap /dev/sdb2
把sdb1挂载在mnt/boot上
[root@localhost ~]# mkdir /mnt/boot
[root@localhost ~]# mount /dev/sdb1 /mnt/boot
在硬盘sdb上安装grub,安装在/mnt/下,会自动寻找boot
[root@localhost ~]# grub-install --root-directory=/mnt /dev/sdb
Probing devices to guess BIOS drives. This may take a long time.
Installation finished. No error reported.
This is the contents of the device map /mnt/boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.
(fd0) /dev/fd0
(hd0) /dev/sda
(hd1) /dev/sdb
[root@localhost ~]# ls /mnt/boot/grub/
device.map ffs_stage1_5 minix_stage1_5 stage2 xfs_stage1_5
e2fs_stage1_5 iso9660_stage1_5 reiserfs_stage1_5 ufs2_stage1_5
fat_stage1_5 jfs_stage1_5 stage1 vstafs_stage1_5
用grub-md5-crypt直接生成md5密码
[root@localhost ~]# grub-md5-crypt
Password:
Retype password:
$1$5/h/s/$pWqRGbP18FxkOvaOJkOgv.
拷贝本机/boot/下的内核和img到新启动分区/mnt/boot/下,并配置菜单项
[root@localhost ~]# cp /boot/vmlinuz-2.6.32-504.el6.x86_64 /mnt/boot/vmlinuz
[root@localhost ~]# cp /boot/initramfs-2.6.32-504.el6.x86_64.img /mnt/boot/initramfs.img
[root@localhost ~]# vim /mnt/boot/grub/grub.conf
default=0
timeout=5
password --md5 $1$5/h/s/$pWqRGbP18FxkOvaOJkOgv.#进入命令行要输入密码112233
title CentOS(Express)
root(hd0,0)
password --md5 $1$5/h/s/$pWqRGbP18FxkOvaOJkOgv.#编辑菜单要输入密码
kernel /vmlinuz ro root=/dev/sda3
initrd /initramfs.img
在分区3中创建根下的文件结构,系统启动后运行bash
[root@localhost ~]# mkdir /mnt/sysroot
[root@localhost ~]# mount /dev/sdb3 /mnt/sysroot/
[root@localhost ~]# cd /mnt/sysroot/
[root@localhost sysroot]# mkdir -pv etc bin sbin lib lib64 dev proc sys tmp var usr home root mnt media
[root@localhost sysroot]# cp /bin/bash /mnt/sysroot/bin/
查看启动bash需要哪些依赖
[root@localhost sysroot]# ldd /bin/bash
linux-vdso.so.1 => (0x00007fff83bff000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f7769bcd000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f77699c9000)
libc.so.6 => /lib64/libc.so.6 (0x00007f7769634000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7769df3000)
把需要用到的依赖拷贝到新boot里
[root@localhost sysroot]# cp /lib64/libtinfo.so.5 /mnt/sysroot/lib64/
[root@localhost sysroot]# cp /lib64/libdl.so.2 /mnt/sysroot/lib64/
[root@localhost sysroot]# cp /lib64/libc.so.6 /mnt/sysroot/lib64/
[root@localhost sysroot]# cp /lib64/ld-linux-x86-64.so.2 /mnt/sysroot/lib64/
进行测试,切换到新根,运行bash
[root@localhost sysroot]# chroot /mnt/sysroot/
bash-4.1# exit
exit
设置/init/bash为第一个用户空间进程,而不是/sbin/init,同时设置selinux=0
[root@localhost sysroot]# vim /mnt/boot/grub/grub.conf
default=0
timeout=5
password --md5 $1$5/h/s/$pWqRGbP18FxkOvaOJkOgv.
title CentOS(Express)
root(hd0,0)
password --md5 $1$5/h/s/$pWqRGbP18FxkOvaOJkOgv.
kernel /vmlinuz ro root=/dev/sda3 selinux=0 init=/bin/bash
initrd /initramfs.img
[root@localhost sysroot]# sync
查看第二块硬盘位置,名称
新建一个虚拟机,把启动盘改成上面的第二块硬盘
启动新虚拟机
输入密码112233
成功启动
grub损坏的三种恢复方法
1.直接输入命令恢复
备份mbr
[root@localhost ~]# dd if=/dev/sda of=/root/mbr.bak count=1 bs=512
记录了1+0 的读入
记录了1+0 的写出
512字节(512 B)已复制,0.00634454 秒,80.7 kB/秒
覆盖MBR的前两百字节,grub第一阶段损坏
[root@localhost ~]# dd if=/dev/zero of=/dev/sda bs=200 count=1
记录了1+0 的读入
记录了1+0 的写出
200字节(200 B)已复制,0.00302779 秒,66.1 kB/秒
[root@localhost ~]# sync
输入命令把第一阶段重装,成功恢复。
[root@localhost ~]# grub-install --root-directory=/ /dev/sda
Installation finished. No error reported.
This is the contents of the device map //boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.
# this device map was generated by anaconda
(hd0) /dev/sda
2.grub提示符下恢复
破坏grub
[root@localhost ~]# dd if=/dev/zero of=/dev/sda bs=200 count=1
记录了1+0 的读入
记录了1+0 的写出
200字节(200 B)已复制,0.00216588 秒,92.3 kB/秒
[root@localhost ~]# sync
进入grub --> root --> setup,成功恢复
[root@localhost ~]# grub
Probing devices to guess BIOS drives. This may take a long time.
GNU GRUB version 0.97 (640K lower / 3072K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB
lists possible command completions. Anywhere else TAB lists the possible
completions of a device/filename.]
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.
grub> quit
quit
[root@localhost ~]# sync
3.紧急救援恢复
破坏grub,重启
[root@localhost ~]# dd if=/dev/zero of=/dev/sda bs=200 count=1
记录了1+0 的读入
记录了1+0 的写出
200字节(200 B)已复制,0.00216588 秒,92.3 kB/秒
[root@localhost ~]# sync
[root@localhost ~]# reboot
按ESC键
输入:linux rescue
不需要网络链接
这里会到硬盘中找之前有没有安装过操作系统,如果找到,会把根挂载到现在这个当前小的紧急救援模式/mnt/sysimage目录下,选择Continue。
找到了,挂载在/mnt/systimage下
选择start shell
输入命令切换到之前的根,安装grub,root目录设置为当前根,重启
恢复成功