万象奥科 RK3506卡片电脑 U-Boot 无法加载 DTB 问题解决方案

问题背景

在 RK3506 平台开发中,U-Boot 启动时出现以下错误:

Failed to load DTB, ret=-19
No valid DTB, ret=-22
Failed to get kernel dtb, ret=-22...
.
.
.
Net:   No ethernet found.

导致系统无法正常启动,最终表现为uboot"无法联网"。

根本原因分析

1. boot.img 格式差异

RK3506 SDK 支持两种 boot.img 格式:

格式 ITS 文件 特点
FIT Image zboot.its / thunderboot.its 使用 U-Boot FIT (Flattened Image Tree) 格式,内嵌 resource.img
Android Bootimg mkbootimg 生成 传统 Android bootimg 格式

2. U-Boot 加载机制

U-Boot 的 resource_setup_blk_list() 函数期望从 boot.img 中加载 DTB:

boot.img 结构:
├── Android Header (0x1000 bytes)
├── Kernel Image (aligned)
├── Ramdisk (aligned)
└── Second/Resource Data (aligned)
                    ↑
              包含 DTB 或 Resource Image

关键问题

  • thunderboot.its 缺少 resource 节点配置
  • zboot.its 包含 resource 节点配置

3. ITS 文件对比

thunderboot.its(问题配置)
/dts-v1/;
/ {
    description = "U-Boot FIT source file for arm";

    images {
        fdt {
            data = /incbin/("@KERNEL_DTB@");
            type = "flat_dt";
            ...
        };

        kernel {
            data = /incbin/("@KERNEL_IMG@");
            type = "kernel";
            ...
        };
        // ❌ 缺少 resource 部分
    };

    configurations {
        default = "conf";

        conf {
            fdt = "fdt";
            kernel = "kernel";
            // ❌ 缺少 multi = "resource"
        };
    };
};
zboot.its(正确配置)
/dts-v1/;
/ {
    description = "U-Boot FIT source file for arm";

    images {
        fdt {
            data = /incbin/("@KERNEL_DTB@");
            type = "flat_dt";
            ...
        };

        kernel {
            data = /incbin/("@KERNEL_IMG@");
            type = "kernel";
            ...
        };

        // ✅ 包含 resource 部分
        resource {
            data = /incbin/("@RESOURCE_IMG@");
            type = "multi";
            arch = "arm";
            compression = "none";

            hash {
                algo = "sha256";
            };
        };
    };

    configurations {
        default = "conf";

        conf {
            fdt = "fdt";
            kernel = "kernel";
            multi = "resource";  // ✅ 引用 resource
        };
    };
};

解决方案

方案一:修改配置文件使用 zboot.its(推荐)

修改文件:

rk3506_linux6.1_sdk/device/rockchip/rk3506/rockchip_rk3506_g_mini_defconfig

修改内容:

# 修改前
RK_BOOT_FIT_ITS_NAME="thunderboot.its"

# 修改后
RK_BOOT_FIT_ITS_NAME="zboot.its"

操作步骤:

# 1. 编辑配置文件
vim rk3506_linux6.1_sdk/device/rockchip/rk3506/rockchip_rk3506_g_mini_defconfig

# 2. 重新构建 kernel
cd rk3506_linux6.1_sdk
./build.sh kernel

# 3. 烧录 boot.img
cd rockdev
sudo upgrade_tool di -p parameter.txt
sudo upgrade_tool di -s MiniLoaderAll.bin
sudo upgrade_tool di -b boot.img
sudo upgrade_tool di -rootfs rootfs.img
sudo upgrade_tool di -oem oem.img
sudo upgrade_tool di -userdata userdata.img
sudo upgrade_tool RD

优点:

  • 改动最小,只需修改一行配置
  • 使用 SDK 已有的正确配置

缺点:

  • 需要重新编译并烧录整个 boot.img
  • 烧录时间较长

方案二:修改分区表添加 resource 分区

修改文件:

rk3506_linux6.1_sdk/device/rockchip/rk3506/parameter-128M.txt

分区表对比:

# 修改前(无 resource 分区)
CMDLINE:mtdparts=:0x00002000@0x00002000(uboot),0x00000800@0x00004000(misc),\
0x00000200@0x00004800(vnvm),0x00007000@0x00004a00(recovery),\
0x00005000@0x0000ba00(boot),0x00020000@0x00010a00(rootfs),\
0x00008000@0x00030a00(oem),-@0x00038a00(userdata:grow)

# 修改后(添加 resource 分区)
CMDLINE:mtdparts=:0x00002000@0x00002000(uboot),0x00000800@0x00004000(misc),\
0x00000200@0x00004800(vnvm),0x00007000@0x00004a00(recovery),\
0x00001000@0x0000ba00(resource),0x00004000@0x0000ca00(boot),\
0x00020000@0x00010a00(rootfs),0x00008000@0x00030a00(oem),\
-@0x00038a00(userdata:grow)

分区变更说明:

分区 偏移 大小(扇区) 用途
boot 0x0000ba00 0x00005000 kernel + ramdisk
resource 0x0000ba00 0x00001000 新增:DTB
boot 0x0000ca00 0x00004000 kernel

操作步骤:

# 1. 修改 parameter-128M.txt
vim rk3506_linux6.1_sdk/device/rockchip/rk3506/parameter-128M.txt

# 2. 烧录分区表和所有镜像
cd rockdev
sudo upgrade_tool di -p parameter.txt
sudo upgrade_tool di -s MiniLoaderAll.bin
sudo upgrade_tool di -u uboot.img
sudo upgrade_tool di -resource resource.img   # ✅ 烧录 resource.img
sudo upgrade_tool di -b boot.img
sudo upgrade_tool di -rootfs rootfs.img
sudo upgrade_tool di -oem oem.img
sudo upgrade_tool di -userdata userdata.img
sudo upgrade_tool RD

优点:

  • U-Boot 可直接从独立的 resource 分区加载 DTB
  • 分区结构更清晰

缺点:

  • 需要修改分区表,可能影响现有分区
  • 需要额外烧录 resource.img

验证方法

烧录完成后,查看串口输出,确认以下信息:

DM: v2
SPI Nand ID b 12 0
Bootdev(atags): mtd 1
GUID Partition Table Header signature is wrong: 0xFFFFFFFFFFFFFFFF != 0x5452415020494645
Repair the backup gpt table OK!
PartType: EFI
boot mode: normal
RESC: 'boot', blk@0x0000d85f
resource: sha256+
FIT: no signed, no conf required
DTB: rk-kernel.dtb          ← ✅ DTB 找到
HASH(c): OK                 ← ✅ 校验通过
vdd_arm init 1011000 uV
Could not find baseparameter partition
Model: Rockchip RK3506 EVB1 V10 Board  ← ✅ 开发板识别成功

如果看到 DTB: rk-kernel.dtbHASH(c): OK,说明问题已解决。

方案对比

特性 方案一(zboot.its) 方案二(resource 分区)
修改复杂度
编译时间 需要重新编译 kernel 不需要
烧录时间 需要烧录 boot.img 需要额外烧录 resource.img
分区影响 需要修改分区表
推荐度 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐

推荐方案

推荐使用方案一,即修改配置文件使用 zboot.its

原因:

  1. 改动最小,只需修改一行配置
  2. 使用 SDK 已验证的配置
  3. 不需要修改分区表,避免潜在风险

相关文件路径

# 配置文件
rk3506_linux6.1_sdk/device/rockchip/rk3506/rockchip_rk3506_g_mini_defconfig
rk3506_linux6.1_sdk/device/rockchip/rk3506/parameter-128M.txt

# ITS 模板文件
rk3506_linux6.1_sdk/device/rockchip/.chips/rk3506/zboot.its
rk3506_linux6.1_sdk/device/rockchip/.chips/rk3506/thunderboot.its

# 烧录工具
rk3506_linux6.1_sdk/tools/linux/Linux_Upgrade_Tool/Linux_Upgrade_Tool/upgrade_tool

参考资料


作者:HX
日期:2025-01-31
版本:v1.0

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