Linux 如何处理单独的 /boot 分区?

jII*_*jII 15 grub boot partition

我有兴趣了解 Linux 如何处理单独的引导分区。我对实际执行此操作感兴趣,但我想知道这是如何在幕后工作的。

考虑一个硬盘驱动器sda,它有两个分区sda1sda2. 假设这sda2是包含 Linux 操作系统的root分区/

我的理解是引导加载程序GRUB2安装到/boot. 但是,当目录/boot位于单独的分区上sda2时,如何在/实际安装之前发生这种情况?

/boot在这种情况下,BIOS、Master 引导记录和 GRUB(或文件)之间的交互如何成功发生?是/boot不是/在这个早期阶段中的数据实际上并未挂载到文件系统?

注意:这个问题涉及挂载根分区,但不讨论单独的引导分区。

str*_*gee 25

这是您理解中的问题:

我的理解是引导加载程序 GRUB2 挂载到 /boot。

GRUB 未在启动时“挂载”。GRUB安装/boot,并从主引导记录中的代码加载。以下是现代启动过程的简化概述,假设 GNU/Linux 发行版带有 MBR/BIOS(不是 GPT/UEFI):

  1. BIOS 加载。
  2. BIOS 加载主引导记录中的一小段代码。
  3. GRUB 不适合 440 字节,即主引导记录的大小。因此,加载的代码实际上只是解析分区表,找到/boot分区(我相信这是在您将 GRUB 安装到主引导记录时确定的),并解析文件系统信息。然后加载 Stage 2 GRUB。(这就是简化的地方。)
  4. 第 2 阶段 GRUB 加载它需要的一切,包括 GRUB 配置,然后显示一个菜单(或不显示,取决于用户配置)。
  5. 选择启动顺序。这可能是由于超时、用户选择菜单项或启动命令列表。
  6. 引导序列开始执行。这可以做很多事情——例如,加载内核、链式加载到另一个引导加载程序——但让我们假设引导顺序是标准的 GNU/Linux。
  7. GRUB 加载 Linux 内核。
  8. GRUB 加载初始 ramdisk
  9. 初始化内存安装件//new_root(可能加密解锁它),开始UDEV,开始与恢复从交换等
  10. 初始 ramdisk 使用pivot_root实用程序设置/new_root为真实的/.
  11. init开始。分区被挂载,守护进程启动,系统启动。

注意内核是如何只在第 7 步加载的。因此,在第 7步之前没有挂载的概念。这就是为什么/boot必须在步骤 9 中再次挂载,即使 GRUB 已经使用了它。

查看GRUB维基百科页面的GRUB 2 部分也可能有用。

  • MBR 代码无法解析文件系统。它在第一个分区之前从 MBR 之后的未使用扇区加载 grub 核心映像,并且该代码了解如何查找和挂载 /boot 分区以查找 grub 配置文件、附加模块和内核。此外,pivot_root 被认为是一个肮脏的 hack,并已被替换为 `run-init`,它会删除 initramfs 中的所有文件,然后将 chroots 插入到根文件系统中。 (7认同)
  • @strugee,在 util-linux 邮件列表上进行讨论后,我的记忆似乎有点偏差:他们停止允许在真正的 rootfs 上使用ivot_root,所以这就是为什么没有人在启动过程中再使用它。Systemd 在关闭时使用它,不是返回到原始的 initrd(切换到真正的 root 时会删除自身),而是切换到新加载的 initrd。请参阅http://marc.info/?l=util-linux-ng&m=139100788306216&w=2 (2认同)

cas*_*sey 6

Linux(内核)并不关心你有多少引导分区。从磁盘加载内核是引导加载程序(例如grubgrub2lilo)的工作,这些工具也不关心内核可能位于的位置数量。他们只关心具体的位置。

例如,我的引导分区是/dev/md1,它是一个 mdadm RAID 镜像,由物理分区/dev/sde1/dev/sdf1. 如果我愿意,我可以单独安装它们,因此从技术上讲这算作有两个引导分区,尽管它们应该包含相同的数据。

有两个分区用于 /boot 对我来说是一个可用性问题,但它们同样可以是不同的 /boot 分区。下一步是引导加载程序如何知道?方法如下:

menuentry 'Linux 3.10.17 (sde) kernel-3.10.17-g' {
        root=hd0,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3
        initrd /boot/initrd-3.10.17-g
}

menuentry 'Linux 3.10.17 (sdf) kernel-3.10.17-g' {
        root=hd1,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3 
        initrd /boot/initrd-3.10.17-g
}
Run Code Online (Sandbox Code Playgroud)

这是grub2配置的摘录,您会注意到唯一的区别是root=hd0,1root=hd1,1确定条目引用的引导分区。


现在带你穿过靴子,这样你就可以了解这里发生了什么。

  • BIOS 从引导卷中读取 MBR 并跳转到引导加载程序
  • 引导加载程序(例如grub2)被配置为知道哪个设备和分区包含您的内核。Grub2 直接访问该分区并将内核加载到内存中。
  • 然后您的引导加载程序会跳转到内核中,内核会引导您的机器。

