grub启动程序配引导置及命令行接口详解

前言

Linux系统的启动引导程序有LiLo和grub,但由于LILO的缺陷——只能识别0-1023范围内的柱面构成的分区中的内核文件,因此目前已逐渐被grub所取代,本篇主要围绕grub legacy开展描述。

grub的版本

grub全称为Grand Unified Bootloader,grub的版本经过多年的发展,其现有版本分为grub 0.X(grub legacy) 和grub 1.X(grub 2)。其中目前Centos 7已经采用grub2位启动引导程序,Centos6和Centos5 普遍沿用grub legacy版本。

grub的三个阶段

grub引导程序分为三个阶段:
1、stage1:用于启动Boot loader来加载stage2的内容至内存中;
2、stage1_5:其能够识别内核和stage2所在的分区的文件系统格式类型,帮助引导stage2.
3、stage2:读取grub.conf 配置文件,并实现引导功能的扩展;

在Linux系统中,与系统启动相关的文件均存储在/boot目录下,如grub、vmlinuz、initramfs等等。

与grub相关的配置文件

与grub相关的配置文件包括:/etc/grub.conf和/boot/grub/grub.conf,其实/etc/grub.conf是指向/boot/grub/grub.conf的软链接,grub程序在引导启动时会读取这个配置文件并按照该文件的配置参数引导启动系统。
通常其内容为:

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
title CentOS 6 (2.6.32-642.el6.x86_64)
    root (hd0,0)
    kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=VolGroup/lv_swap crashkernel=auto LANG=zh_CN.UTF-8 rd_LVM_LV=VolGroup/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
    initrd /initramfs-2.6.32-642.el6.x86_64.img

