BootLoader-GRUB

如果没有loader, 那么kernel根本没有办法被系统加载, 现在来说说grub吧, 当前Linux里最主流的boot loader.

GRUB (old version)

在CentOS5/6系统启动流程中我们就已经提过了grub这个小东西. 全称叫GRand Unified Bootloader.

从CentOS7开始, 使用了新版的grub, 也就是1.x版本, 这个被叫做grub2. 而原先的CentOS5/6使用的就是grub 0.x版本 也就是所谓grub legacy. 并且这两者也已经出现了巨大的变化.

1
2
3
4
grub legacy:
stage1: mbr
stage1_5: mbr之后的扇区, 让stage1中的bootloader可以识别stage2所在分区的文件系统
stage2: 磁盘分区(/boot/grub/)

这些在前文都已经提过了.

先从旧版的开始吧. :)

grub的配置文件就位于/boot/grub/grub.conf, 在当前目录就有一个符号链接指向他, 这个先不说, 另外还有一个/etc/grub.conf也指向它.

尽管在前文曾经提到过, 但是现在我们再把这个grub的引导过程顺一遍: 首先在主板识别了硬盘并且通过INT_13中断(管他是什么, 反正能将第一扇区的内容export出去)来进行bootloader的读取之后, 此时bootloader已经可以读取主机上的硬盘设备了, 但此时仍然不能读取文件系统(软件组织的), 因此这个时候通过文件系统驱动的帮助, 就进入了stage2, stage2和内核等都放在一个基本的磁盘分区.接着主程序就开始读取配置文件了.

这里需要先明确grub的功用:

  • 提供菜单, 并提供交互接口
    • e: 编辑模式, 用于编辑菜单
    • c: 命令模式, 交互式接口
  • 加载用户选择的内核或操作系统, 允许传递参数给内核, 可隐藏菜单
  • 保护机制, 为编辑菜单, 启用内核进行认证
  • 控制权移交功能(important)

我们进入/boot/grub下看一看里面的关键文件:

grub_stg

这里面的stage1文件就是我们说的, 用来进行跳转的.

*stage1_ 5文件包含了各种识别文件系统的代码,使得grub可以从文件系统中读取体积更大功能更复杂的stage2文件. stage1_ 5一般安装在MBR后、第一个分区前的那段空闲空间中,也就是MBR gap空间,它的作用是跳转到stage2的第一个扇区.

其实传统的grub在某些环境下是可以不用stage1_5文件就能正常运行的.

stage2的作用就是加载各种环境和加载内核 当跳转到stage2的第一个扇区后,该扇区的代码负责加载stage2剩余的内容. 需要说的一点是: stage2是存放在磁盘上的. 这点和后面我们要说的GRUB2有对应.

下面就来看一下grub的命令行接口吧:

进入grub菜单的方式就是在出现boot的界面的时候按下任意键就行了.

enter_grub

接着就会看到这样的菜单:

grub_menu

使用help就可以显示所有支持的命令, 还可以单独的进行help [KEYWORD] 来查看单个命令的使用方式

比如设置挂载根文件系统的命令root. 在后面加上设备路径, 把他当成根来挂载. (这里的根是指要被挂载成grub根的根哦!)

root_help

在仔细说说命令行的使用前, 让我们再来讨论一下 这个**/boot**. 可以分区 也可以不分区而是根的一个目录, 这些都是可能的. 我们都知道,如果想要访问某个设备就要先将其挂载到我们的目录上, 有一个入口才行.所以第一种情况, boot在根分区上(一个分区), 那么就是一个目录文件. 所以在读取vmlinuz的时候, 我就需要先加载根文件系统才可以读取到也就是:

1
/boot/vmlinuz --- 这里的根是 根文件系统那个的根

第二种情况 如果/boot是一个不同于根的分区, 是挂载上去的. 那么这个时候访问路径就变成了:

1
/vmlinuz --- 这里的根就变成了 boot对应的那个分区的文件系统的根

我们知道这个时候, 是系统启动之前, 所以根是没有装载起来的, 但是现在要访问vmlinuz文件哇, 这个时候访问就是向第一种情况的那种. 此时如果grub想要从根访问/boot, 一个要求就是根必须是基本的文件系统, 不能是那种复杂的逻辑卷. 这,就是为什么推荐将boot单独分区, 且是那种很简单的, 这样在根使用了一些叫高级复杂的文件系统架构时候也可以确保正常启动内核.

那么如何识别设备呢? 在进入菜单之后, 其实就可以看到一个默认的根:

