在Bootpimage的情况下,initrd是否真的减少了内核映像的大小?

时间:2014-11-14 10:06:35

标签: linux linux-kernel arm initrd

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

我的问题是,如果我们添加在initrd中加载实际文件系统所需的模块等而不是在实际内核映像中以节省保存然后我们将在Bootpimage中实现的内容,其中内核和initrd被组合以形成单个bootpimage。即使使用initrd,这个内核的大小也会增加。

有人可以澄清吗?

2 个答案:

答案 0 :(得分:2)

定义"内核的大小"。

是的,如果你有一个最小的内核映像加上一个装满了数百个模块的initrd,它可能会比编译所有内容的等效内核占用更多存储空间,所有的内容都是模块标题等。但是,一旦它启动,确定它所使用的硬件,加载了几个模块并抛弃所有剩余的(initrd中的 init ) ,它将占用更少的记忆。另一方面,全内置内核映像一旦启动,内存仍然与磁盘一样大,浪费了所有不需要的驱动程序代码的空间。

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

答案 1 :(得分:1)

尺寸有几个方面,这可能令人困惑。

  • 磁盘/网络上的二进制大小
  • 启动时间大小
  • 运行时间

    TL-DR;使用initrd模块为通用映像提供了当前(3.17)Linux内核代码的最小运行时内存占用。

  

我的问题是,如果我们添加在initrd中加载实际文件系统所需的模块等而不是在实际内核映像中以节省保存然后我们将在Bootpimage中实现的内容,其中内核和initrd被组合以形成单个bootpimage。即使使用initrd,这个内核的大小也会增加。

你是对的,无论你选择哪种机制,都会传输相同数量的数据。实际上,带有模块加载的 initrd 将比完全静态链接的内核大,启动时间会更慢。听起来不错。

专门为设备构建的定制内核并不包含额外的硬件驱动程序或模块支持始终是最好的。 Debian handbook on kernel compilation给出了两个使用可能想要创建自定义内核的原因。

  1. 通过功能最小化来限制安全问题的风险
  2. 优化内存消耗
  3. 第二个选项通常是最关键的参数。最小化正在运行的内核消耗的内存量。 initrd (或 initramfs )是一个二进制磁盘映像,作为ram磁盘加载。所有用户代码都具有探测设备和使用模块加载来获取系统正确驱动程序的单一任务。完成此任务后,它将安装真实启动设备或正常的 root 文件系统。发生这种情况时, initrd 图像将被丢弃。

    initrd 不会占用运行时内存。您既可以获得通用图像,也可以获得相当少的运行时足迹。

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

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

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

相关问题