You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从RAM启动时Yocto根文件系统空间分配及扩容问题

解决Yocto initramfs空间不足及启动Kernel Panic问题

问题背景

基于i.MX8MPlus平台开发从RAM运行的嵌入式Yocto测试构建,通过Yocto生成包含initramfs的fitimage启动。随着initramfs功能增加,体积持续增大,此前调整INITRAMFS_MAXSIZE、IMAGE_OVERHEAD_FACTOR等Yocto变量可解决空间问题,但当前这些变量已失效。设备拥有2GB物理内存,启动后initramfs占满557MB,却仍有1GB以上空闲tmpfs空间。添加新包后编译不触发INITRAMFS_MAXSIZE报错,但启动时出现Kernel Panic,报错信息如下:

[   10.918626] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[   10.926889] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 5.15.52 #1
[   10.934110] Hardware name: i.MX8MPlus
[   10.940026] Call trace:
[   10.942470]  dump_backtrace+0x0/0x1a0
[   10.946138]  show_stack+0x18/0x70
[   10.949452]  dump_stack_lvl+0x68/0x84
[   10.953116]  dump_stack+0x18/0x34
[   10.956431]  panic+0x160/0x30c
[   10.959485]  mount_block_root+0x180/0x234
[   10.963496]  mount_root+0x178/0x198
[   10.966984]  prepare_namespace+0x130/0x170
[   10.971081]  kernel_init_freeable+0x24c/0x290
[   10.975437]  kernel_init+0x28/0x12c
[   10.978927]  ret_from_fork+0x10/0x20
[   10.982503] SMP: stopping secondary CPUs
[   10.986709] Kernel Offset: 0x80000 from 0xffff800008000000
[   10.992192] PHYS_OFFSET: 0x40000000
[   10.995677] CPU features: 0x00002401,20000842
[   11.000031] Memory Limit: none
[   11.003086] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) ]--- 

已尝试方法:

  • 增大INITRAMFS_MAXSIZE、IMAGE_OVERHEAD_FACTOR;
  • 使用IMAGE_ROOTFS_SIZE和IMAGE_ROOTFS_EXTRA_SPACE扩容;
  • 排查U-Boot和内核配置的空间限制但无结果。

需求:重新分配未使用的tmpfs空间给initramfs。


问题分析

该Kernel Panic并非单纯的tmpfs空间分配问题,而是initramfs加载/解压时超出了内核或U-Boot预留的内存区域,导致内核无法完整识别initramfs文件系统。Yocto的INITRAMFS_MAXSIZE仅限制编译时生成的initramfs大小,但如果内核/U-Boot在启动阶段限制了initramfs的可用内存,就会出现编译通过但启动失败的情况。


具体解决步骤

1. 调整内核initramfs相关配置

  • 打开内核配置界面:
    bitbake -c menuconfig virtual/kernel
    
  • 确认以下配置:
    • 开启CONFIG_BLK_DEV_INITRD=y,并将CONFIG_INITRAMFS_MAX_SIZE设为足够大的值(设为0表示无限制,或直接配置为1610612736即1.5GB);
    • 确保CONFIG_PHYS_ADDR_T_64BIT=y,保证内核能识别全部2GB物理内存;
    • 检查CONFIG_INITRAMFS_ROOT_UID/CONFIG_INITRAMFS_ROOT_GID配置,确保权限设置正确,不影响文件系统挂载。

2. 修正U-Boot启动参数的initramfs内存分配

  • 在U-Boot命令行执行printenv bootargs,查看是否包含initrd参数,格式通常为initrd=0x<起始地址>,<大小>;
  • 若initrd的大小参数过小,将其调整为更大的值(比如0x60000000即1.5GB),确保能容纳解压后的initramfs;
  • 若使用fitimage启动,执行iminfo <fitimage地址>查看fitimage中各段大小,确保initramfs段大小与实际生成的文件匹配,避免U-Boot传递错误的大小参数。

3. 调整设备树的内存预留配置

  • 打开i.MX8MPlus的设备树文件,找到reserved-memory节点:
    • 检查CMA、GPU等其他预留内存区域是否占用过多空间,适当缩小这些区域的大小,为initramfs腾出内存;
    • 若存在专门给initramfs预留的内存节点,调整其size属性为更大的值(比如0x60000000)。

4. 验证Yocto变量的实际生效情况

  • 执行以下命令查看INITRAMFS_MAXSIZE的实际生效值,确认未被其他层配置覆盖:
    bitbake -e <你的镜像名> | grep INITRAMFS_MAXSIZE
    
  • 在local.conf中强制配置initramfs大小:
    INITRAMFS_MAXSIZE = "1610612736"  # 1.5GB
    IMAGE_OVERHEAD_FACTOR = "1.3"
    
  • 若使用高压缩算法(如lzma)导致解压后体积骤增,可暂时将INITRAMFS_COMPRESSION改为gzip,降低解压后的内存占用。

5. 验证initramfs的实际大小

  • 找到生成的initramfs文件(通常在tmp/deploy/images/<平台>/目录下),用以下命令查看压缩前的实际大小:
    zcat initramfs.cpio.gz | cpio -t | wc -c
    
  • 确保该大小不超过你在U-Boot和内核中配置的预留内存。

验证方法

调整完成后,重新编译内核、U-Boot和fitimage,启动设备后:

  • 执行df -h查看根文件系统(initramfs)的大小;
  • 执行free -h查看内存使用情况,确认initramfs占用空间正常,剩余tmpfs内存充足。

内容的提问来源于stack exchange,提问作者Bryce C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:14:55