Initramfs Ubuntu

2025年03月17日 | 阅读 9 分钟

Initramfs 是为 Linux 2.6 系列内核指定的解决方案。其理念是,内核中实现的一些安装魔法,在用户空间中也可以同样方便地实现。乍一看,它与经典的 initrd 略有不同。

下面提到了 initramfs 的几个关键点

  • CPIO 归档,因此内核中根本不需要文件系统。简单地说,归档文件被解压到 ramdisk 中。
  • 解压在运行 do_basic_setup 之前进行。这意味着固件文件在内核驱动程序加载之前就已存在。
  • 通常调用 userspace init 而不是调用 prepare_namespace。所有根设备查找和 md 的设置都在 userspace 中实现。
  • initramfs 可以通过将其包含在 .init.ramfs 段名下的 EMF 归档 中,直接创建到内核中。
  • 一个 initramfs 可以被变形。通过经典的 initrd 机制向内核提供 initramfs 会导致它与内核中创建的 initramfs 一起解压。
  • 所有根设备魔法命名都消失了。将 udev 开发到 initramfs 中指定,在启动序列期间可以使用完全相似的 /dev 树外观。它应该解决在安装可以完成但 initrd 无法启动时发现的 SATA 故障 的大部分问题。

Initramfs 的详细信息

Initramfs 用作我们系统可访问的初始 根文件系统。它用于挂载包含所有数据的实际 rootfsinitramfs 包含挂载 rootfs 所需的几个模块。但是我们总是可以编译内核以包含这些模块。是否需要 initramfs?答案是“取决于我们的系统”。

一些系统配置需要用户空间实用程序来促使内核正确配置设备。例如,cryptdevices:它们需要通过用户获取密码。密码请求实用程序是用户空间实用程序,但在用户空间实用程序存在之前,rootfs 无法启动。initramfs 充当中间人,提供一个临时 rootfs,其中包含挂载实际 rootfs 所需的用户空间实用程序。

这些用户空间实用程序从何而来?

挂载实际 rootfs 所需的这些用户空间实用程序来自我们的 rootfs。当我们使用命令(即 "mkinitramfs""update-initramfs")构建 initramfs 时。这些命令会将这些实用程序从它们所在的位置复制到一个临时目录。

例如,cryptsetup(二进制文件) 来自 cryptsetup(包)。此二进制文件包含在 /sbin/ 目录中。因此,如果我们安装该包,将会发生以下情况

  • 在我们的 /usr/share/initramfs/hooks/ 中添加任何文件 - 例如,cryptroot。这些文件在我们输入 update-initramfs 时运行。当我们查看这个 "cryptroot" 脚本时,我们会看到这个钩子会将 cryptsetup/sbin/cryptsetup 目录复制到 initramfs/sbin/cryptsetup 目录。
  • 此外,它会自动调用 update-initramfs

因此,所有可能配置我们根设备的包都有一个“钩子”脚本,当我们运行 mkinitramfsupdate-initramfs 时会运行该脚本,以便将用户空间的基本实用程序包含在我们的 rootfs 中。通常,如果我们安装了一个能够配置我们根设备的包,就会调用 "update-initramfs"

例如,如果我们安装 "cryptsetup" 包,无论我们的根设备是否已加密,包安装都会调用 update-initramfs,这将执行已安装的脚本(即 "hook")(如果该包已经安装)。

当我们的根设备依赖于一个模块(未在内核中编译)时,例如在 initramfs 中的 module_must_be,以便在启动时识别我们的根设备。通常,当我们安装内核包时,模块会安装在 /lib/modules/<kernel-version>/ 目录中。

但是,当我们手动编译任何内核时,需要调用 make modules_install(这会将编译后的模块安装到 /lib/modules/<kernel-version>/ 目录中)并随后执行 "depmod"(这会在 /lib/modules/<kernel-version>/ 目录中生成一个 modules.dep 和一个映射文件)。

在此步骤之后,我们需要通过调用 "mkinitramfs""update-initramfs" 来更新我们的 initramfs(如果是新内核,则制作一个新的)。如果我们忘记这些步骤,我们的根设备在启动时将无法识别。

注意:如果我们单独编译一个模块(而不是安装 Ubuntu 内核包),则使用这种类似的命令方案。

现在,initramfs 的运行方式如下。获取控制的初始进程是一个进程,即 init。按照程序,init 进程 可以调用保存在 initrd 中的许多其他脚本。这些脚本驻留在我们的 initramfs 中的 dir 脚本中。dir 脚本进一步分为以下目录

  • init-top
  • init-premount
  • boot-top(我们的加密脚本在此处运行,例如,用于询问用户密码)
  • boot-premount
  • boot
  • boot-bottom
  • init-bottom

在这里,boot 被 remote 或 local 替换,这取决于我们的 rootfs 是远程还是本地。该脚本会将我们的 rootfs 挂载到 initramfs/root/ 目录中。如果一切顺利,init-bottom 脚本会按顺序运行,然后是 boot-bottom。然后,init 重新获得控制权并执行以下操作

  • init/sys 目录从 initramfs 移动到 /initramfs/root/sys(在我们的实际 rootfs 中)。
  • 它将 /proc 目录移动到 /initramfs/root/proc 目录。
  • 它调用 run-init 来执行实际的 init,该 init 驻留在我们实际的 rootfs 中的 /root 目录中。run-init 执行一些操作,即 chroot 到实际的 rootfs,然后运行驻留在 /bin/sbin/ 目录中的 init,或者用户声明为启动参数的任何内容。

如果在挂载 rootfs 时出现问题,则会尝试恢复任务,如果恢复任务也失败,则会向用户显示控制台以进行干预(手动)。

