ARM 上 initramfs 的大小限制?

Size constraints of initramfs on ARM?

我正在 PicoZed 板(ARM CortexA9 内核)上创建一个可引导的 Linux 系统,并且我已经 运行 进入 "limitation",我不认为确实是一个限制(我觉得这是另一个伪装成限制的问题)。

我是用JTAG启动方式启动系统;在板子上通电后,我使用 xmd 调试器将 u-boot 放入系统的 RAM 中,然后我 运行 它。

接下来,我将内核 (uImage)、gzip 压缩后的 initramfs 映像和设备树放入内存中。最后我告诉 u-boot 使用 bootm 启动系统,并使用三个参数指出所有图像的内存位置。

所有这些都有效,我设法启动了 Linux + userland。但是,我需要增加 initramfs,这就是我 运行 遇到问题的地方。

工作图像恰好是 16MiB。我试图将其设置为 24MiB(每次我尝试启动时都从头开始完全重新生成),但就在内核加载并试图找到 init 内核报告文件系统故障并失败后。应该没有任何重叠,但以防万一我尝试稍微移动一下,但出现了同样的问题。

搜索了一些技巧后,我在论坛上看到有人说图片需要以16MiB对齐(我认为这不是真的,但我试过了 none less ,但它没有得到一个工作系统)。另一个 post 声称图像必须与其大小对齐(我再次认为这不是真的,但我也试过了,但没有改变)。还有一个 post 声称如果 initramfs 映像跨越 __init 结束边界就会发生这种情况,并且将 initramfs 映像牢牢地放在里面将允许在映像被内核解压缩后回收内存,并将其放置在 __init 部分之外会起作用,但在启动后该内存将永远丢失。我对 Linux 知之甚少,无法知道其中是否存在 true/accurate,而且我不知道“__init”在哪里 - 如果存在这样的东西- 结束边界是,但如果问题是我正在穿越它,我尝试将 initramfs 图像移动到我以前使用它的任何地方之外,但这并没有改变任何东西。

我也尝试了原始位置(适用于 16MiB 图像)并创建了 16MiB + 1K 大小的图像,但这也不起作用。 (显然,要检查它是否没有覆盖任何重叠图像)。

这最初让我认为有一个 16MiB 的 initramfs 大小限制潜伏在某处。但是在搜索它时,我觉得这没有意义——据我所知,u-boot 中的 bootm 命令应该为系统设置标签列表(包括 initramfs 的位置和大小),到目前为止,我还没有遇到任何关于 initramfs 标记列表的 16MiB 限制的说明。

我发现一个页面声称 initramfs 大小实际上限制为系统中物理 ram 大小的大约一半,而 PicoZed 板有 1G RAM,所以我们相差几个数量级从什么"should"是一个限制。

澄清一下:16MiB图片是原始图片的大小;压缩后不到 6MiB。但是,如果我填充它以便它没有被压缩得那么紧,它没有任何区别——问题似乎与压缩图像的大小无关,只与未压缩图像有关。

主要问题:

附带问题:

Size constraints of initramfs on ARM?

我没有遇到您所说的 16 MiB 大小限制。
有一次我认为也有大小限制,但事实证明那是引导期间的内存占用问题。一旦解决了这个问题,我就一直在使用 30MiB 的大型 initramfs(例如,使用 glibc、gtstreamer 和 qt5 库)。

Where is this apparent 16MiB initramfs size limit coming from?

没有一个。 ramfs 仅受可用 RAM 的限制。
"Default RAM disk size" 有一个定义,但这不会影响 initramfs 的大小。


您使用 U-Boot bootm 命令启动的方法值得怀疑,即您将 initramfs 的内存地址作为第二个参数传递。
U-Boot documentation 清楚地将第二个参数描述为 "the address of an initrd image"(强调已添加)。
没有提到 initramfs 作为参数。

Linux kernel documentation 指出 initramfs 存档可以是 "linked into the linux kernel image"。有一个内核 menuconfig 条目用于指定 initramfs cpio 文件的路径。 make 脚本会将此 cpio 文件附加到内核映像,以便只有一个映像文件用于引导。

或者(像 initrd)"a separate file" 可以在引导时传递给内核以填充 initramfs。
U-Boot 将此存档的位置(和长度)作为 ATAG 条目或设备树 blob 中的保留内存区域传递。
内核需要 initramfs 的 cpio 存档或 initrd 的 tar 存档。

你忘记提及(除了它的压缩)这个 "initramfs""separate file" 是什么样的存档实际上是.
因此,不清楚您是使用 initrd(tar 存档)还是 initramfs(cpio 存档)引导内核。

您反复将 initramfs 称为“image”文件而不是 cpio 存档,这表明您确实在使用 initrd。
initrd 肯定会有大小限制。


Is there such a thing as an "kernel __init section" which is reclaimed by the kernel after it has uncompressed/loaded images?

是的,有一段__init内存,内核初始化完成后释放

If so, how do I see/configure the location/size of it?

通常初始化后没有用的例程和数据可以用__init宏声明。参见 this
该内存部分的位置和大小将由链接描述文件控制,而不是由用户显式控制。内核 System.map 文件应该有供审查的信息。

我认为你需要在 uboot bootargs 命令中传递 ramdisk_size

ramdisk_size如果是ram-disk解压文件需要设置 尺寸大于默认设置。应该超过 ramdisk 解压缩文件大小。