如何配置及排除GRUB故障

本文将会向你介绍 GRUB 的知识,并会说明你为什么需要一个引导加载程序,以及它是如何给系统增加功能的。

Linux 引导过程 是从你按下你的电脑电源键开始,直到你拥有一个全功能的系统为止,整个过程遵循着这样的主要步骤:

  • 一个叫做 POST(上电自检)的过程会对你的电脑硬件组件做全面的检查。

  • 当 POST 完成后,它会把控制权转交给引导加载程序,接下来引导加载程序会将 Linux 内核(以及 initramfs)加载到内存中并执行。

  • 内核首先检查并访问硬件,然后运行初始化进程(主要以它的通用名 init 而为人熟知),接下来初始化进程会启动一些服务,最后完成系统启动过程。

在该系列的第七讲(“SysVinit、Upstart 和 Systemd”)中,我们介绍了现代 Linux 发行版使用的一些服务管理系统和工具。在继续学习之前,你可能想要回顾一下那一讲的知识。

GRUB 引导装载程序介绍

在现代系统中,你会发现有两种主要的 GRUB 版本(一种是有时被称为 GRUB Legacy 的 v1 版本,另一种则是 v2 版本),虽说多数最新版本的发行版系统都默认使用了 v2 版本。如今,只有 红帽企业版 Linux 6 及其衍生系统仍在使用 v1 版本。

因此,在本指南中,我们将着重关注 v2 版本的功能。

不管 GRUB 的版本是什么,一个引导加载程序都允许用户:

  • 通过指定使用不同的内核来修改系统的行为;

  • 从多个操作系统中选择一个启动;

  • 添加或编辑配置区块来改变启动选项等。

如今,GNU 项目负责维护 GRUB,并在它们的网站上提供了丰富的文档。当你在阅读这篇指南时,我们强烈建议你看下 GNU 官方文档。

当系统引导时,你会在主控制台看到如下的 GRUB 画面。最开始,你可以根据提示在多个内核版本中选择一个内核(默认情况下,系统将会使用最新的内核启动),并且可以进入 GRUB 命令行模式(使用 c 键),或者编辑启动项(按下 e 键)。

未分类

GRUB 启动画面

你会考虑使用一个旧版内核启动的原因之一是之前工作正常的某个硬件设备在一次升级后出现了“怪毛病(acting up)”(例如,你可以参考 AskUbuntu 论坛中的这条链接)。

在启动时会从 /boot/grub/grub.cfg 或 /boot/grub2/grub.cfg 文件中读取GRUB v2 的配置文件,而 GRUB v1 使用的配置文件则来自 /boot/grub/grub.conf 或 /boot/grub/menu.lst。这些文件不应该直接手动编辑,而应通过 /etc/default/grub的内容和 /etc/grub.d 目录中的文件来更新。

在 CentOS 7 上,当系统最初完成安装后,会生成如下的配置文件:

GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto  vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

除了在线文档外,你也可以使用下面的命令查阅 GNU GRUB 手册:

# info grub

如果你对 /etc/default/grub 文件中的可用选项特别感兴趣的话,你可以直接查阅配置一节的帮助文档:

# info -f grub -n 'Simple configuration'

使用上述命令,你会发现 GRUB_TIMEOUT 用于设置启动画面出现和系统自动开始启动(除非被用户中断)之间的时间。当该变量值为 -1 时,除非用户主动做出选择,否则不会开始启动。

当同一台机器上安装了多个操作系统或内核后,GRUB_DEFAULT 就需要用一个整数来指定 GRUB 启动画面默认选择启动的操作系统或内核条目。我们既可以通过上述启动画面查看启动条目列表,也可以使用下面的命令:

在 CentOS 和 openSUSE 系统上

# awk -F/' '$1=="menuentry " {print $2}' /boot/grub2/grub.cfg

在 Ubuntu 系统上

# awk -F/' '$1=="menuentry " {print $2}' /boot/grub/grub.cfg