几个包决定了它们的脚本必须放在哪里。但所有对于挂载我们的 rootfs 至关重要的脚本都必须驻留在 {init-top, init-premount, boot-top, boot-premount}

这些包通常有多个脚本需要在启动时运行。这些多个脚本通常有一个需要遵循的执行顺序。

例如,假设 P 包包含两个 S1 和 S2 脚本,用于在启动时进行系统配置。S1 需要在 S2 之后和 root 挂载之前运行——当 S1 和 S2 有助于配置根设备时。因此,如果 S1 不依赖于任何其他东西,则 S1 可以保存在 init-top 中,如果 S2 除了 S1 脚本之外不依赖于任何其他东西,则 S2 可以保存在 init-premount 中。

除了这个通用经验法则之外,我们不能将脚本保存在其他任何地方。

这意味着来自不同包的多个脚本在类似目录(例如 init-premount)中的运行顺序可能彼此无关。因此,它们可以并行运行。这就是我们决定在基于事件的 initramfs 中利用的方式。

重要: 类似目录中的脚本也可能相互关联。

顺序由该目录中的一个名为 "order" 的文件决定。不同目录中的脚本在执行顺序上可能不相关,它们也可以并行运行。我们需要识别这些脚本。

initramfs 的唯一目的是挂载根文件系统。它是我们通常在根文件系统上会看到的所有目录的完整集合。它被捆绑到一个 cpio 归档中,并使用多种压缩算法之一进行压缩。

引导加载程序可以将内核和 initramfs 镜像加载到内存中,并在启动时启动内核。内核将检查 initramfs 的存在,如果看到,则将其挂载为 / 并执行 /init。通常,init 程序是一个 shell 脚本。

重要: 当使用 initramfs 时,启动过程需要更长时间,可能明显更长。

内核模块是几乎所有发行版中包含 initramfs 的最大原因。在正常发行版中,有几个未知数,如磁盘布局和文件系统类型。从某种意义上说,它与 LFS 相反,在 LFS 中,系统布局和功能是已知的,并且内核是正常构建的。在这种情况下,initramfs 很少需要。

在 LFS 环境中包含 initramfs 只有四个主要原因:从 LVM 逻辑卷加载 rootfs、通过网络加载它、包含需要密码的加密 rootfs,或者为了方便地将 rootfs 描述为 UUIDLABEL。其他任何情况都意味着内核配置不正确。

在 Ubuntu 20.04 中安装 busybox-initramfs

在本文中,我们将学习如何在 Ubuntu 20.04 版本中安装 busybox-initramfs。busybox-initramfs 是用于 initramfs 独立 shell 设置的独立 shell 设置。

busybox-initramfs 简介

Busybox 将多个常用 UNIX 实用程序的微小版本关联到一个小型可执行文件中。它为我们通常在桌面系统上看到的(即 tar、mount、mv、cp、ls 等)最基本实用程序提供极简主义的替代品。

Busybox 中,这些实用程序通常比其功能齐全的 GNU 同类产品具有更少的选项。但是,添加的选项提供了良好的功能,并且与它们的 GNU 对应项非常相似。Busybox-initramfs 提供了一个常见的独立 shell,它只提供 initramfs 所需的常用实用程序。

使用 apt-get 安装 busybox-initramfs

我们需要使用 apt-get 更新 apt 数据库。我们可以使用以下命令


Initramfs Ubuntu

更新 apt 数据库后,我们现在可以通过执行以下命令使用 apt-get 安装 busybox-initramfs


Initramfs Ubuntu

使用 apt 安装 busybox-initramfs

我们需要使用 apt 更新 apt 数据库。我们可以使用以下命令

更新 apt 数据库后,我们现在可以通过执行以下命令使用 apt 安装 busybox-initramfs

如何使用 initramfs 启动 Ubuntu?

在使用计算机时,我们可能会遇到一些问题,其中之一是操作系统无法正常重启。有几种解决启动问题的方法,有些可以很快修复,有些则需要我们重新安装整个操作系统。

此外,Ubuntu 也可能会出现同样的问题,其中 "initramfs" 问题就是其中之一。这是一个 Ubuntu 的启动问题,由于内存中的坏扇区和坏块导致,它们不允许操作系统启动。

我们的系统包含几个基本文件,因此这样的问题可能会有点令人不安。但我们无需担心,因为本文主要集中于如何解决 "initramfs" 问题并正常启动 Ubuntu。那么,让我们开始吧

如何解决 Ubuntu 中的 "initramfs" 问题?

如果我们的屏幕显示 "initramfs" 错误,我们已经处于恢复模式,这意味着我们可以输入命令并执行不同的操作。我们可以输入 "exit" 以获取错误信息。

重要: 并非每次输入 "exit" 都能收到错误信息。

如上所述,当我们的启动盘受到感染时,会出现 Initramfs 错误。我们可能连接了多个磁盘,要查看它们,我们可以使用以下命令

分区可以通过 /dev/sdb、/dev/sda 或任何其他名称进行检查。为了修复 "initramfs" 问题,我们将使用一个实用程序,即 "fsck",它也被称为 "文件系统一致性检查"。它将检查文件系统的问题并修复它们。我们需要遵循下面提到的语法

例如,如果任何分区名为 /dev/sdb,则命令将如下所示

点击 "Enter" 按钮,该命令将自动清除内存中的所有坏扇区。在出现提示时点击 "y"。我们可以简单地将 "-y" 选项与命令一起使用以防止提示

如果我们有多个分区,我们可以使用上面提到的命令来检查它们。如果分区没有坏扇区,该命令将不打印任何内容。系统现在将花费一些时间来分析和修复我们内存中受感染的部分。完成后,我们需要输入以下命令

如果重启不起作用,我们可以输入 "exit"。好了,问题已解决,Ubuntu 将正常启动。


下一个主题iTunes Ubuntu