default=0:表示有多个grub引导菜单时,选择哪一个作为默认启动引导菜单,default=0表示默认使用第一个title菜单中的配置;
timeout=5:在grub选择菜单中,5秒内,如果用户没有选择任何一个title,则使用default中指定的titile菜单中的配置进行启动。
splashimage:指定引导菜单中的背景图片的路径;
titile:指定title菜单到的名称;
root:表示kernel和initrd文件所在的分区路径,而不是“根分区”;其设置格式为:root (hd#,#),硬盘均会被识别为hd,第一个#表示第几个硬盘,从0开始;地第二个#表示同一个硬盘上的不同分区,也使用数字标识,从0开始;
kernel:通常用于指定要运行的内核文件路径,如:/vmlinuz-2.6.32-642.el6.x86_64;另外也可在其后设置相关的内核参数,如:ro表示只读,root表示指定根分区所在路径,关闭selinux等等;
initrd:为内核运行指定其可用的ramdisk文件,其版本须与内核版本相一致;

grub程序的功能

1、提供引导菜单,并提供交互式的命令行接口;在菜单界面,按e可进入编辑模式,用于编辑菜单,按c可以进入命令模式;
2、加载用户选择的内核或操作系统,并允许传递相应的内核参数给内核;可选择隐藏此菜单;
3、为菜单提供保护机制,可为编辑菜单设置认证或为启用内核或操作系统进行认证;

在系统开机启动过程中,有几秒的过渡页面,此时按任意键可进入到菜单页面中:


按任意键进入菜单页面

进入到菜单页面后,如果存在着多个内核,此时可按上下键选择需要启动的内核,或者按e进入内核编辑模式,按c可进入grub的命令行模式。


grub菜单

grub的命令行接口

在菜单页面按c即可进入命令行接口,在此命令行接口, 我们可以配置相关的grub设置,如指定root 路径、kernel文件的路径等等。grub命令行接口的常用指令有:

help:查看命令帮助;
root (DEVICE):指定系统和内核文件所在的分区,如root(hd0,0)。
find  (hd0,0) /path/to/file:用于查找对应分区下的文件。常用于当不确认内核文件在哪个分区时,可使用此命令确认文件所在路径;支持tab补全;
kernel /path/to/kernel_file:用于指定要运行的内核文件。
initrd /path/to/kernel_file:指定initrd文件;
boot:以当前配置好的grub配置启动系统;
grub的命令行接口

grub保护机制

grub程序提供了相关的认证机制用于系统保护,如防止恶意用户随意通过单用户模式修改root密码或启动其他内核。
设置认证的方法为:在相应的grub.conf配置文件中,添加passwd -md5 STRING。
如下图为提供grub菜单的编辑认证:

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password --md5 $1$3WOVb/$a0JViRBPU3q.ibdBsuFSn/  #用户在grub菜单界面要输入相应的密码才能对进入相关的编辑模式或命令行模式
title CentOS 6 (2.6.32-642.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=VolGroup/lv_swap crashkernel=auto LANG=zh_CN.UTF-8 rd_LVM_LV=VolGroup/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-642.el6.x86_64.img
对菜单界面的编辑进行密码认证

下述为为对应的内核启动提供密码认证:

default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS 6 (2.6.32-642.el6.x86_64)
        root (hd0,0)
        password --md5 $1$3WOVb/$a0JViRBPU3q.ibdBsuFSn/   #
        kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS rd_NO_MD rd_LVM_LV=VolGroup/lv_swap crashkernel=auto LANG=zh_CN.UTF-8 rd_LVM_LV=VolGroup/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-642.el6.x86_64.img
内核启动的密码认证

grub的安装

1、使用grub-install命令

grub-install [--root-directory=DIR] DEVICE

DEVICE:安装的目标磁盘;
--root-directory=DIR:指grub映像文件的存放位置,默认为当前系统根目录。grub-install会在指定的目录下创建boot/grub/的层级目录,并生成相关的grub文件生成在DIR/boot/grub/下。

2、在grub命令行下安装grub
输入命令grub进入grub命令行:

[root@localhost ~]# grub    #进入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)    #指定boot分区
root (hd0,0)
 Filesystem type is ext2fs, partition type 0x83
grub> setup (hd0)  #安装grub
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

在grub程序出现损坏时,我们还可以利用上述方法对其进行修复:

  • 模拟grub损坏,但系统未重启,对grub进行修复:
[root@localhost ~]# dd if=/dev/zero of=/dev/sda count=1 bs=400   #复写破坏硬盘中的MBR
1+0 records in
1+0 records out
400 bytes (400 B) copied, 0.0132301 s, 30.2 kB/s
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# grub-install /dev/sda    #在系统重启前使用修复安装grub
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

也可以通grub命令行来修复grub程序:

root@localhost ~]# dd if=/dev/zero of=/dev/sda count=1 bs=400
1+0 records in
1+0 records out
400 bytes (400 B) copied, 0.000711047 s, 563 kB/s
[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损坏后,系统重启了的情况下修复grub

方法一:利用安装光进入救援模式进行grub修复

[root@localhost ~]# dd if=/dev/zero of=/dev/sda count=1 bs=400
1+0 records in
1+0 records out
400 bytes (400 B) copied, 0.0071285 s, 56.1 kB/s
[root@localhost ~]# shutdown -r now

Broadcast message from [email protected]
    (/dev/pts/2) at 1:42 ...

The system is going down for reboot NOW!
系统无法正常启动

插入光盘,进入救援模式。


进入紧急救援模式

在完成相关的硬件检测及引导程序,依次设置语言、键盘及是否启动网络,接着系统会查找根分区,随后选择continue以读写的方式挂载根文件系统。


挂载根文件系统

点击OK,最后选择start shell。

环境切换提示

启动shell后,输入chroot /mnt/sysimage,然后使用grub-install修复grub。
grub修复

至此grub已修复完成,系统应能正常启动。

方法二:将损坏的硬盘拆卸挂载到其他Linux系统上进行修复

[root@localhost ~]# echo "scsi add-single-device 2 0 1 0" > /proc/scsi/scsi   #在新系统上识别出需要修复的硬盘
[root@localhost ~]# lsblk
NAME                        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0                          11:0    1 1024M  0 rom  
sda                           8:0    0   20G  0 disk 
├─sda1                        8:1    0  500M  0 part /boot
└─sda2                        8:2    0 19.5G  0 part 
  ├─VolGroup-lv_root (dm-0) 253:0    0 17.6G  0 lvm  /
  └─VolGroup-lv_swap (dm-1) 253:1    0    2G  0 lvm  [SWAP]
sdb                           8:16   0   20G  0 disk 
├─sdb1                        8:17   0  500M  0 part 
└─sdb2                        8:18   0 19.5G  0 part 
[root@localhost ~]# mkdir /mnt/boot    
[root@localhost ~]# mount /dev/sdb1 /mnt/boot/
[root@localhost ~]# grub-install --root-directory=/mnt /dev/sdb  #root directory指定/dev/sdb1挂载的目录的父目录
/dev/sdb does not have any corresponding BIOS drive.  #出现该报错可添加--recheck解决
[root@localhost ~]# grub-install --root-directory=/mnt --recheck /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 ~]# umount /mnt/boot/   #卸载对应的硬盘
[root@localhost ~]# cat /proc/scsi/scsi 
Attached devices:
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: NECVMWar Model: VMware IDE CDR10 Rev: 1.00
  Type:   CD-ROM                           ANSI  SCSI revision: 05
Host: scsi2 Channel: 00 Id: 00 Lun: 00
  Vendor: VMware,  Model: VMware Virtual S Rev: 1.0 
  Type:   Direct-Access                    ANSI  SCSI revision: 02
Host: scsi2 Channel: 00 Id: 01 Lun: 00
  Vendor: VMware,  Model: VMware Virtual S Rev: 1.0 
  Type:   Direct-Access                    ANSI  SCSI revision: 02
[root@localhost ~]# echo "scsi remove-single-device 2 0 1 0" > /proc/scsi/scsi  #从系统中移除识别相应的硬盘
[root@localhost ~]# lsblk
NAME                        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sr0                          11:0    1 1024M  0 rom  
sda                           8:0    0   20G  0 disk 
├─sda1                        8:1    0  500M  0 part /boot
└─sda2                        8:2    0 19.5G  0 part 
  ├─VolGroup-lv_root (dm-0) 253:0    0 17.6G  0 lvm  /
  └─VolGroup-lv_swap (dm-1) 253:1    0    2G  0 lvm  [SWAP]

修复完成后,将对应硬盘拆卸挂载回原来的系统,再启动验证即可。

补充:如何在Linux系统不重启下添加或移除硬盘。
添加命令为:

echo "scsi add-single-device 2 0 1 0" > /proc/scsi/scsi

移除命令为:

echo "scsi remove-single-device 2 0 1 0" > /proc/scsi/scsi

这两个命令的成功与否在于对应的数字ID是否正确,其格式为:

echo "scsi [add|remove]-single-device w x y z" > /proc/scsi/scsi
w为主机适配器标识,第一个适配器标识为0;
x为主机适配器上的通道channel,第一个channel标识通常为0;
y为设备的ID;
z为LUN标识,第一个LUN标识为0;

可以通过查看/proc/scsi/scsi查看对应的标识信息,如:
```
[root@localhost ~]# cat /proc/scsi/scsi 
Attached devices:
Host: scsi1 Channel: 00 Id: 00 Lun: 00   #对应的w x y z为1 0 0 0
  Vendor: NECVMWar Model: VMware IDE CDR10 Rev: 1.00
  Type:   CD-ROM                           ANSI  SCSI revision: 05
Host: scsi2 Channel: 00 Id: 00 Lun: 00 #对饮的w x y z 为 2 0 0 0
  Vendor: VMware,  Model: VMware Virtual S Rev: 1.0 
  Type:   Direct-Access                    ANSI  SCSI revision: 02
```

你可能感兴趣的:(grub启动程序配引导置及命令行接口详解)