如何配置并排除GNU引导加载程序(GRUB)故障

由于 LFCS 考试需求的变动已于 2016 年 2 月 2 日生效,因此我们向 LFCS 系列 添加了一些必要的话题。为了准备认证考试,我们也强烈推荐你去看看 LFCE 系列。

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

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

  1. 一个叫做 POST(上电自检)的过程会对你的电脑硬件组件做全面的检查。
  2. 当 POST 完成后,它会把控制权转交给引导加载程序,接下来引导加载程序会将 Linux 内核(以及 initramfs)加载到内存中并执行。
  3. 内核首先检查并访问硬件,然后运行初始化进程(主要以它的通用名 init 而为人熟知),接下来初始化进程会启动一些服务,最后完成系统启动过程。

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

GRUB 引导装载程序介绍

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

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

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

  1. 通过指定使用不同的内核来修改系统的行为;
  2. 从多个操作系统中选择一个启动;
  3. 添加或编辑配置区块来改变启动选项等。

如今,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 上,当系统最初完成安装后,会生成如下的配置文件:


  1. GRUB_TIMEOUT=5 
  2. GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" 
  3. GRUB_DEFAULT=saved 
  4. GRUB_DISABLE_SUBMENU=true 
  5. GRUB_TERMINAL_OUTPUT="console" 
  6. 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" 
  7. GRUB_DISABLE_RECOVERY="true" 

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


  1. # info grub 

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


  1. # info -f grub -n 'Simple configuration' 

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

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

在 CentOS 和 openSUSE 系统上


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

在 Ubuntu 系统上


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

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


  1. GRUB_DEFAULT=3 

 使用旧版内核启动系统

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

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


  1. 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 并重启即可:


  1. 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:


  1. # ls (hd0,msdos1)/ 

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

查找 Grub 配置

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


  1. set prefix=(hd0,msdos1)/grub2 
  2. set root=(hd0,msdos1) 
  3. insmod normal 
  4. normal 

 查找并启动 Grub 菜单

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


  1. # grub2-install /dev/sdX 

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

总结

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

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

作者:Gabriel Cánepa

来源:51CTO

时间: 2024-11-03 00:21:49

如何配置并排除GNU引导加载程序(GRUB)故障的相关文章

LFCS 系列第十三讲:如何配置并排除 GNU 引导加载程序(GRUB)故障

