标签 GRUB2 下的文章

你是否曾经对操作系统为何能够执行应用程序而感到疑惑?那么本文将为你揭开操作系统引导与启动的面纱。

理解操作系统开机引导和启动过程对于配置操作系统和解决相关启动问题是至关重要的。该文章陈述了 GRUB2 引导装载程序开机引导装载内核的过程和 systemd 初始化系统执行开机启动操作系统的过程。

事实上,操作系统的启动分为两个阶段: 引导 boot 启动 startup 。引导阶段开始于打开电源开关,结束于内核初始化完成和 systemd 进程成功运行。启动阶段接管了剩余工作,直到操作系统进入可操作状态。

总体来说,Linux 的开机引导和启动过程是相当容易理解,下文将分节对于不同步骤进行详细说明。

  • BIOS 上电自检(POST)
  • 引导装载程序 (GRUB2)
  • 内核初始化
  • 启动 systemd,其是所有进程之父。

注意,本文以 GRUB2 和 systemd 为载体讲述操作系统的开机引导和启动过程,是因为这二者是目前主流的 linux 发行版本所使用的引导装载程序和初始化软件。当然另外一些过去使用的相关软件仍然在一些 Linux 发行版本中使用。

引导过程

引导过程能以两种方式之一初始化。其一,如果系统处于关机状态,那么打开电源按钮将开启系统引导过程。其二,如果操作系统已经运行在一个本地用户(该用户可以是 root 或其他非特权用户),那么用户可以借助图形界面或命令行界面通过编程方式发起一个重启操作,从而触发系统引导过程。重启包括了一个关机和重新开始的操作。

BIOS 上电自检(POST)

上电自检过程中其实 Linux 没有什么也没做,上电自检主要由硬件的部分来完成,这对于所有操作系统都一样。当电脑接通电源,电脑开始执行 BIOS( 基本输入输出系统 Basic I/O System )的 POST( 上电自检 Power On Self Test )过程。

在 1981 年,IBM 设计的第一台个人电脑中,BIOS 被设计为用来初始化硬件组件。POST 作为 BIOS 的组成部分,用于检验电脑硬件基本功能是否正常。如果 POST 失败,那么这个电脑就不能使用,引导过程也将就此中断。

BIOS 上电自检确认硬件的基本功能正常,然后产生一个 BIOS 中断 INT 13H,该中断指向某个接入的可引导设备的引导扇区。它所找到的包含有效的引导记录的第一个引导扇区将被装载到内存中,并且控制权也将从引导扇区转移到此段代码。

引导扇区是引导加载器真正的第一阶段。大多数 Linux 发行版本使用的引导加载器有三种:GRUB、GRUB2 和 LILO。GRUB2 是最新的,也是相对于其他老的同类程序使用最广泛的。

GRUB2

GRUB2 全称是 GRand Unified BootLoader,Version 2(第二版大一统引导装载程序)。它是目前流行的大部分 Linux 发行版本的主要引导加载程序。GRUB2 是一个用于计算机寻找操作系统内核并加载其到内存的智能程序。由于 GRUB 这个单词比 GRUB2 更易于书写和阅读,在下文中,除特殊指明以外,GRUB 将代指 GRUB2。

GRUB 被设计为兼容操作系统多重引导规范,它能够用来引导不同版本的 Linux 和其他的开源操作系统;它还能链式加载专有操作系统的引导记录。

GRUB 允许用户从任何给定的 Linux 发行版本的几个不同内核中选择一个进行引导。这个特性使得操作系统,在因为关键软件不兼容或其它某些原因升级失败时,具备引导到先前版本的内核的能力。GRUB 能够通过文件 /boot/grub/grub.conf 进行配置。(LCTT 译注:此处指 GRUB1)

GRUB1 现在已经逐步被弃用,在大多数现代发行版上它已经被 GRUB2 所替换,GRUB2 是在 GRUB1 的基础上重写完成。基于 Red Hat 的发行版大约是在 Fedora 15 和 CentOS/RHEL 7 时升级到 GRUB2 的。GRUB2 提供了与 GRUB1 同样的引导功能,但是 GRUB2 也是一个类似主框架(mainframe)系统上的基于命令行的前置操作系统(Pre-OS)环境,使得在预引导阶段配置更为方便和易操作。GRUB2 通过 /boot/grub2/grub.cfg 进行配置。