如下图所示的例子中,如果我们想要使用版本为 3.10.0-123.el7.x86_64 的内核(第四个条目),我们需要将 GRUB_DEFAULT 设置为 3(条目从零开始编号),如下所示:

GRUB_DEFAULT=3

未分类

使用旧版内核启动系统

最后一个需要特别关注的 GRUB 配置变量是 GRUB_CMDLINE_LINUX,它是用来给内核传递选项的。我们可以在 内核变量文件和 man 7 bootparam 中找到能够通过 GRUB 传递给内核的选项的详细文档。

我的 CentOS 7 服务器上当前的选项是:

GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto  vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet"

为什么你希望修改默认的内核参数或者传递额外的选项呢?简单来说,在很多情况下,你需要告诉内核某些由内核自身无法判断的硬件参数,或者是覆盖一些内核检测的值。

不久之前,就在我身上发生过这样的事情,当时我在自己已用了 10 年的老笔记本上尝试了衍生自 Slackware 的 Vector Linux。完成安装后,内核并没有检测出我的显卡的正确配置,所以我不得不通过 GRUB 传递修改过的内核选项来让它工作。

另外一个例子是当你需要将系统切换到单用户模式以执行维护工作时。为此,你可以直接在 GRUB_CMDLINE_LINUX 变量中直接追加 single 并重启即可:

GRUB_CMDLINE_LINUX="vconsole.keymap=la-latin1 rd.lvm.lv=centos_centos7-2/swap crashkernel=auto  vconsole.font=latarcyrheb-sun16 rd.lvm.lv=centos_centos7-2/root rhgb quiet single"

编辑完 /etc/default/grub 之后,你需要运行 update-grub (在 Ubuntu 上)或者 grub2-mkconfig -o /boot/grub2/grub.cfg (在 CentOS 和 openSUSE 上)命令来更新 grub.cfg 文件(否则,改动会在系统启动时丢失)。

这条命令会处理早先提到的那些启动配置文件来更新 grub.cfg 文件。这种方法可以确保改动持久化,而在启动时刻通过 GRUB 传递的选项仅在当前会话期间有效。

修复 Linux GRUB 问题

如果你安装了第二个操作系统,或者由于人为失误而导致你的 GRUB 配置文件损坏了,依然有一些方法可以让你恢复并能够再次启动系统。

在启动画面中按下 c 键进入 GRUB 命令行模式(记住,你也可以按下 e 键编辑默认启动选项),并可以在 GRUB 提示中输入 help 命令获得可用命令:

未分类

修复 Linux 的 Grub 配置问题

我们将会着重关注 ls 命令,它会列出已安装的设备和文件系统,并且我们将会看看它查找到的东西。在下面的图片中,我们可以看到有 4 块硬盘(hd0 到 hd3)。

貌似只有 hd0 已经分区了(msdos1 和 msdos2 可以证明,这里的 1 和 2 是分区号,msdos 则是分区方案)。

现在我们来看看能否在第一个分区 hd0(msdos1)上找到 GRUB。这种方法允许我们启动 Linux,并且使用高级工具修复配置文件,或者如果有必要的话,干脆重新安装 GRUB:

# ls (hd0,msdos1)/

从高亮区域可以发现,grub2 目录就在这个分区:

未分类

查找 Grub 配置

一旦我们确信了 GRUB 位于 (hd0, msdos1),那就让我们告诉 GRUB 该去哪儿查找它的配置文件并指示它去尝试启动它的菜单:

set prefix=(hd0,msdos1)/grub2
set root=(hd0,msdos1)
insmod normal
normal

未分类

查找并启动 Grub 菜单

然后,在 GRUB 菜单中,选择一个条目并按下回车键以使用它启动。一旦系统成功启动后,你就可以运行 grub2-install /dev/sdX 命令修复问题了(将 sdX 改成你想要安装 GRUB 的设备)。然后启动信息将会更新,并且所有相关文件都会得到恢复。

# grub2-install /dev/sdX

