K3 COM260 Kit 刷机流程:FIT 单文件烧录 + 可编辑设备树
背景
StarryOS 在 SpacemiT K3 COM260 Kit 真机上运行,之前的启动流程非常繁琐:
- 必须手动设置 bootargs。设备树里固化的是原厂 Linux 参数(
root=PARTUUID=...),与 StarryOS 的 GPT 分区名(rootfs)不匹配,导致启动 panic:configured root device was not found。每次开机都要在 U-Boot 里setenv bootargs root=PARTLABEL=rootfs才能启动。 - 内核与设备树分两次上传。fastboot 需要 U-Boot ↔ 宿主机来回配合两次(
fastboot stage内核 +fastboot stage设备树),再booti指定两个加载地址。 - 设备树不可编辑。
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.its | FIT 镜像描述文件(内核 + 设备树打包) |
os/StarryOS/configs/board/spacemitk3-com260kit.toml | K3 板级构建配置(触发 axbuild 自动打包) |
刷机流程
1. 构建内核(自动生成 FIT 镜像)
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 0x180000000bootargs 已固化在设备树里,无需手动 setenv。
3. 验证
root@starry:#
ls /dev/k3_airunner设备树如何编辑
spacemit-k3-com260-ifx.dts 是 dts 源码,直接编辑后用 dtc 编译:
dtc -I dts -O dtb spacemit-k3-com260-ifx.dts -o spacemit-k3-com260-ifx.dtb当前 chosen 节点的 bootargs:
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 的要点:
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 配置,永远不会被构建触发,可择机清理。