两个 GRUB 的最主要作用都是将内核加载到内存并运行。两个版本的 GRUB 的基本工作方式一致,其主要阶段也保持相同,都可分为 3 个阶段。在本文将以 GRUB2 为例进行讨论其工作过程。GRUB 或 GRUB2 的配置,以及 GRUB2 的命令使用均超过本文范围,不会在文中进行介绍。

虽然 GRUB2 并未在其三个引导阶段中正式使用这些 阶段 stage 名词,但是为了讨论方便,我们在本文中使用它们。

阶段 1

如上文 POST(上电自检)阶段提到的,在 POST 阶段结束时,BIOS 将查找在接入的磁盘中查找引导记录,其通常位于 MBR( 主引导记录 Master Boot Record ),它加载它找到的第一个引导记录中到内存中,并开始执行此代码。引导代码(及阶段 1 代码)必须非常小,因为它必须连同分区表放到硬盘的第一个 512 字节的扇区中。 在传统的常规 MBR 中,引导代码实际所占用的空间大小为 446 字节。这个阶段 1 的 446 字节的文件通常被叫做引导镜像(boot.img),其中不包含设备的分区信息,分区是一般单独添加到引导记录中。

由于引导记录必须非常的小,它不可能非常智能,且不能理解文件系统结构。因此阶段 1 的唯一功能就是定位并加载阶段 1.5 的代码。为了完成此任务,阶段 1.5 的代码必须位于引导记录与设备第一个分区之间的位置。在加载阶段 1.5 代码进入内存后,控制权将由阶段 1 转移到阶段 1.5。

阶段 1.5

如上所述,阶段 1.5 的代码必须位于引导记录与设备第一个分区之间的位置。该空间由于历史上的技术原因而空闲。第一个分区的开始位置在扇区 63 和 MBR(扇区 0)之间遗留下 62 个 512 字节的扇区(共 31744 字节),该区域用于存储阶段 1.5 的代码镜像 core.img 文件。该文件大小为 25389 字节,故此区域有足够大小的空间用来存储 core.img。

因为有更大的存储空间用于阶段 1.5,且该空间足够容纳一些通用的文件系统驱动程序,如标准的 EXT 和其它的 Linux 文件系统,如 FAT 和 NTFS 等。GRUB2 的 core.img 远比更老的 GRUB1 阶段 1.5 更复杂且更强大。这意味着 GRUB2 的阶段 2 能够放在标准的 EXT 文件系统内,但是不能放在逻辑卷内。故阶段 2 的文件可以存放于 /boot 文件系统中,一般在 /boot/grub2 目录下。

注意 /boot 目录必须放在一个 GRUB 所支持的文件系统(并不是所有的文件系统均可)。阶段 1.5 的功能是开始执行存放阶段 2 文件的 /boot 文件系统的驱动程序,并加载相关的驱动程序。

阶段 2

GRUB 阶段 2 所有的文件都已存放于 /boot/grub2 目录及其几个子目录之下。该阶段没有一个类似于阶段 1 与阶段 1.5 的镜像文件。相应地,该阶段主要需要从 /boot/grub2/i386-pc 目录下加载一些内核运行时模块。

GRUB 阶段 2 的主要功能是定位和加载 Linux 内核到内存中,并转移控制权到内核。内核的相关文件位于 /boot 目录下,这些内核文件可以通过其文件名进行识别,其文件名均带有前缀 vmlinuz。你可以列出 /boot 目录中的内容来查看操作系统中当前已经安装的内核。

GRUB2 跟 GRUB1 类似,支持从 Linux 内核选择之一引导启动。Red Hat 包管理器(DNF)支持保留多个内核版本,以防最新版本内核发生问题而无法启动时,可以恢复老版本的内核。默认情况下,GRUB 提供了一个已安装内核的预引导菜单,其中包括问题诊断菜单(recuse)以及恢复菜单(如果配置已经设置恢复镜像)。

阶段 2 加载选定的内核到内存中,并转移控制权到内核代码。

内核

内核文件都是以一种自解压的压缩格式存储以节省空间,它与一个初始化的内存映像和存储设备映射表都存储于 /boot 目录之下。

在选定的内核加载到内存中并开始执行后,在其进行任何工作之前,内核文件首先必须从压缩格式解压自身。一旦内核自解压完成,则加载 systemd 进程(其是老式 System V 系统的 init 程序的替代品),并转移控制权到 systemd。