其它更加复杂的情景及其修复建议都记录在 Ubuntu GRUB2 故障排除指南 中。该指南中阐述的概念对于其它发行版也是有效的。

总结

本文向你介绍了 GRUB,并指导你可以在何处找到线上和线下的文档,同时说明了如何面对由于引导加载相关的问题而导致系统无法正常启动的情况。

幸运的是,GRUB 是文档支持非常丰富的工具之一,你可以使用我们在文中分享的资源非常轻松地获取已安装的文档或在线文档。

你有什么问题或建议吗?请不要犹豫,使用下面的评论框告诉我们吧。我们期待着来自你的回复!

CentOS7启动出现grub>提示符修复方法

本文档适用于CentOS 7.X,其他系统未测试。

出现这个问题的原因是grub配置文件错误、损坏或丢失,执行以下步骤修复

1. 罗列所有的磁盘区块

grub>ls

我的是(hd0),(hd0,msdos1),(hd0,msdos2)

2. 确定boot分区

ls (hd0,X)/boot/grub

如果存在,则列出该文件夹里的所有文件,不存在则会报错。如果boot为独立分区则使用

ls(hd0,X)/grub2

3. 将boot分区设置为临时root分区

grub>set root=hd0,msdos1

hd0,msdos1为第二步中确定的boot分区

4. 命令后面的路径可以用tab键补全,xxxx代表你的系统内核版本号

/dev/mapper/centos-root为根分区,如果分区格式不是lvm的,根据你的本机情况填写,如/dev/sda1

grub>linux16 /vmlinuz-xxxx.e17.x86_64  root=/dev/mapper/centos-root

5. 命令后面的路径可以用tab键补全,xxxx代表你的系统内核版本号

grub>lintrad16 /initramfs-xxxx.e17.x86_64.img

6. 启动

grub>boot

7. 进入系统之后使用命令重新生成grub配置文件

grub2-mkconfig -o /boot/grub2/grub.cfg

设置grub密码保护系统

在开机启动临时进入1模式的时候,系统先调用/etc/grub.conf。

/etc/grub.conf其实是/boot/grub/grub.conf的软连接。

加密改文件就有效的防止其他用户直接绕过口令登陆1模式,从而进入到root中做一些破坏。

未分类

我们可以看一下如何进入1模式。

未分类

我们可以看一下临时进入init1模式的窗口

未分类

这里的内容与grub文件对比一下

未分类

可以看出里面的内容就是从grub提取出来的

如果我们把grub文件加密的情况,那么就不能随便进入init1模式,这样就增加系统的安全性。

想要增加密码,就直接在grub.conf文件中添加一句话,就可以直接添加上密码了。

未分类

这样的明文口令不安全,我们可以换成密文的。

grub-md5-crype

未分类

我们可以直接把密文口令作为口令。但是要在前面说明是md5加密的

未分类

当然我们也可以用其他的加密方式。

比如:

grub-crypt

未分类

这个密文更加复杂

未分类

Debian grub丢失后修复的方法

家里的台由于偶尔玩玩游戏,安装了win7+debian的双系统.最近一次玩游戏后,手贱点了win7的升级,结果系统坏了.重装win7后,导致debian的引导丢失.由于长期是在debian下使用,所以不想重装那么麻烦,重点是debian系统没有被损坏啊.所以就查资料研究了一下如何修复grub.由于/boot是独立的分区,走了不少弯路.我尝试了两种方式修复grub,以下是两种修复方式的记录.

通过Debian rescue模式重建grub

  1. 制作debian的U盘安装盘
  2. 进入debian的U盘安装盘的 rescue模式(急救模式)
  3. 选择语言/键盘/输入姓名/配置网络等信息后,进入急救模式->选择在安装程序环境中运行shell->选择请不要使用根文件系统(方便手动挂载已有系统文件系统)。
# 由于/ /boot /home都是独立的分区,所以需要分别进行挂载
mount /dev/sda11 /mnt
mount /dev/sda8 /mnt/boot
mount /dev/sda12 /mnt/home
mount -t proc proc /mnt/proc
mount -t sysfs sys /mnt/sys
mount -o bind /dev /mnt/dev
chroot /mnt /bin/bash
grub-install /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg

cd /
umount -a
exit
cd /
umount -a
reboot
# 重启后即可出现引导菜单界面

# 若有办法进入系统(如手动启动引导),则可进入系统后直接采用如下方式安装grub
sudo grub-install /dev/sda
sudo grub-mkconfig -o /boot/grub/grub.cfg
reboot

手动启动引导

从win的启动引导中进行手动启动引导.此方式需要在win下通过easybcd安装grub,所以需要能进入win系统.既然能进入win,当然也可以在win下制作对应Linux系统的U盘安装盘,然后通过上面介绍的救援模式进行修复.

  1. 在win下安装easybcd
  2. 添加linux的grub,可针对不同分区多添加几项,避免不断重启添加其他分区。
  3. 重启后即可出现linux的grub引导项,可逐项尝试。
  4. 进入grub rescue后,即可进行手动启动引导。
  5. 可通过ls查看分区信息.
  6. 若根分区为(hd0,10),输入如下命令(注:root和prefix后到末尾都没有输入空格)
set root=(hd0,10)
set prefix=(hd0,10)/boot/grub
insmod normal
normal
# 最后的normal命令输入后即可进入引导菜单。
# 进入系统后即可直接安装grub

# 若未能进入grub2引导菜单,而是进入了另一个grub2命令界面.可在此进行如下操作.

set root=(hd0,msdos8)               # (hd0,msdos8)      为/boot分区
linux /vmlinuz* ro root=/dev/sda11       # *指具体的内核版本,可通过tab键补全, sda11为根目录的分区.
initrd /initrd.img*
boot

# 至次已经成功启动系统.
# set root=(hd0,msdos8)               (hd0,msdos8)      为/boot分区
# linux /vmlinuz* ro root=/dev/sda11    *指具体的内核版本,可通过tab键补全, sda11为根目录的分区.   注:若/boot为独立分区时:  /vmlinuz*   若/boot不是独立分区时:  /boot/vmlinuz*
# initrd /initrd.img*    *指具体的内核版本,可通过tab键补全
# set root后,可通过ls命令查看该分区指定路径下的文件信息.比如:不记得分区信息了,可依次设置分区,然后通过ls查看/或/boot下是否包含内核文件及根分区相应的目录,从而确定/分区和/boot分区.

Ubuntu16.04系统无法启动grub rescue模式下修复grub

前几天整理了下电脑的分区,合并并删除一些分区,结果导致 grub 被破坏了,Ubuntu进不去了,启动后直接进入了 rescure 模式。后来又折腾了下,终于修复好了,现总结一下。

先说一下我的系统环境,我是 Win7 + Ubuntu 16.04 双系统,先安装的 Win7,后安装的 Ubuntu。采用的是 Windows 引导 Ubuntu 的方式,使用的工具是”EasyBCD 2.3 个人版本“。Ubuntu 分区时,”/boot” 是单独分区的。详细分区情况如下:“/boot” 分区, “/” 分区, “swap 交换空间“。

另外需要说明的,我在安装 Ubuntu 时,“安装启动引导器的设备”选择的是 “/boot” 所在的分区。

下面正式开始详细说明解决办法:

进入 Ubuntu 时,画面如下:

系统管理

首先,使用 ls 命令,找到 Ubuntu 的分区,执行 ls 命令后的结果如下:

系统管理

此时会看到硬盘上的分区情况,例如(hd0,msdos1),(hd0,msdos2)等等,其中 hd0 中的 0 代表第 1 块硬盘(硬盘号从 0 开始),msdos1 中的 1 代表第 1 个分区。

然后依次调用如下命令,直到找到 Ubuntu 所在的分区,命令如下:ls (hdx,msdosy)
其中 x 代表硬盘号,y 代表分区号。
以我的机器为例,依次查看每个分区情况:

ls (hd0,msdos1)
ls (hd0,msdos2)
ls (hd0,msdos3)
#......

执行结果如下:

系统管理

系统管理

系统管理

执行完之后,发现 (hd0,msdos5)和(hd0,msdos6)是 Ubuntu 的分区。然后分别执行如下命令,确定 grub 所在的分区:

ls (hd0,msdos5)/grub
ls (hd0,msdos6)/grub
# 若 “/boot” 没有单独分区,需要执行如下命令(待验证):
ls (hd0,msdos5)/boot/grub
ls (hd0,msdos6)/boot/grub

系统管理

执行完之后,发现 (hd0,msdos5) 中,有 grub.cfg 文件。说明 (hd0,msdos5) 是我们要找的引导分区。

之后,再依次执行如下命令,修复 grub 引导,并进入 grub2 引导画面:

set root=(hd0,msdos5)
set prefix=(hd0,msdos5)/grub
insmod normal
normal
# 若 “/boot” 没有单独分区,需要执行如下命令(待验证):
set root=(hd0,msdos5)
set prefix=(hd0,msdos5)/boot/grub
insmod normal
normal

系统管理

执行完上述命令之后,就可以看到 Ubuntu 的 grub2 引导画面,可以正常进入 Ubuntu 了。

系统管理

不过你会发现,若重新启动电脑的话,问题依旧。那是因为我们还没有执行 grub 的更新命令。

重新执行上述的命令,进入 Ubuntu。然后在终端执行如下命令更新 grub:

sudo update-grub2
sudo grub-install /dev/sda

  
注意: /dev/sda 后面不要加分区号,例如 sda1,sda2 之类的。
  
执行结果如下:

系统管理

系统管理

至此,grub 终于的修复完毕。不过,此时若重新电脑的话,你会发现,启动时变成了 Ubuntu 引导 Windows 了。而修复之前是 Windows 引导 Ubuntu。

为了解决这个问题,我用的方法是先进入 Win7,然后使用 ”EasyBCD“ 重新修复 MBR 从而解决了这个问题。

操作方法很简单:启动 EasyBCD,选择左侧的 ”BCD部署“,然后选中右侧的 ”在MBR中安装 Windows Vista+的bootloader“,也就是默认的第一项,最后点击 ”编写 MBR“ 按钮。

到这里,才算是直接的完成了 grub 的修复,并且可以用 Windows 引导 Ubuntu 了。
  ——————————————————————————————————

在一般情况下,有人可能直接修改GRUB配置文件“/boot/grub/grub.cfg”,但使用“sudu vim /boot/grub/grub.cfg”发现提示这个是系统自动生成的文件,不建议直接编辑,而应该到“/etc/grub.d”和“/etc/default/grub”去修改。
  
“/etc/grub.d”是操作系统菜单目录,一般由系统生成,我们无需修改,接下来就是修改“/etc/default/grub”文件了。使用“sudo vim /etc/default/grub”命令打开该配置文件。
  
其中的“GRUB_DEFAULT=0”就是设置的默认启动项了。GRUB启动项是按照启动菜单依次使用数字进行索引了,起始数字为0。结合前面的系统启动菜单,我们可以看到,Windows8的启动项在第5项,因此这里我们就需要修改为4(因为第一项是从0开始的)
  
修改完成,保存退出之后,还需要执行一下“sudo update-grub”来重新生成GRUB启动配置项。(修改GRUB配置之后,注意使用update-grub更新启动程序,否则修改将不会生效。)

修复CentOS7的MBR和GRUB

一:修复MBR:

MBR(Master Boot Record 主引导记录) 硬盘的0柱面、0磁头、1扇区称为主引导扇区。其中446Byte是BootLoader,64Byte为Partition table,剩下的2Byte为magic number

1:查看一下前512个字节的内容

系统管理

2:破坏bootloader(这里的block size 只要小于等于446即可)

系统管理

3:再查看一下前512个字节,分区表未破坏

系统管理

4:重启之后在光盘引导界面选择Troubleshotting

