0

我知道它们是两个不同的东西,但是实际的 Linux 内核和 rootFS 文件系统之间有什么区别,尤其是在内存中的位置和更新方面?

关于分区,为什么内核和 rootFS 几乎总是在不同的分区上?内核代码不会存储在 rootFS 本身中吗?那么它们在内存中的不同分区上如何呢?

现在关于更新,我一直在研究一个声称可以进行完整内核映像更新的 OTA 更新框架。它为 rootFS 使用两个单独的分区。如果更新一个 rootFS 分区出现问题,它可以退回到正常工作的 rootFS 分区,这是有意义的。但是,这实际上是如何更新内核的呢?我不明白。

4

1 回答 1

3

我知道它们是两个不同的东西,但是实际的 Linux 内核和 rootFS 文件系统之间有什么区别,尤其是在内存中的位置和更新方面?

内核通常是一个图像文件(如zImage)。在 ARM 系统中,内核也需要设备树文件,但我们暂时避免使用它。反过来,RootFS 是一个文件系统,其中包含您的所有文件/,如二进制文件 ( init, bash)、配置文件 ( /etc)、用户主目录等。有时 RootFs 包含内核映像文件,有时不包含,取决于您的特定系统。

关于分区,为什么内核和 rootFS 几乎总是在不同的分区上?内核代码不会存储在 rootFS 本身中吗?那么它们在内存中的不同分区上如何呢?

您问题的关键是考虑引导加载程序(如 U-Boot 或 GRUB)。一旦您了解了引导加载程序中操作系统引导过程的工作原理,答案就会自动显现。正如您所提到的,存在不同的分区方案,这导致启动过程中的差异。实际上,有很多不同的引导方案。让我们回顾一下其中的一些,希望它能解释您想知道的内容。

  1. 不同分区上的内核和 rootfs。在这种情况下,引导加载程序通常将内核映像读取到 RAM,通过内核 cmdline(通过root=参数)传递 rootfs 分区。然后 bootloader 开始执行内核,内核正在从root=参数指定的分区挂载 rootfs。
  2. 内核映像位于 rootfs 内。在这种情况下,引导加载程序应该知道内核映像的确切位置(例如在 中/boot/zImage)。Bootloader 知道 rootfs FS 格式(例如 ext4),/boot/zImage从 rootfs 读取到 RAM。然后像上一项一样继续执行。
  3. 内核映像和 rootfs 通过网络(例如 TFTP)传递。在这种情况下,有时,rootfs 被放入 RAM 并作为 ramdisk(从 RAM)安装。在这种情况下不使用持久存储,并且对 rootfs 的任何更改都将在重新启动后丢失。另一个网络案例是通过 NFS 挂载 rootfs 时,将使用服务器上的持久存储(用户可以透明地查看)。

现在关于更新,我一直在研究一个声称可以进行完整内核映像更新的 OTA 更新框架。它为 rootFS 使用两个单独的分区。如果更新一个 rootFS 分区出现问题,它可以退回到正常工作的 rootFS 分区,这是有意义的。但是,这实际上是如何更新内核的呢?我不明白。

在更新方面,使用哪种方案(1)或(2)没有什么不同。你所说的被称为(至少在 Android 中)A/B 无缝更新,这意味着两个分区(A 和 B)用于存储相同的图像(例如旧的 rootfs 和新的 rootfs)。您需要了解只更新没有内核的 rootfs 是可以的。内核开发中有一条规则是这样的:“我们不会破坏用户空间”。这意味着您可以依靠不同版本的内核来运行相同的用户空间,或者您可以依靠一个内核版本来运行不同的用户空间。

所以它更像是架构问题:你想更新系统中的内核吗?如果是,那么您需要为内核提供两个不同的分区,为 rootfs 提供两个分区。或者,您可以将内核映像和 rootfs 放在同一个分区中(例如,参见Android 启动映像格式),并提供第二个分区进行更新。

于 2019-01-06T12:47:46.783 回答