引导加载程序grub详解

上一章讲到,常见的boot loader(引导加载程序)有LILO和grub,LILO有一大缺点,它只能识别0-1023范围内的柱面构成的分区的内核文件,故已逐渐被grub取代。

创新互联公司2013年至今,是专业互联网技术服务公司,拥有项目做网站、成都做网站网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元阿图什做网站,已为上家服务,为阿图什各地企业和个人服务,联系电话:18980820575

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目录下

引导加载程序grub详解

3、grub的功能

  ①提供菜单,并提供交互式接口

     e: 进入编辑模式

  ②选择要启动的内核或系统

     允许传递引导参数给内核

     选择界面可隐藏

  ③为编辑功能提供保护机制

     启用内核文件:

       选择运行指定的内核得先输入密码

     传递参数:

       使用e命令得先输入密码

开机后有三秒种的过渡页面,按任意键可进入菜单页面。在菜单页面可用上下键选择所要启动的内核或内核,按e键进入内核编辑模式,按c键进入grub命令行模式

引导加载程序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:隐藏菜单

   titleTILTE STRING:显示于菜单中的标题

      root

      kernel

      initrd

  ■若由于grub.conf文件错误或丢失而无法自动进入系统,可通过grub命令行引导系统后再手动更改或创建这个文件

[root@node2 ~]# cat /boot/grub/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/sda2
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-431.el6.x86_64)
	root (hd0,0)
	kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=aa0330af-3681-428c-98e2-ccf2e6f0f686 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
	initrd /initramfs-2.6.32-431.el6.x86_64.img
[root@node2 ~]# ll /etc/grub/conf
ls: cannot access /etc/grub/conf: No such file or directory
[root@node2 ~]# ll /etc/grub.conf
lrwxrwxrwx. 1 root root 22 Aug  6 04: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 /
bin   dev  home                                 lib    lost+found  misc  net  proc  sbin     srv  tmp  var
boot  etc  initramfs-2.6.32-431.el6.x86_64.img  lib64  media       mnt   opt  root  selinux  sys  usr  vmlinuz-2.6.32-431.el6.x86_64
[root@node2 ~]# vim /etc/grub.conf
...
default=0
timeout=5
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-431.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=aa0330af-3681-428c-98e2-ccf2e6f0f686 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-431.el6.x86_64.img
#添加如下几行,构成一个新的启动项
title testCentos  #新的标题
        root (hd0,1)  #现在根分区下也有内核和临时根文件,根分区为sda2,故写成(hd0,1)
        kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/sda2
        initrd /initramfs-2.6.32-431.el6.x86_64.img

引导加载程序grub详解

6、grub保护机制:可防止恶意用户随意进入单用户模式修改root密码

  ①生成密码:

   grub-md5-crypt

  ②保护所有内核,需要在title之外添加

   password --md5 密码串

  ③保护使用某内核,则需要在内核对应的title之下添加

   password --md5 密码串

[root@node2 ~]# grub-md5-crypt   #生成密码
Password: 
Retype password: 
$1$oWUbV$Sb/PsrhmkE5bUJPMJGn871
[root@node2 ~]# vim /etc/grub.conf
...
default=0
timeout=5
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
password --md5 $1$oWUbV$Sb/PsrhmkE5bUJPMJGn871   #添加于title之外可保护所有内核
title CentOS (2.6.32-431.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=aa0330af-3681-428c-98e2-ccf2e6f0f686 rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-431.el6.x86_64.img
title testCentos
password --md5 $1$oWUbV$Sb/PsrhmkE5bUJPMJGn871   #可保护使用指定内核
        root (hd0,1)
        kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=aa0330af-3681-428c-98e2-ccf2e6f0f686
        initrd /initramfs-2.6.32-431.el6.x86_64.img

引导加载程序grub详解

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 ~]# dd if=/dev/zero of=/dev/sda bs=400 count=1   #将MBR中的引导加载程序冲刷掉,注意不能殃及分区表
1+0 records in
1+0 records out
400 bytes (400 B) copied, 0.000324129 s, 1.2 MB/s
[root@node2 ~]# rm -f /boot/grub/stage2   #将"stage 2"也删除
[root@node2 ~]# grub-install /dev/sda      #使用grub-install的方式安装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
[root@node2 ~]# ll /boot/grub/stage2   #已重新生成"stage 2"
-rw-r--r-- 1 root root 126100 Oct 28 22:19 /boot/grub/stage2

