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

32位i.MX6 Arm板Bootloader开发:设备树启动时如何传递initrd位置?

问题描述

我正在为32位i.MX6 Arm板编写Bootloader,希望使用设备树和内存中静态存储的initrd文件启动Linux内核。参考U-Boot可知,可使用bootm命令传递内核、设备树及ramdisk参数:

从内存启动应用镜像:
bootm [addr [arg ...]] - 启动存储在内存中的应用镜像并传递参数'arg...';启动Linux内核时,‘arg'可为initrd镜像的地址

我了解Bootloader向内核传递信息有两种方式:传统ATAGS方法和现代设备树方法。通过ATAGS可使用ATAG_INITRD2标签指定ramdisk的内存地址,但使用扁平设备树时不会向内核传递ATAGS(启动日志会显示"No ATAGs?"),且未找到设备树方式下指定ramdisk的方法。

查阅Arm平台Linux内核启动文档,文档指定了以下接口:

  • CPU寄存器设置
    r0 = 0,
    r1 = 上述(3)中获取的机器类型编号。
    r2 = 系统RAM中标记列表的物理地址,或系统RAM中设备树块(dtb)的物理地址

该文档提到启动前必须配置initramfs,但未说明设备树启动时的配置方法。请问是否存在替代方案?U-Boot是否会自动将相关信息追加到设备树中,或存在其他告知内核initrd位置的方式?

解决方案

1. U-Boot会自动修改DTB传递initrd信息

当使用U-Boot的bootm(或针对压缩内核的bootz)命令,按bootm <内核地址> <initrd地址> <DTB地址>的格式传递参数时,U-Boot会自动完成以下操作:

  • 解析initrd镜像的大小(U-Boot支持识别标准cpio格式的initrd镜像)
  • 在DTB的chosen节点中添加linux,initrd-start和linux,initrd-end两个属性,分别填入initrd的物理起始地址和结束地址(起始地址+镜像大小)
  • 内核启动时会自动读取这两个属性,找到内存中的initrd并加载

比如执行U-Boot命令:

bootm 0x10800000 0x11000000 0x12000000

U-Boot会自动更新DTB的chosen节点,最终DTB中会出现类似内容:

chosen {
    linux,initrd-start = <0x11000000>;
    linux,initrd-end = <0x11800000>;
};

2. 自定义Bootloader时的手动配置方法

如果是自己编写Bootloader而非使用U-Boot,需要手动修改内存中的DTB:

  1. 找到DTB中的chosen节点(如果没有则创建该节点)
  2. 添加linux,initrd-start和linux,initrd-end属性,值为initrd在内存中的物理起始和结束地址
  3. 确保修改后的DTB结构合法(若有校验和等字段,需同步更新)

示例DTB片段:

chosen {
    bootargs = "console=ttymxc0,115200 root=/dev/ram rw";
    linux,initrd-start = <0x11000000>;
    linux,initrd-end = <0x11800000>;
};

3. 补充:内核启动参数方式(适合存储设备中的initrd)

如果initrd存储在Flash等存储设备上,也可以通过chosen节点的bootargs传递initrd=参数,但对于内存中静态存储的initrd,使用上述地址属性的方式更直接高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:41:12