引导加载程序不关心你有多少引导分区,它只关心它们在哪里,你必须告诉它这些信息。

内核并不关心您有多少个引导分区,因为它永远不需要看到它们(例如,您只需要让它可用于添加新内核)。


slm*_*slm 6

问题#1

我的理解是引导加载程序 GRUB2 挂载到 /boot。但是,当目录 /boot 位于单独的分区 sda2 上时,如何在 / 实际挂载之前发生这种情况?

我不认为你的理解是完全正确的。从GNU GRUB 维基百科页面

摘抄

当计算机打开时,计算机的BIOS 会找到配置的主可引导设备(通常是计算机的硬盘)并从主引导记录(MBR)加载并执行初始引导程序。MBR 是硬盘的第一个扇区,编号为 0(扇区计数从 0 开始)。长期以来,扇区的大小一直是 512 字节,但从 2009 年开始,出现了扇区大小为 4096 字节的硬盘,称为高级格式磁盘。截至 2013 年 10 月,此类硬盘仍可通过512e 仿真以 512 字节扇区访问。

GRUB 版本 2 中发生以下情况:

摘抄

启动计算机

打开电源时,会发生以下情况:

  • 硬件初始化,将 CPU 设置为实模式(无虚拟内存)并跳转到固定位置 0xFFFF0(在 CPU 电路中硬连线)
  • 因此,执行映射到该位置的 ROM 或闪存中存储的 BIOS 代码。
  • BIOS 代码查看 BIOS 配置数据以查看哪个是引导设备。BIOS 配置数据通常可以通过在打开电源后按一些特殊的按键序列进行编辑,从而使 BIOS 配置程序运行。除此之外,通常可以在此处选择引导设备。
  • BIOS 代码将引导设备的 MBR 加载到 RAM 中。请记住,一个 MBR 只有 512 个字节!加载的数据当然是 grub-install 在执行 grub-install 程序时动态创建和写入的程序和数据。
  • BIOS 代码跳转到加载的 MBR 的起始地址(即 Grub 代码自上电后第一次执行)。
  • Grub 的 MBR 代码加载一个扇区,其地址被硬连接到 MBR 块中。然后循环遍历该扇区中的 (address,len) 对,将所有数据从磁盘加载到内存中(即加载 file 的内容/boot/grub/core.img,或其“嵌入”副本)。MBR 代码然后跳转到加载的代码,即“执行”中的程序core.img
  • 如“安装 Grub”部分所述,这种嵌入原始磁盘块地址的技巧可以存储core.img在不在分区中的空间中,并且根本没有格式化为文件系统(“嵌入”)。而在这种情况下,如果core.img被修改,只要将新版本“嵌入”在同一位置,就不需要更新MBR代码。
  • 或者,它可能core.img位于真实的文件系统中,并且 Grub 可以在core.img没有该文件系统的驱动程序的情况下读取文件内容。但是在这种情况下,如果core.img被修改,那么文件的第一个块很可能会被赋予一个新的磁盘地址;如果发生这种情况,则必须更新 MBR 以指向这个新位置。然而,正如core.img通常通过运行 grub-install 更新的那样,这通常不是问题。
  • 请注意,理论上,如果core.img与 MBR 位于不同的设备上,并且添加了新硬件,则 Grub 生成的 MBR 记录可能无法正确加载core.img文件;将在其上找到第一个扇区的设备 IDcore.img硬连接到 MBR,而不是搜索。但是,对此没有解决方案;无法将 Grub“搜索”命令的等效项嵌入到 512 字节的 MBR 中。不过,这个问题不太可能;通常core.img与 MBR 嵌入在同一设备上。一旦core.img被加载,它就可以使用 search.mod 来查找所有其他/boot/grub文件,因此不受硬件重新排列的影响。
  • 执行的core.img代码现在初始化所有内置的模块(链接到core.img);这些模块之一将是能够读取目录/boot/grub所在文件系统的文件系统驱动程序。
  • 它还注册了一组内置命令:set、unset、ls、insmod。
  • 如果“配置文件”已链接到core.img,则将其传递给一个非常简单的内置脚本解析器进行处理。配置文件中的脚本命令只能调用内置或链接命令。简单场景(例如从本地驱动器启动典型的台式计算机)不需要配置文件;此工具用于诸如通过 pxe、远程 nfs 或何时/boot/grub在 LVM 设备上引导之类的事情。
  • Core.img现在“/boot/grub/normal.mod”从磁盘动态加载文件,并跳转到其入口函数。请注意,此步骤需要设置(即内置)适当的文件系统驱动程序。

     ss 启动过程

注意:当您看到典型的 GRUB2 菜单时,您可以在其中选择要引导的操作系统/内核,此时您正在引用系统/boot/grub目录。

                                         ss of grub tui

参考