Skip to content

K3 COM260 Kit 刷机流程:FIT 单文件烧录 + 可编辑设备树

背景

StarryOS 在 SpacemiT K3 COM260 Kit 真机上运行,之前的启动流程非常繁琐:

  1. 必须手动设置 bootargs。设备树里固化的是原厂 Linux 参数(root=PARTUUID=...),与 StarryOS 的 GPT 分区名(rootfs)不匹配,导致启动 panic:configured root device was not found。每次开机都要在 U-Boot 里 setenv bootargs root=PARTLABEL=rootfs 才能启动。
  2. 内核与设备树分两次上传。fastboot 需要 U-Boot ↔ 宿主机来回配合两次(fastboot stage 内核 + fastboot stage 设备树),再 booti 指定两个加载地址。
  3. 设备树不可编辑spacemit-k3-com260-ifx.dtb 是编译后的二进制,想调整参数只能改回二进制或依赖反编译。

本次改造一次性解决这三个问题:设备树改为可编辑的 dts 源码、bootargs 固化进设备树、烧录流程合并为 FIT 单文件上传

相关文件

文件说明
os/StarryOS/configs/board/spacemit-k3-com260-ifx.dts设备树源码(可编辑)
os/StarryOS/configs/board/spacemit-k3-com260-ifx.dtb由 dts 编译的设备树二进制
os/StarryOS/configs/board/spacemitk3-com260kit.itsFIT 镜像描述文件(内核 + 设备树打包)
os/StarryOS/configs/board/spacemitk3-com260kit.tomlK3 板级构建配置(触发 axbuild 自动打包)

刷机流程

1. 构建内核(自动生成 FIT 镜像)

bash
cd tgoskits
cargo starry build --config os/StarryOS/configs/board/spacemitk3-com260kit.toml

由于 spacemitk3-com260kit.toml 同目录存在同名 .its 文件,axbuild 构建后会自动调用 mkimage 打包出 FIT 镜像:

target/riscv64gc-unknown-none-elf/release/starryos.uimg

镜像内含:

  • 内核:加载地址 0x140000000(12.6 MiB)
  • 设备树:加载地址 0x138000000(139 KiB)
  • 两者均带 sha256 校验

2. 上传并启动(U-Boot ↔ 宿主机各一次)

# U-Boot:一次会话,FIT 上传到 0x180000000(与内核/fdt 加载地址错开)
fastboot -l 0x180000000 -s 0x04000000 usb 0

# Host:一次上传
fastboot stage target/riscv64gc-unknown-none-elf/release/starryos.uimg

# U-Boot:启动(FIT 自动解包,把内核搬到 0x140000000、fdt 搬到 0x138000000)
bootm 0x180000000

bootargs 已固化在设备树里,无需手动 setenv

3. 验证

root@starry:#
ls /dev/k3_airunner

设备树如何编辑

spacemit-k3-com260-ifx.dts 是 dts 源码,直接编辑后用 dtc 编译:

bash
dtc -I dts -O dtb spacemit-k3-com260-ifx.dts -o spacemit-k3-com260-ifx.dtb

当前 chosen 节点的 bootargs:

dts
chosen {
    bootargs = "console=ttyS0,115200 earlycon=sbi root=PARTLABEL=rootfs rw";
    boot-hartid = <0x00>;
    stdout-path = "serial0:115200";
};
  • root=PARTLABEL=rootfs:按 GPT 分区名定位根文件系统(K3 UFS 分区表的分区 3 名为 rootfs
  • 需要调整(如改串口、加调试参数)直接改这一行再编译即可

注意:当前 dts 是反编译原厂 dtb 得到的,节点 phandle 是数字引用。日常维护只需编辑 chosen 等少量节点,改完编译回 dtb 时 phandle 保持一致,无需把整棵树重写为可读引用。

FIT 打包机制说明

axbuild(scripts/axbuild/src/starry/build.rs)的 uimage_generation_plan 约定:

board 配置 .toml 同目录存在同名 .its 文件 → 构建后自动生成 .uimg

spacemitk3-com260kit.its 的要点:

dts
images {
    kernel {
        data = /incbin/("${kernel_bin}");          // axbuild 渲染为绝对路径
        load = <0x1 0x40000000>;                   // 0x140000000
        entry = <0x1 0x40000000>;
        hash { algo = "sha256"; };
    };
    fdt {
        data = /incbin/("../../../os/StarryOS/configs/board/spacemit-k3-com260-ifx.dtb");
        load = <0x1 0x38000000>;                   // 0x138000000
        hash { algo = "sha256"; };
    };
};
  • ${kernel_bin} 由 axbuild 替换为内核 bin 的绝对路径
  • fdt 路径是相对渲染后 .its 所在目录target/riscv64gc-unknown-none-elf/release/)的,../../../ 上溯到 workspace 根目录
  • 三个地址互不重叠:fdt 0x138000000 < 内核 0x140000000 < FIT 上传点 0x180000000

常见问题

Q1:ERROR: new format image overwritten - must RESET the board

FIT 镜像上传地址与内核/fdt 加载地址重叠。此前用 fastboot -l 0x140000000 上传 FIT,而内核 load 地址恰好也是 0x140000000,bootm 搬运内核时覆盖了 FIT 自身。

解决:FIT 上传到与子镜像加载地址错开的地址,如 0x180000000

Q2:configured root device was not found in discovered block devices

bootargs 里的 root= 指定了不存在的分区。旧设备树固化的是原厂 root=PARTUUID=9a52aa56-...,与 StarryOS 的 GPT 分区名不匹配。当前 dts 已改为 root=PARTLABEL=rootfs,不再出现。

Q3:TEST_UNIT_READY failed ... retry 1

UFS 设备上电后返回 UNIT_ATTENTION(sense key 0x06/asc 0x29 = power-on reset),驱动重试后成功,是正常行为。

待改进项

  • ${dtb_bin} 占位符:当前 fdt 路径是手写的相对路径,与 mkimage 的解析基准(.its 所在目录)耦合。后续可在 axbuild 的 render_uimage_its_template 增加 ${dtb_bin} 占位符,像 ${kernel_bin} 一样由 axbuild 替换为绝对路径,消除路径魔法。
  • starry-mininal-k32-.its 孤儿文件:K32 设备的遗留文件(K3 ≠ K32),无匹配的 board 配置,永远不会被构建触发,可择机清理。