dev

hd0,0 表示的就是 hard disk 第一块磁盘的第一个分区. 也就是说hd磁盘编号,分区编号

好, 让我们继续吧!

1
2
3
4
5
6
7
8
9
grub> find FILENAME
# 这个寻找指令不是简单的输入文件名就好了哦,要指定具体的分区, 写出完整的路径
grub> find (hd0,0)/vmlinuz-2.6.32-220.el6.x86_64
(hd0,0)
# 通过这个可以快速的确定文件的存在性
# 但其实我也可以先指定根的所在, 这样就可以不同每一次都加上分区了
grub> root (hd0,0)
grub> find /vmlinuz-2.6.32-220.el6.x86_64
(hd0,0)

接下来就是设置要加载的内核文件镜像以及ramdisk是什么, 使用kernelinitrd

1
2
grub> kernel /vmlinuz-2.6.32-220.el6.x86_64
grub> initrd /initramfs-2.6.32-220.el6.x86_64.img

这里一定要做到: 版本完完全全匹配

最后执行boot就可以了

1
grub> boot

我们还可以手动在加上一些参数, 比如: selinux=0, 以及开机等级什么的.

所以现在就会明白了: 当我们直接选择这个选项并且直接回车的时候…

boot_2

其实执行的就是敲击e进入的编辑页面的这些:

boot_3

列举一些常用选项: quiet 表示静默模式, 显示较少的信息, 也可以直接加上等级, 一种常见的就是加上1或者single, 进入单用户维护模式.

前面说过了 读取完配置文件就会有这么一个菜单, 这么个配置文件就决定这么个菜单的表现形式.位置也已经在上面说过了, 现在就先来看一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@WWW ~]$ cat /etc/grub
# 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/mapper/vg_livecd-lv_root
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0 # 哪一个是默认启动的菜单
timeout=5 # 超时5秒
splashimage=(hd0,0)/grub/splash.xpm.gz # 默认的背景图片, 最大支持14位颜色深度(2^14)
hiddenmenu # 隐藏菜单
title CentOS (2.6.32-220.el6.x86_64) # 这个就是一开始看到的一级菜单的那个选项内容, 下面的缩进三只就是进去看到的二级菜单
root (hd0,0)
kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/vg_livecd-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_livecd/lv_swap rd_NO_MD quiet rd_LVM_LV=vg_livecd/lv_root SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM
initrd /initramfs-2.6.32-220.el6.x86_64.img

.我们还可以对菜单进行加密:

1
2
3
4
5
6
7
8
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
# 在这里可以插进来一条全局的配置, 菜单编辑认证(防编辑)
password [--md5] STRING
title CentOS (2.6.32-220.el6.x86_64)
password [--md5] STRING # 启用选定的内核或操作系统的认证(防启动)

这里放的密码串, 可以直接写明文, 但是这样很不安全, 因此更应该使用md5形式的摘要串, grub提供了这样的一个工具来帮我们生成: grub-md5-crypt 使用方法就是直接敲进去进入交互界面然后就键入要加密的密码串就可以的得到了.

现在在我折腾了之后看到的菜单, 不仅多了一条菜单而且还会发现这个时候下方的提示也变了

grub_改

使用p进入密码输入界面:

grub_password

接着就会变成原来的那种, 由于我给第二个Linux系统加入了密码认证, 所以在直接Enter第二的时候, 会进入这样的页面:

boot_passwd'

如果输入错误就会直接回到GRUB的主页面, 正确当然就是直接进入系统啦

进入单用户模式

说到这里, 进入单用户维护模式就变得非常简单了.

1). 编辑grub菜单(选定要编辑的title, 而后使用e命令)

2). 在选定的kernel后面加上: 1, s, S, single都行

3). 在kernel所在行, 键入b命令(boot)

grub的重新安装

什么时候才需要重装grub啊? 很多时候, 重新安装grub体现在很多问题的解决上. 所以当出现了一些系统无法启动的时候, 别急着重装系统! 先看看问题出在哪一个环节上, 有时候当问题出现在引导上, 修复一下也要不了多少时间而且还可以完美无损. 并且grub的重新安装还可以解决多系统在同一块硬盘上共存的问题.

重新安装一个最简单的方法就是使用grub-install命令 但是注意呀, 这里说的修复是指修复镜像和ramdisk 不包括grub.conf 的, 所以说如果你的grub.conf 损坏了, 是要进行手动的重写的.

具体的操作步骤:

鸟哥的私房菜旧版