这就是引导过程的结束。此刻,Linux 内核和 systemd 处于运行状态,但是由于没有其他任何程序在执行,故其不能执行任何有关用户的功能性任务。

启动过程

启动过程紧随引导过程之后,启动过程使 Linux 系统进入可操作状态,并能够执行用户功能性任务。

systemd

systemd 是所有进程的父进程。它负责将 Linux 主机带到一个用户可操作状态(可以执行功能任务)。systemd 的一些功能远较旧式 init 程序更丰富,可以管理运行中的 Linux 主机的许多方面,包括挂载文件系统,以及开启和管理 Linux 主机的系统服务等。但是 systemd 的任何与系统启动过程无关的功能均不在此文的讨论范围。

首先,systemd 挂载在 /etc/fstab 中配置的文件系统,包括内存交换文件或分区。据此,systemd 必须能够访问位于 /etc 目录下的配置文件,包括它自己的。systemd 借助其配置文件 /etc/systemd/system/default.target 决定 Linux 系统应该启动达到哪个状态(或 目标态 target )。default.target 是一个真实的 target 文件的符号链接。对于桌面系统,其链接到 graphical.target,该文件相当于旧式 systemV init 方式的 runlevel 5。对于一个服务器操作系统来说,default.target 更多是默认链接到 multi-user.target, 相当于 systemV 系统的 runlevel 3emergency.target 相当于单用户模式。

(LCTT 译注:“target” 是 systemd 新引入的概念,目前尚未发现有官方的准确译名,考虑到其作用和使用的上下文环境,我们认为翻译为“目标态”比较贴切。以及,“unit” 是指 systemd 中服务和目标态等各个对象/文件,在此依照语境译作“单元”。)

注意,所有的 目标态 target 服务 service 均是 systemd 的 单元 unit

如下表 1 是 systemd 启动的 目标态 target 和老版 systemV init 启动 运行级别 runlevel 的对比。这个 systemd 目标态别名 是为了 systemd 向前兼容 systemV 而提供。这个目标态别名允许系统管理员(包括我自己)用 systemV 命令(例如 init 3)改变运行级别。当然,该 systemV 命令是被转发到 systemd 进行解释和执行的。

SystemV 运行级别systemd 目标态systemd 目标态别名描述
halt.target 停止系统运行但不切断电源。
0poweroff.targetrunlevel0.target停止系统运行并切断电源.
Semergency.target 单用户模式,没有服务进程运行,文件系统也没挂载。这是一个最基本的运行级别,仅在主控制台上提供一个 shell 用于用户与系统进行交互。
1rescue.targetrunlevel1.target挂载了文件系统,仅运行了最基本的服务进程的基本系统,并在主控制台启动了一个 shell 访问入口用于诊断。
2 runlevel2.target多用户,没有挂载 NFS 文件系统,但是所有的非图形界面的服务进程已经运行。
3multi-user.targetrunlevel3.target所有服务都已运行,但只支持命令行接口访问。
4 runlevel4.target未使用。
5graphical.targetrunlevel5.target多用户,且支持图形界面接口。
6reboot.targetrunlevel6.target重启。
default.target 这个 目标态 target 是总是 multi-user.targetgraphical.target 的一个符号链接的别名。systemd 总是通过 default.target 启动系统。default.target 绝不应该指向 halt.targetpoweroff.targetreboot.target

表 1 老版本 systemV 的 运行级别与 systemd 与 目标态 target 或目标态别名的比较

每个 目标态 target 有一个在其配置文件中描述的依赖集,systemd 需要首先启动其所需依赖,这些依赖服务是 Linux 主机运行在特定的功能级别所要求的服务。当配置文件中所有的依赖服务都加载并运行后,即说明系统运行于该目标级别。

systemd 也会查看老式的 systemV init 目录中是否存在相关启动文件,若存在,则 systemd 根据这些配置文件的内容启动对应的服务。在 Fedora 系统中,过时的网络服务就是通过该方式启动的一个实例。

如下图 1 是直接从 bootup 的 man 页面拷贝而来。它展示了在 systemd 启动过程中一般的事件序列和确保成功的启动的基本的顺序要求。