[root@node2 ~]# dd if=/dev/zero of=/dev/sda bs=400 count=1
1+0 records in
1+0 records out
400 bytes (400 B) copied, 0.000368562 s, 1.1 MB/s
[root@node2 ~]# 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)   #使用方法二安装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

  情景2:grub损坏且系统已关闭,这时候可用如下两种方式修复:

  方式一:将故障磁盘挂载于其它正常主机上重装grub

   ①手动将node1的磁盘的grub损毁并关机

[root@node1 ~]# dd if=/dev/zero of=/dev/sda bs=400 count=1
1+0 records in
1+0 records out
400 bytes (400 B) copied, 0.000164892 s, 2.4 MB/s
[root@node1 ~]# shutdown -h now

   ②将node1的磁盘移除并添加到node2上(关于 如何在不重启的情况下识别新增硬盘 见末尾补充部分)

   ③挂载node1的分区并安装grub,安装完后卸载

[root@node2 ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   30G  0 disk 
├─sda1   8:1    0  200M  0 part /boot
├─sda2   8:2    0   10G  0 part /
└─sda3   8:3    0    2G  0 part [SWAP]
sdb      8:16   0   30G  0 disk   #node1的硬盘在node2上被识别为sdb
├─sdb1   8:17   0  200M  0 part 
├─sdb2   8:18   0   10G  0 part 
└─sdb3   8:19   0    2G  0 part 
sr0     11:0    1  4.2G  0 rom  
[root@node2 ~]# mkdir /mnt/boot
[root@node2 ~]# mount /dev/sdb1 /mnt/boot
[root@node2 ~]# grub-install --root-directory=/mnt /dev/sdb
/dev/sdb does not have any corresponding BIOS drive.
# 注意:若这里提示找不到相应的BIOS驱动,可使用选项--recheck重新检查磁盘,如下:
[root@node2 ~]# 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@node2 ~]# umount /mnt/boot

   ④从node2上移除node1的硬盘后再装回node1启动即可

  方式二:插入系统光盘进入救援模式修复

   ①将Linux安装光盘放入光驱。硬盘的MBR损坏后,BIOS会自动从光盘引导,进入菜单页面后,选择进入“救援模式”

引导加载程序grub详解

   ②系统会检测硬件,引导光盘上的Linux环境,依次提示选择救援模式下使用的语言、键盘以及是否需要设置网络,可按需选择

   ③接下来系统会查找根分区,出现挂载提示,硬盘的根分区将被挂载到光盘Linux环境的/mnt/sysp_w_picpath目录下;默认选项“continue”表示挂载权限为读写,“Read-only”为只读,如。此处,因为要对系统进行修复,故需要有读写权限,选择“continue”。

引导加载程序grub详解

   ④按提示执行“chroot /mnt/sysp_w_picpath”切换根环境并安装grub,然后退出shell并重启即可

     chroot:切换根环境,即以指定的目录作为根

     用法:chroot /path/to/directory [SHELL]

     例如 chroot /mnt/sysp_w_picpath /bin/tcsh   #将sysp_w_picpath作为根目录,并运行其中的tcsh

引导加载程序grub详解

引导加载程序grub详解

补充:如何实现不重启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 ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   30G  0 disk 
├─sda1   8:1    0  200M  0 part /boot
├─sda2   8:2    0   10G  0 part /
└─sda3   8:3    0    2G  0 part [SWAP]
sr0     11:0    1  4.2G  0 rom
[root@node2 ~]# cat /proc/scsi/scsi
Attached devices:
Host: scsi0 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: 00 Lun: 00
  Vendor: NECVMWar Model: VMware IDE CDR10 Rev: 1.00
  Type:   CD-ROM                           ANSI  SCSI revision: 05
#可以看到,当前最大ID号为00,因此新增硬盘的ID号应为01
[root@node2 ~]# echo "scsi add-single-device 0 0 1 0" > /proc/scsi/scsi
[root@node2 ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   30G  0 disk 
├─sda1   8:1    0  200M  0 part /boot
├─sda2   8:2    0   10G  0 part /
└─sda3   8:3    0    2G  0 part [SWAP]
sdb      8:16   0   30G  0 disk   #新增硬盘已被识别出来
├─sdb1   8:17   0  200M  0 part 
├─sdb2   8:18   0   10G  0 part 
└─sdb3   8:19   0    2G  0 part 
sr0     11:0    1  4.2G  0 rom
[root@node2 ~]# echo "scsi remove-single-device 0 0 1 0" > /proc/scsi/scsi   #移去该硬盘
[root@node2 ~]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0   30G  0 disk 
├─sda1   8:1    0  200M  0 part /boot
├─sda2   8:2    0   10G  0 part /
└─sda3   8:3    0    2G  0 part [SWAP]
sr0     11:0    1  4.2G  0 rom

分享文章:引导加载程序grub详解
网站地址:http://ybzwz.com/article/igjsjj.html