系统管理

5:进入救援模式

系统管理

6:此时挂载光盘加载了一个Linux系统

系统管理

7:根据提示输入1之后进入救援模式的命令行

系统管理

8:使用 grub2-install 命令重建BootLoader

系统管理
显示无错误,使用sync写入磁盘

9:现在看一下是否修复

系统管理

10:恢复成功,重启一下试试,grub正常运行

系统管理
至此,MBR修复完成

二:修复GRUB

1:看下grub2目录下的存放的文件

系统管理

2:直接删除grub2目录后重启

rm -rf /boot/grub2/
reboot

3:重启之后进入了 grub rescue> 模式,但是不能识别命令,所以还是要进入救援模式

系统管理

4:进入救援模式后切根

chroot /mnt/sysimage/

5:使用 grub2-install 命令修复grub

系统管理

6:现在查看一下是否修复

系统管理

7:修复grub配置文件

系统管理

8:此时/boot/grub2/下已生成grub.cfg文件。退出并重启看系统是否能正常启动

系统管理
启动成功,grub2修复完成

grub rescue下手动引导系统

今天把测试服务器的另外两块硬盘撤下,不能开机,又装上,发现启动不了ubuntu系统了,出现grub rescue的画面。现在让我们来学习手动来引导系统。
1、执行ls命令会出现所有的系统分区,如下

  1. grub rescue> ls
  2. (hd0,1),(hd0,2),(hd1,1),(hd2,1)

2、一个人ls查看,看能否看到/boot分区

  1. grub rescue> ls (hd0,1)/
  2.    grub      lost+found    memtest86+_multiboot.bin     vmlinuz-3.2.0-29-generic
  3. config-3.2.0-29-generic  initrd.img-3.2.0-29-generic  memtest86+.bin  System.map-3.2.0-29-generic

如果出现类似如上文件列表,表明此hd0,1为boot分区;如果出现unkonw system,继续ls下一分区。
3、设置root和prefix

  1. grub rescue>set root=(hd0,1)
  2. grub rescue>set root=(hd0,1)/grub

4、载入模块并启动

  1. grub rescue>insmod /grub/normal.mod
  2. grub rescue>normal

5、这时候顺利的话会成功引导进系统,下一步就是正常的修复grub了。
进入系统后,执行如下命令修复(以ubuntu为例)

  1. sudo update-grub
  2. sudo grub-install /dev/sda

注:/dev/sda根据bios设置的第一硬盘设置。如果重启之后还出现grub rescue,重复以上步骤,把sda换成其它硬盘,直到成功为止。
centos的grub修复请参考http://devops.webres.wang/2012/06/centos-install-repair-grub/

centos安装或修复grub引导

有时候我们使用u盘安装linux系统,不小心把grub安装到u盘,导致引导需要插入u盘才能启动服务器,或者grub损坏,这时需要重新安装grub到硬盘。

安装grub方法1

指定/boot分区

  1. grub> root (hd0,0)

如果不确定/boot是在哪个分区,使用下面的命令找出。

  1. grub> find /boot/grub/stage1

安装grub到第一硬盘的MBR。

  1. grub> setup (hd0)

或者安装grub到第一硬盘第一分区引导扇区。

  1. grub> setup (hd0,0)

安装grub方法2

  1. # grub-install –root-directory=/boot /dev/hda

使用grub手动引导linux和windows

引导Linux

重启进入到grub菜单界面时,按“c”键进入grub命令模式。
1、指定/boot所在的分区,比如分区是第一块硬盘第一分区,即hd0,0

  1. grub> root (hd0,0)

2、指定kernel。

  1. grub> kernel /vmlinuz

3、指定initrd。

  1. grub> initrd /initrd

4、开始引导。

  1. grub> boot

引导windows

重启进入到grub菜单界面时,按“c”键进入grub命令模式。

  1. grub> rootnoverify (hd0,0)
  2. grub> chainloader +1
  3. grub> makeactive
  4. grub> boot