sysinit.targetbasic.target 目标态可以被视作启动过程中的状态检查点。尽管 systemd 的设计初衷是并行启动系统服务,但是部分服务或功能目标态是其它服务或目标态的启动的前提。系统将暂停于检查点直到其所要求的服务和目标态都满足为止。

sysinit.target 状态的到达是以其所依赖的所有资源模块都正常启动为前提的,所有其它的单元,如文件系统挂载、交换文件设置、设备管理器的启动、随机数生成器种子设置、低级别系统服务初始化、加解密服务启动(如果一个或者多个文件系统加密的话)等都必须完成,但是在 sysinit.target 中这些服务与模块是可以并行启动的。

sysinit.target 启动所有的低级别服务和系统初具功能所需的单元,这些都是进入下一阶段 basic.target 的必要前提。

图 1:systemd 的启动流程

sysinit.target 的条件满足以后,systemd 接下来启动 basic.target,启动其所要求的所有单元。 basic.target 通过启动下一目标态所需的单元而提供了更多的功能,这包括各种可执行文件的目录路径、通信 sockets,以及定时器等。

最后,用户级目标态(multi-user.targetgraphical.target) 可以初始化了,应该注意的是 multi-user.target 必须在满足图形化目标态 graphical.target 的依赖项之前先达成。

图 1 中,以 * 开头的目标态是通用的启动状态。当到达其中的某一目标态,则说明系统已经启动完成了。如果 multi-user.target 是默认的目标态,则成功启动的系统将以命令行登录界面呈现于用户。如果 graphical.target 是默认的目标态,则成功启动的系统将以图形登录界面呈现于用户,界面的具体样式将根据系统所配置的显示管理器而定。

故障讨论

最近我需要改变一台使用 GRUB2 的 Linux 电脑的默认引导内核。我发现一些 GRUB2 的命令在我的系统上不能用,也可能是我使用方法不正确。至今,我仍然不知道是何原因导致,此问题需要进一步探究。

grub2-set-default 命令没能在配置文件 /etc/default/grub 中成功地设置默认内核索引,以至于期望的替代内核并没有被引导启动。故在该配置文件中我手动更改 GRUB_DEFAULT=savedGRUB_DEFAULT=2,2 是我需要引导的安装好的内核文件的索引。然后我执行命令 grub2-mkconfig > /boot/grub2/grub.cfg 创建了新的 GRUB 配置文件,该方法如预期的规避了问题,并成功引导了替代的内核。

结论

GRUB2、systemd 初始化系统是大多数现代 Linux 发行版引导和启动的关键组件。尽管在实际中,systemd 的使用还存在一些争议,但是 GRUB2 与 systemd 可以密切地配合先加载内核,然后启动一个业务系统所需要的系统服务。

尽管 GRUB2 和 systemd 都比其前任要更加复杂,但是它们更加容易学习和管理。在 man 页面有大量关于 systemd 的帮助说明,freedesktop.org 也在线收录了完整的此帮助说明。下面有更多相关信息链接。

附加资源


作者简介:

David Both 居住在美国北卡罗纳州的首府罗利,是一个 Linux 开源贡献者。他已经从事 IT 行业 40 余年,在 IBM 教授 OS/2 20余年。1981 年,他在 IBM 开发了第一个关于最初的 IBM 个人电脑的培训课程。他也曾在 Red Hat 教授 RHCE 课程,也曾供职于 MCI worldcom,Cico 以及北卡罗纳州等。他已经为 Linux 开源社区工作近 20 年。


via: https://opensource.com/article/17/2/linux-boot-and-startup

作者:David Both 译者: penghuster 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习 GRUB 引导加载程序是如何预备你的系统并启动操作系统内核的。

 title=

自从上个月为我的文章《Linux 引导和启动过程简介》做研究开始,我对更深入了解 GRUB2 产生了兴趣。这篇文章提供了配置 GRUB2 的简要介绍。为了简便起见,我大多数情况下会使用 GRUB 指代 GRUB2。

GRUB

GRUB 来自 GRand Unified Bootloader 的缩写。它的功能是在启动时从 BIOS 接管掌控、加载自身、加载 Linux 内核到内存,然后再把执行权交给内核。一旦内核开始掌控,GRUB 就完成了它的任务,也就不再需要了。

