1

根据维基百科关于 initrd 的文章“许多 Linux 发行版都提供一个单一的通用内核映像——发行版的开发人员打算在尽可能广泛的硬件上启动。这个通用内核映像的设备驱动程序作为可加载模块包含在内,因为将许多驱动程序静态编译到一个内核中会导致内核映像变得更大,可能太大而无法在内存有限的计算机上启动。这就引发了检测和加载在引导时挂载根文件系统所需的模块的问题,或者就此而言,推断出根文件系统的位置或内容。为了避免将这么多特殊情况的处理硬编码到内核中,使用了带有临时根文件系统(现在称为早期用户空间)的初始引导阶段。"

我的问题是,如果我们在 initrd 中而不是在实际的内核映像中添加加载实际文件系统所需的模块等来保存保存,那么在内核和 initrd 组合形成单个 bootpimage 的 Bootpimage 的情况下我们将实现什么。即使使用 initrd,内核的大小也会增加。

有人可以澄清吗?

4

2 回答 2

2

定义“内核的大小”。

是的,如果你有一个最小的内核映像加上一个包含数百个模块的 initrd,它可能会比编译所有内容的等效内核占用更多的总存储空间,以及所有模块头等。然而,一旦它启动,确定它在什么硬件上,加载一些模块并将其余的都扔掉(initrd 中的init),它将占用相当少的内存。另一方面,全内置内核映像一旦启动,在内存中仍然和磁盘一样大,所有不需要的驱动程序代码都在浪费空间。

存储几乎总是比 RAM 便宜得多且更丰富,因此以减少系统运行时的可用内存为代价优化存储空间通常有点愚蠢。即使对于网络启动,为了加快启动速度而牺牲总映像大小的运行时能力也是没有意义的。这种考虑可能有任何优点的少数几种系统几乎肯定不会首先使用通用多平台内核。

于 2014-11-14T20:45:28.703 回答
1

大小有几个方面,这可能令人困惑。

  • 磁盘/网络上的二进制大小

  • 启动时间大小

  • 运行时间大小

    tl-博士;使用带有模块的initrd可为通用映像提供当前 (3.17) Linux 内核代码的最小运行时内存占用。

我的问题是,如果我们在 initrd 中而不是在实际的内核映像中添加加载实际文件系统所需的模块等来保存保存,那么在内核和 initrd 组合形成单个 bootpimage 的 Bootpimage 的情况下我们将实现什么。即使使用 initrd,内核的大小也会增加。

您是正确的,无论您选择哪种机制,都将传输相同数量的数据。事实上,带有模块加载的initrd会比完全静态链接的内核更大,并且启动时间会更慢。听起来很糟糕。

专门为设备构建且不包含额外硬件驱动程序或模块支持的定制内核始终是最好的。Debian 内核编译手册给出了用户可能想要制作自定义内核的两个原因。

  1. 通过功能最小化来限制安全问题的风险。
  2. 优化内存消耗

第二个选项通常是最关键的参数。最小化正在运行的内核消耗的内存量。initrd(或initramfs)是作为 ram 磁盘加载的二进制磁盘映像。它是所有用户代码,具有探测设备和使用模块加载来为系统获取正确驱动程序的单一任务。完成这项工作后,它会挂载一个真正的引导设备或普通的文件系统。发生这种情况时,initrd映像将被丢弃。

initrd不消耗运行时内存。您将获得一个通用图像和一个运行时间占用极少的图像。

我会说发行版人员所做的努力有时会产生性能问题。通常,ARM 驱动程序仅针对一个SOC 编译;虽然source支持一个SOC系列,但是通过条件只能选择一个。在最近的内核中,ARM 驱动程序始终支持整个 SOC 系列。内存开销是最小的。但是,将函数指针用于低级驱动程序传递函数会限制控制器的带宽。

cacheflush例程有一个multi -cache选项。函数指针导致编译器自动溢出。但是,如果您针对特定的缓存类型进行编译,则编译器可以内联函数。这通常会生成更好更小的代码。大多数驱动程序没有这种类型的基础设施。但是,如果您编译一个针对您的 CPU 进行调整的单片内核,您将获得更好的运行时行为。几个关键的内核函数将使用内联函数。

当编译到内核中时,驱动程序通常不会更快。许多系统支持通过 USB、PCMCIA、SDIO 等进行热插拔。这些系统在模块加载方面也具有内存优势。

于 2014-11-15T20:20:05.033 回答