由于 LFCS 考试需求的变动已于 2016 年 2 月 2 日生效,因此我们向 LFCS 系列 添加了一些必要的话题.为了准备认证考试,我们也强烈推荐你去看看 LFCE 系列. LFCS 系列第十三讲:配置并排除 Grub 引导加载程序故障. 本文将会向你介绍 GRUB 的知识,并会说明你为什么需要一个引导加载程序,以及它是如何给系统增加功能的. Linux 引导过程 是从你按下你的电脑电源键开始,直到你拥有一个全功能的系统为止,整个过程遵循着这样的主要步骤: 1. 一个叫做 POST(上电自

引导加载程序之争: LILO 和 GRUB

在不考虑他们的工作或专业情况下,所有 Linux 用户都会使用的是哪个工具?引导加载程序.通过本文了解引导加载程序的工作原理,认识两个流行的引导加载程序 LILO(LInux LOader)和 GNU GRUB(GRand Unified Boot loader), 并研究两者各自的优点和缺点. 什么是引导加载程序? 最简单地讲,引导加载程序(boot loader) 会引导操作系统.当机器引导它的操作系统时,BIOS 会读取引导介质上最前面的 512 字节(即人们所知的 主引导记录(maste

Gujin 2.8.5发布 PC引导加载程序

Gujin是一个PC引导加载程序,可用于分析你的分割区和文件系统.它能够发现Linux内核映像,以及其他可引导分区(* BSD.MS-DOS.Windows,等)和文件(*.kgz)和启动磁盘映像(*.bdi),并显示了一个图形化的菜单选择来引导系统. Gujin使用文件记录的接口来引导Linux内核,如:LILO和GRUB,所以它不需要任何其他预装引导程序.它可以直接加载gzip压缩的ELF32或ELF64文件,用一个简单的界面来收集实模式的BIOS数据.你无需执行任何一个新的内核,只需将该内

winxp系统中CAD2012配置的Heidi驱动程序未加载怎么办?

  AutoCAD2012打开出错:配置的Heidi驱动程序未加载,切换到默认软件驱动程序. Autodesk Inventor Fusion 2012打开出错:应用程序不可用,很抱歉,初始化图形子系统时出错.这可能是由于以下一种或多种原因所致:您的图形驱动程序没有针对"真彩色"进行配置;安装应用程序时出现问题;应用程序安装受损;或者图形硬件和驱动程序或应用程序配置出现其他问题. 1.对于XP系统,在桌面上点"右键"-属性-设置-高级-疑难解答-将"硬件加

CodeIgniter配置之autoload.php自动加载用法分析_php实例

本文实例分析了CodeIgniter配置之autoload.php自动加载用法.分享给大家供大家参考,具体如下: CodeIgniter带了自动加载的功能,可以全局加载类库.模型.配置.语言包等,对于需要全局使用的功能相当方便. 例如:有个全局函数写在app_helper.php中,需要全局加载这个函数,只需设置autoload.php: 复制代码 代码如下: $autoload['helper'] = array('app'); 接下来,所有的地方都可以使用了,配置.模型等配置相似.但方便的同

Gujin 2.8.4发布 PC引导加载器

Gujin一个PC引导加载器,可以分析你的分区和文件系统.它发现可用的Linux内核映像,以及其他(如*BSD,MS-DOS,Windows等)可引导分区,文件(*. KGZ)和启动磁盘映像(*. BDI),并显示图形菜单选择哪个系统引导.它使用Linux内核的文件接口引导,如LILO和GRUB,所以它不需要任何其他预安装引导程序.它也可以直接加.gzip压缩ELF32或ELF64文件,用一个简单的界面,收集实模式BIOS数据.复制到"/boot"目录内核映像文件,用标准的名称.Guj

大数据与机器学习:实践方法与行业案例.3.3 自动加载程序的数据库设计

3.3 自动加载程序的数据库设计 根据之前的设计,自动加载程序需要从数据库配置表中获取配置信息,并不断更新相关的状态,表3-2列出了自动加载程序需要的所有配置表. 表3-2 自动加载程序的配置表 表 名 中文名称 用 途 file_settings 数据文件信息表 存储数据文件名称.日期等配置信息 file_status 数据文件状态表 存储数据文件的状态 load_config 加载配置信息表 存储数据库中表的相关信息 ftp_server 数据缓冲区信息表 存储数据缓冲区文件服务器的相关信息

使用Donetbar控件,出现“设计器加载程序未提供根组件 但没有指出原因”错误如何解决

问题描述 使用Donetbar控件,出现"设计器加载程序未提供根组件 但没有指出原因"错误如何解决 使用donetbar控件搭建winform窗体应用程序,在用到SuperTabControl的SelectedTabChanged方法时,只要后台代码有改动,设计界面就会变成空白,去掉这个方法就正常,请问这是什么问题,如何解决? 解决方案 应该是你的dotnetbar是破解的或者版本和你用的.net框架不匹配造成的.

webadi-ORACLE WEB ADI 加载程序错误

问题描述 ORACLE WEB ADI 加载程序错误 ORACLE WEB ADI 加载程序错误 创建集成器的时候,加载程序那一步,选择 自模板,然后点击创建按钮,报错信息如下: oracle.jbo.TooManyObjectsException: JBO-25013: 匹配主键 oracle.jbo.Key 的对象太多. 有没有WEB ADI 的大神知道如何解决,希望能告知解决的具体方法. 注:个人感觉是集成器的一些表中的数据没有清理干净引起的,但具体是哪些表的哪些字段,目前并不清楚. 希望