GRUB 支持多种 Linux 内核,并允许用户在启动时通过菜单在其中选择。我发现这是一种非常有用的工具,因为我有很多次遇到一个应用程序或者系统服务在特定内核版本下失败的问题。有好几次,引导到一个较旧的内核时就可以避免类似的问题。默认情况下,使用 yumdnf 进行更新时会保存三个内核 - 最新的以及两个比较旧的。在被包管理器删除之前所保留的内核数目可以在 /etc/dnf/dnf.conf/etc/yum.conf 文件中配置。我通常把 installonly_limit 的值修改为 9 以便保留 9 个内核。当我不得不恢复到低几个版本的内核时这非常有用。

GRUB 菜单

GRUB 菜单的功能是当默认的内核不是想要的时,允许用户从已经安装的内核中选择一个进行引导。通过上下箭头键允许你选中想要的内核,敲击回车键会使用选中的内核继续引导进程。

GRUB 菜单也提供了超时机制,因此如果用户没有做任何选择,GRUB 就会在没有用户干预的情况下使用默认内核继续引导。敲击键盘上除了回车键之外的任何键会停止终端上显示的倒数计时器。立即敲击回车键会使用默认内核或者选中的内核继续引导进程。

GRUB 菜单提供了一个 “ 救援 rescue ” 内核,用于故障排除或者由于某些原因导致的常规内核不能完成启动过程。不幸的是,这个救援内核不会引导到救援模式。文章后面会更详细介绍这方面的东西。

grub.cfg 文件

grub.cfg 文件是 GRUB 配置文件。它由 grub2-mkconfig 程序根据用户的配置使用一组主配置文件以及 grub 默认文件而生成。/boot/grub2/grub.cfg 文件在 Linux 安装时会初次生成,安装新内核时又会重新生成。

grub.cfg 文件包括了类似 Bash 脚本的代码以及一个按照安装顺序排序的已安装内核列表。例如,如果你有 4 个已安装内核,最新的内核索引是 0,前一个内核索引是 1,最旧的内核索引是 3。如果你能访问 grub.cfg 文件,你应该去看看感受一下它看起来是什么样。grub.cfg 太大也就没有包含在这篇文章中。

GRUB 配置文件

grub.cfg 的主要配置文件都在 /etc/grub.d 目录。该目录中的每个文件都包含了最终会整合到 grub.cfg 文件中的 GRUB 代码。这些配置文件的命名模式以排序方式设计,这使得最终的 grub.cfg 文件可以按正确的顺序整合而成。每个文件都有注释表明该部分的开始和结束,这些注释也是最终的 grub.cfg 文件的一部分,从而可以看出每个部分是由哪个文件生成。分隔注释看起来像这样:

### BEGIN /etc/grub.d/10_linux ###

### END /etc/grub.d/10_linux ###

不要修改这些文件,除非你是一个 GRUB 专家并明白更改会发生什么。无论如何,修改 grub.cfg 文件时你也总应该保留一个原始文件的备份。 40_custom41_custom 这两个特别的文件用于生成用户对 GRUB 配置的修改。你仍然要注意对这些文件的更改的后果,并保存一份原始 grub.cfg 文件的备份。

你也可以把你自己的文件添加到 /etc/grub.d 目录。这样做的一个可能的原因是为非 Linux 操作系统添加菜单行。要注意遵循命名规则,确保配置文件中额外的菜单选项刚好在 10_linux 条目之前或之后。

GRUB 默认文件

老版本 GRUB 的配置非常简单而明了,我只需要修改 /boot/grub/grub.conf 就可以了。对于新版本的 GRUB2,我虽然还可以通过更改 /boot/grub2/grub.cfg 来修改,但和老版本的 GRUB 相比,新版本相对更加复杂。另外,安装一个新内核时 grub.cfg 可能会被重写,因此任何修改都可能消失。当然,GNU.org 的 GRUB 手册确实有过直接创建和修改 /boot/grub2/grub.cfg 的讨论。

一旦你明白了如何做,更改 GRUB2 配置就会变得非常简单。我为之前的文章研究 GRUB2 的时候才明白这个。秘方就在 /etc/default 目录里面,一个自然而然称为 grub 的文件,它可以通过简单的终端命令操作。/etc/default 目录包括了一些类似 Google Chrome、 useradd、 和 grub 程序的配置文件。

