
路认清了。今天跑第一次全量编译,从敲命令到认出产物:哪些 img 是分区,哪个整包能拿去刷。
./build.sh --product-name rk3568_evb --ccache 跑了三十多分钟,最后一行看起来像成功。你在 out/ 里转了一圈,看见一堆 .img,随手拿一个叫 update.img 的丢进刷机工具,工具打不开;换 boot_linux.img 当整包刷,工具说分区表不对。再过一天,终于找到 sd_image.img,刷进去内核 panic,串口在等 fe310000.sdhci,你这张卡明明插在 SD 槽里。
构建成功只说明各分区镜像生成了。可刷的整包是另一次打包。打包用的工具不在 ./build.sh 里,空分区镜像构建也不生成。SD 和 eMMC 的差别不在内核,在两份 fstab。这几件事叠在一起,第一次全量的人会觉得镜像体系有病。它没病,它只是把分区方案、瑞芯微的 RKFW、开源鸿蒙自己的 ramdisk,缝在同一个目录里。
环境那篇把 Ubuntu、依赖、白名单、khrplatform.h 说过了。这篇从「已经能开始 ./build.sh」往下写:命令、产物、打包脚本、两种整包头、fstab 介质、编完怎么验、OOM 137 和 ninja dupbuild。产品名 rk3568_evb。
16 核、32 GB 内存、SSD、ccache 已热,大概 30~40 分钟。冷 ccache、第一次、还要重编内核,靠近 40。16 GB 内存硬编也能开机,链接 vmlinux 和若干 thinLTO 的大 so 时会 OOM,退出码 137。那不是源码错。
常用开关:
ninja -w dupbuild=warn 必须在实际编译命令里。开源鸿蒙的 GN 偶尔让两个 target 写同一个输出,ninja 默认当错误。板级包装脚本若没加,你自己会在日志里看见:
看起来像两个模块抢文件。公版就这样。包装里应类似:
没有包装就自己补。不要去「修」那两个 target 的输出路径,那是跟整棵树作对。
日志用 tee 留下来。失败时从末尾往上翻,先看退出码,再看最后一个 FAILED。中间几千行 warning 多数可以当没看见。
成功之后,先去这里:
你应该能看到这些名字(缺哪个后面说怎么补):
以及构建不一定生成、打包却要的:
这四个是占位。正常启动内容为空,几百字节到 64K 全零。package-file 点了名,afptool 找不到文件就直接 FAILED。它们固化在:
./build.sh 不管它们。新机 rm -rf out 之后,images 里没有这四个,是正常的。
看体积,心里有个数:
经验范围(按产品裁剪会变,差一个数量级才需要紧张):
boot_linux.img 必须是 ext2。U-Boot 的 bootrkp 认这个格式、认分区名 boot_linux。不要把它转成 FIT、不要改名成 boot。file boot_linux.img 应类似:
里面至少有:
期望看到 Image 或内核文件、extlinux.conf、最好还有 ramdisk.img。extlinux.conf 缺 initrd 那一行,是致命的,启动链那篇写为什么会把 system 分区文件删光。这里先验存在:
里面要有类似:
fdt 那行可以有。开机真正用的 dtb 来自 resource 分区的 rk-kernel.dtb,不要以为改 boot_linux 里这份 dtb 就等于改了设备树。
可刷整包不是 ./build.sh 吐的。板级脚本 pack_update_img.sh 做四件事:把工具就位、把空分区补齐、把 images 同步到打包目录、两步合成。
三件套本身不在开源鸿蒙源码里,构建也不生成。放在:
afptool、rkImageMaker 是 x86-64 静态二进制。package-file 是文本,分区名必须和 parameter.txt 一致。
一份能在新机上跑的 pack_update_img.sh 骨架如下。路径按产品名写死,不要留占位符。
关键点:
package-file 长这样(分区名必须与 parameter.txt 里括号内的名字一致):
名字对不上的后果很阴:afptool 仍可能成功,对应镜像根本没写进整包。刷完板子用的还是旧分区,或空分区。打包前对一次:
boot_linux 必须叫 boot_linux。U-Boot 硬编码找这个名,改成 boot 或 kernel,日志不一定有明显错误,就是起不来。
misc.img 必须全零。U-Boot 看 misc 决定要不要进 recovery。非零的 misc 会让你「刷完怎么进了 recovery」。
打包目录最后躺两个文件:
看头,不要看文件名:
期望:
Windows 上:
52 4B 46 57 是 RKFW,52 4B 41 46 是 RKAF。
有人看见 update.img 眼熟,公版文档也写 update。那是另一条烧录链路,配 config.cfg 走「下载镜像」。本机实践里 RKAF 经常根本加载失败。eMMC 交付也交 RKFW,只是把 sd_image.img改名为emmc-xxx.img。文件头不会因为改名变成另一种格式。介质信息靠文件名约定,不靠魔数。
共享目录、md5,是给 Windows 那台刷机电脑用的。产物不要只停在 out/。虚拟机共享盘性能不够编源码,丢镜像可以。
内核、dtb、system.img,SD 版和 eMMC 版可以完全一样。差别在挂载路径里的控制器名:
两份文件:
fstab.required 典型四条(SD 版):
eMMC 版把 fe2b0000.dwmmc 换成 fe310000.sdhci。vendor 行必须带 required。只有 wait 的话,一阶段不挂 vendor,二阶段找不到 fstab.rk30board,/data 永远挂不上,foundation 崩,五十八秒重启。
fstab.rk30board 还要挂 userdata → /data、misc 等。同样按介质换控制器名。
只改一份的后果,按死亡时间就能认:
启动是串行的。先暴露第一个错。正确做法是一次 grep 全改,不要「先修日志里那一个再看」:
DTS 的 boot_devices=fe2b0000.dwmmc,fe310000.sdhci 是候选列表,两个都列是正常的,不要当 fstab 改。
切介质可以做成幂等脚本,只改挂载行,不碰注释和 DTS:
出完 eMMC 包,立刻改回 SD 再打一份 ramdisk/vendor。 否则下次你以为自己在编默认 SD,fstab 还留着 sdhci,SD 卡必 panic。源码树只应有一个「当前介质」状态。交付两份包,是两次 pack 的产物,不是树上长期并存两套 fstab。
改 fstab 不必重编内核。但要让 ninja 重打对应镜像:
ramdisk 里仍是 dwmmc、你以为已经切到 eMMC,就是 staged 副本没清。刷之前以镜像内文件为准,不以源码为准。
exit 0 不够。至少做这三组。
你这次没动内核,可以跳过。动过 defconfig / 板级驱动 / khdf,不要跳。
再解 resource,确认 U-Boot 即将交出的那份:
两份 dtb 对不上,刷 resource 和刷 boot_linux 效果会分叉。以 resource 那份为准。
4 GB 内存板,公版 MiniLoader 经常是 DDR V1.10 @ 1560 MHz,训练写完就停,串口不再往下走。能稳定起来的是 V1.16,频率常用 1056 MHz。
期望能看到 V1.16。看到 V1.10 又是 4 GB 板,先换 loader 再 pack。合成办法在启动链那篇,用 boot_merger 和 rkbin 的 ini。刷卡会覆盖卡上 loader 区,所以「我这张卡以前能起 4 GB」不能保证刷完还能起——新包把 loader 换掉了。
Windows 再 md5 一次。共享盘拷大文件可能截断,头仍是 RKFW,尾巴已经不是这次的 system。截断的包刷进去,后面几个分区是垃圾,现象随机。
日志末尾不是 error: xxx.c:12: ...,而是:
137 = 128 + 9,SIGKILL。OOM killer 在链 vmlinux 或 thinLTO 某个大 so 时动手。16 GB 无 swap 几乎必中。
加 swap,不必重装系统:
正在跑的那次已经被杀。重新 ./build.sh --product-name rk3568_evb --ccache,已经编完的 .o 和 ccache 还在,不会从零开始。虚拟机「动态内存」在链接高峰来不及要页,一样 137,给成固定 32 GB 更省心。
磁盘满的报错是 No space left on device,常出现在打 system.img 时,看起来像镜像脚本的 bug。df -h . 一眼能看出来。out/ 一次全量 60~80 GB,别和源码、prebuilts 挤在一块 256 GB 的盘上还留两份 out。
环境那篇写过,这里只把它接到「全量失败时别重装 Ubuntu」。
init 服务白名单。 板级在 init.rk30board.cfg 里加了自启服务,preloader 扫描时服务名不在名单里,报错在 out/preloader。把产品登记过的名单拷进 build/ 对应位置,或:
普通 ./build.sh(没有 --fast-rebuild)会重新生成 preloader。拷了名单还报,看是不是 out 里旧副本。
Lume 缺 khrplatform.h。 图形 3D 编到 spirv_cross_helpers_gles.cpp,include <KHR/khrplatform.h>,搜索路径指向 third_party/openGLES/api/GL。文件常缺,同仓库 EGL 里有:
cdc_ncm.c 的 rx_speed。 内核补丁删了字段,公版驱动还在用。板级应覆盖一份改过的 kernel/linux/linux-5.10/drivers/net/usb/cdc_ncm.c。没覆盖,编到 USB 网卡停。
这三件不是「依赖没装全」。重装 Ubuntu 解决不了。
全量的成本几乎全在用户态重链和大镜像。改一个驱动不要再走全量。三条捷径,细节留给最小重建那篇,这里只把边界划清:
改 dts / khdf / defconfig,至少要让内核 action 跑起来,删 checkpoint。改 uhdf / init.rk30board / 相机 json,不要删 out/kernel,否则你无偿买一次 8 分钟内核。
第一次全量的意义是:把 out/ 热起来,把 images 齐,把 pack 脚本跑通,拿到一份已知能进桌面的 RKFW。之后的每一次改动,对着源码树那篇的表,只重建对应那张 img。
product rk3568_evb not found。 产品 json 没登记,或板级 overlay 没 apply。先 ls device/product、ls device/board/rk。
ninja dupbuild 当错误退出。 加 -w dupbuild=warn。
137 / Killed。 OOM。加 swap,看 dmesg。
No space left on device。 盘满,或 loop 挂载没卸导致假满。df -h、losetup -a。
afptool not found。loader/ 里三件套没同步到 pack_update。rm -rf out 之后必现,除非脚本第 0 步会拷。
Add file: ./Image/misc.img open failed。 空分区没补。从 loader/prebuilt-images/ 拷。
Get image version failed。 rkImageMaker 缺 -os_type:ANDROIDOS,或 update.img 损坏。
整包头是 RKAF。 你把 update.img 当交付了。要用 sd_image.img。
刷进去 16s panic wait dwmmc。 介质和 fstab 错配。打包前 grep 两份 fstab,grep 镜像内副本。
刷进去 DDR 训练后无 U-Boot。 MiniLoader 版本。strings | grep DDR。
pack 出来的 sd_image 里 boot_linux 还是旧的。 第 2 步没 cp。比 images/ 和 pack_update/Image/ 的 md5。
两行不同就不要刷这张整包。
extlinux.conf 没有 initrd。 不要交付。缺 ramdisk 的启动会把 system 文件删光,重刷才能救。
第一次全量的验收不是「日志最后有 success」。验收是:sd_image.img 头为 RKFW、两份 fstab 与打算刷的介质一致、MiniLoader 能 strings 出正确 DDR 版本、boot_linux 是 ext2 且 conf 里有 initrd、md5 已经和即将拷走的那份对上。
系列第 8 篇 · 芯片:瑞芯微 RK3568 · OpenHarmony 4.1(API 11) · Linux 5.10