/etc/default/grub 文件非常简单。这个 grub 默认文件已经列出了一些有效的键值对。你可以简单地更改现有键值或者添加其它文件中还没有的键。下面的列表 1 显示了一个没有更改过的 /etc/default/grub 文件。

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="rd.lvm.lv=fedora_fedora25vm/root 
   rd.lvm.lv=fedora_fedora25vm/swap 
   rd.lvm.lv=fedora_fedora25vm/usr rhgb quiet"
GRUB_DISABLE_RECOVERY="true"

列表 1:Fedora 25 一个原始 grub 默认文件。

GRUB 手册 5.1 章节包括了所有可以添加到该 grub 文件的键的信息。我只需要修改 grub 默认文件已经有的一些键值就够了。让我们看看这些键值以及一些在 grub 默认文件中没有出现的每个键的意义。

  • GRUB_TIMEOUT 这个键的值决定了显示 GRUB 选择菜单的时间长度。GRUB 提供了同时保存多个安装内核并在启动时使用 GRUB 菜单在其中选择的功能。这个键的默认值是 5 秒,但我通常修改为 10 秒使得有更多时间查看选项并作出选择。
  • GRUB_DISTRIBUTOR 这个键定义了一个从 /etc/system-release 文件中提取发行版本的 sed 表达式。这个信息用于生成出现在 GRUB 菜单中的每个内核发布版的文本名称,例如 “Fedora” 等。由于不同发行版之间 system-release 文件结构的差异,在你的系统中这个 sed 表达式可能有些不同。
  • GRUB_DEFAULT 决定默认引导哪个内核。如果是 saved,这代表最新内核。这里的其它选项如果是数字则代表了 grub.cfg 中列表的索引。使用索引号 3,就会总是加载列表中的第四个内核,即使安装了一个新内核之后也是。因此使用索引数字的话,在安装一个新内核后会加载不同的内核。要确保引导特定内核版本的唯一方法是设置 GRUB_DEFAULT 的值为想要内核的名称,例如 4.8.13-300.fc25.x86_64
  • GRUB_SAVEDEFAULT 通常,grub 默认文件中不会指定这个选项。当选择不同内核进行引导时,正常操作下该内核只会启动一次。默认内核不会改变。当其设置为 true 并和 GRUB_DEFAULT=saved 一起使用时,这个选项会保存一个不同内核作为默认值。当选择不同内核进行引导时会发生这种情况。
  • GRUB_DISABLE_SUBMENU 一些人可能会希望为 GRUB 菜单创建一个内核的层级菜单结构。这个键和 grub.cfg 中一些额外内核配置允许创建这样的层级结构。例如,主菜单中可能有 productiontest 子菜单,每个子菜单中包括了一些合适的内核。设置它为 false 可以启用子菜单。
  • GRUB_TERMINAL_OUTPUT 一些环境下可能需要或者必要将输出重定向到一个不同的显示控制台或者终端。默认情况下是把输出发送到默认终端,通常 console 等价于 Intel 系列个人电脑的标准输出。另一个有用的选择是在使用串行终端或者 Integrated Lights Out (ILO) 终端连接的数据中心或者实验室环境中指定 serial
  • GRUB_TERMINAL_INPUTGRUB_TERMINAL_OUTPUT 类似,可能需要或者必要重定向输入为串行终端或者 ILO 设备、而不是标准键盘输入。
  • GRUB_CMDLINE_LINUX 这个键包括了在启动时会传递给内核的命令行参数。注意这些参数会被添加到 grub.cfg 所有已安装内核的内核行。这意味着所有已安装的内核在启动时都会有相同的参数。我通常删除 rhgbquiet 参数以便我可以看到引导和启动时内核和 systemd 输出的所有内核信息消息。
  • GRUB_DISABLE_RECOVERY 当这个键的值被设置为 false,GRUB 菜单中就会为每个已安装的内核创建一个恢复条目。当设置为 true 时就不会创建任何恢复条目。但不管这个设置怎样,最后的内核条目总是一个 rescue 选项。不过在 rescue 选项中我遇到了一个问题,下面我会详细介绍。

还有一些你可能觉得有用但我没有在这里介绍的键。它们的描述可以在 GRUB 手册 2 的 5.1 章节找到。

生成 grub.cfg

完成所需的配置之后,就需要生成 /boot/grub2/grub.cfg 文件。这通过下面的命令完成。

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

这个命令按照顺序使用位于 /etc/grub.d 的配置文件构建 grub.cfg 文件,然后使用 grub 默认文件的内容修改输出以便获得最终所需的配置。grub2-mkconfig 命令会尝试定位所有已安装的内核并在 grub.cfg 文件的 10_Linux 部分新建条目。它还创建一个 rescue 条目提供一个用于从 Linux 不能启动的严重问题中恢复的方法。

强烈建议你不要手动编辑 grub.cfg 文件,因为任何对该文件的直接修改都会在下一次安装新内核或者手动运行 grub2-mkconfig 时被重写。

问题

我遇到一个如果没有意识到就可能导致严重后果的 GRUB2 问题。这个救援内核没有启动,反而启动了另外一个内核。我发现那是列表中索引为 1 的内核,也就是列表中的第二个内核。额外的测试发现不管使用原始的还是我生成的 grub.cfg 配置文件都会发生这个问题。我在虚拟机和真实硬件上都尝试过而且都发生了这个问题。我只测试了 Fedora 25,因此其它 Fedora 发行版本可能没有这个问题。

注意,从救援内核生成的 “recovery” 内核条目不能引导到维护模式。

我推荐将 grub 默认文件中 GRUB_DISABLE_RECOVERY 的值更改为 “false”,然后生成你自己的 grub.cfg。这会在 GRUB 菜单中为每个已安装的内核生成可用的恢复条目。这些恢复配置能像期望那样工作,从而从那些需要输入密码登录的内核条目中引导到运行级别 1,也就是进入(不需要密码的)单用户维护模式。你也可以按 Ctrl-D 继续正常的引导进入默认运行级别。

总结

GRUB 是引导 Linux 计算机到可用状态过程的一系列事件中,发生在 BIOS 之后的第一步。理解如何配置 GRUB 对于恢复或者处理多种类型的问题非常重要。

这么多年来我多次不得不引导到恢复或者救援模式以便解决多种类型的问题。其中的一些问题确实是类似 /etc/fstab 或其它配置文件中不恰当条目导致的引导问题,也有一些是由于应用程序或者系统软件和最新的内核不兼容的问题。硬件兼容性问题也可能妨碍特定的内核启动。

我希望这些信息能对你开启 GRUB 配置之旅有所帮助。

( 题图 : Internet Archive Book Images. Opensource.com 修改。 CC BY-SA 4.0)


作者简介:

David Both - David Both 是一个居住在 Raleigh,北卡罗来纳州的 Linux 和开源倡导者。他在 IT 界已经有超过 40 年,并在他工作的 IBM 执教 OS/2 20 多年。在 IBM 的时候,他在 1981 年开设了第一个最初 IBM 个人电脑的培训课程。他在红帽教授过 RHCE 课程并在 MCI Worldcom、 Cisco、 和北卡罗来纳州工作过。他已经在 Linux 和开源软件方面工作将近 20 年。


via: https://opensource.com/article/17/3/introduction-grub2-configuration-linux

作者:David Both 译者:ictlyh 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Linux的GRUB2启动加载器可以直接从硬盘启动Linux ISO文件,可以启动Live CD的 ISO,而不用烧录到光盘来安装Linux到一个硬盘分区,或从USB驱动启动。

我们在Ubuntu 14.04上实施了该过程——Ubuntu及基于Ubuntu的Linux版本对此支持良好。其它Linux发行版上的工作原理也类似。

获取Linux ISO文件

这一密技需要你的硬盘驱动器上安装有Linux系统,你的计算机必须使用GRUB2启动加载器,这是大多数Linux系统的标准启动加载器。不好意思,你是不能使用Windows启动加载器来直接启动一个Linux ISO文件的。

下载你想要使用的ISO文件,并放到你的Linux分区中。GRUB2应该支持大多数Linux系统的。如果你想要在live环境中使用它们,而不想将它们安装到硬盘驱动器上,请确认你下载的是各个Linux ISO的“live CD”版本。很多基于Linux的可启动工具盘也应该可以工作。

检查ISO文件内容

你可能需要查看ISO文件的内部来知道那些特定的的文件在哪里。例如,你可以通过使用Ubuntu及其它基于GNOME的桌面环境中的归档管理器/文件管理器这些图形化应用程序来打开ISO文件。在Nautilus文件管理器中,右击ISO文件并选择使用归档管理器打开。

找到内核文件和initrd映像。如果你正在使用Ubuntu ISO文件,你会在casper文件夹中找到这些文件——vmlinuz文件是Linux内核,而initrd文件是initrd映像。后面,你需要知道它们在ISO文件中所处的位置。

检查硬盘分区路径

GRUB使用与Linux不同的“设备命名”方式。在Linux系统中,/dev/sda0是硬盘上的第一个分区——a是指第一个硬盘,而0是指第一个分区。在GRUB中,与/dev/sda0相对应的是(hd0,1)。0指第一个硬盘,而1则指它上面的第一个分区。换句话说,在GRUB设备名中,磁盘编号从0开始计数,而分区编号则从1开始计数——是啊,这真是突然令人困惑。例如,(hd3,6)是指第四磁盘上的第六分区。

你可以使用fdisk -l命令来查看该信息。在Ubuntu上,打开终端并运行以下命令:

sudo fdisk -l

你将看到一个Linux设备路径列表,你可以自行将它们转成GRUB设备名。例如,在下面的图片中,我们可以看到有个系统分区是/dev/sda1——那么,对于GRUB而言,它就是(hd0,1)。

创建GRUB2启动条目

添加自定义启动条目的最简单的方式是编辑/etc/grub.d/40\_custom脚本,该文件设计用于用户自行添加启动条目。在编辑该文件后,/etc/defaults/grub文件和/etc/grub.d/脚本的内容将合成创建/boot/grub/grub.cfg文件——你不应该手工编辑这个文件。它被设计为通过你在另外的文件中指定的设置自动生成。

你需要以root特权打开/etc/grub.d/40\_custom文件来编辑。在Ubuntu上,你可以通过打开终端窗口,并运行以下命令来完成:

sudo gedit /etc/grub.d/40_custom

放轻松点,你可以用你喜爱的文本编辑打开该文件。例如,你可以替换命令中“gedit”为“nano”,在Nano文本编辑器中打开它。

除非你已经添加了其它自定义启动条目,否则你应当看到的是一个几乎空的文件。你需要在注释行下添加一个或多个ISO启动部分。

这里为你展示了怎样来从ISO文件启动Ubuntu或基于Ubuntu的发行版,我们在Ubuntu 14.04下作了测试:

menuentry "Ubuntu 14.04 ISO" {
set isofile="/home/name/Downloads/ubuntu-14.04.1-desktop-amd64.iso"
loopback loop (hd0,1)$isofile
linux (loop)/casper/vmlinuz.efi boot=casper iso-scan/filename=${isofile} quiet splash
initrd (loop)/casper/initrd.lz
}

自定义启动条目以包含你期望的菜单的条目名称,并指定计算机上该ISO文件的正确路径,以及包含ISO文件的硬盘和分区设备名。如果vmlinuz和initrd文件的名称或路径不同,请为这些文件指定正确的路径。

(如果你的/home/ 目录是一个分区,请忽略/home部分,像这样:set isofile="/name/Downloads/${isoname}")。

重要说明:不同的Linux版本要求带有不同启动选项的不同的启动条目,GRUB Live ISO多启动项目提供了用于不同Linux发行版的菜单条目的各种不同类型。你应当为你想要启动的ISO文件调整这些示例菜单条目。你也可以仅仅从网页搜索你想要启动的Linux发行版的名称和发行编号,并附带关键词“在GRUB中从ISO启动”,以获取更多信息。

如果你想要添加更多ISO启动选项,请为该文件添加额外部分。

完成后保存文件,返回终端窗口并运行以下命令:

sudo update-grub

再次启动计算机时,你将看到ISO启动条目,你可以选择它来启动ISO文件。在启动时,你可能需要按Shift键来显示GRUB菜单。

如果在尝试启动ISO文件时你看见错误信息或黑屏,那么你的启动条目配置肯定配置错误了。即使ISO文件路径和设备名是正确的,ISO文件上的vmlinuz和initrd文件的路径可能是不正确的,或者你启动Linux系统可能需要不同的选项。


via: http://www.howtogeek.com/196933/how-to-boot-linux-iso-images-directly-from-your-hard-drive/

作者:Chris Hoffman 译者:GOLinux 校对:wxy

本文由 LCTT 原创翻译,Linux中国 荣誉推出