Android SDK 编译(SMDT 双 SDK 联编)
1. 概述
1.1 功能简介
本文按 SMDT RK3588 3588A V3.1 板的实际产线流程编写。
本产品的固件不是在单一 SDK 树里编出来的,而是采用 Rockchip 的「双 SDK 联编」架构:两棵 SDK 树各负责一侧,分别编译后再把产物合并成完整固件。
- A16(system 侧):
ROCKCHIP_ANDROID16.0_SSI_SDK,Android 16 SSI 框架(API 36,build BP2A.250605.031.A3),lunch 目标ssi_16_arm64-bp2a-userdebug。SMDT 板卡资产(dts、外设驱动等)只在这棵树里维护,这棵树是它们的唯一源。 - A14(vendor 侧):
RK_Android14_SDK_Archive,Rockchip 官方 Android 14 全量 SDK(kernel 6.1.172、u-boot、rkst、RKTools),lunch 目标rk3588_u-userdebug,联编时只把它当 vendor 侧用。
1.2 应用场景
- Android 16 系统镜像全量/增量编译
- SMDT 板级适配(dts、外设驱动)与验证
- system.img / vendor_boot.img 等分区镜像定向更新
- update.img 整包生成、烧录与发布
1.3 工作原理
deploy_board.sh(板卡资产 A16 → A14,幂等)
→ rkbuild setup(写 config.json + 建软链)
→ rkbuild_build ssi(A16 编 system 侧,make dist)
→ rkbuild_build uboot(A14 编 u-boot)
→ rkbuild_build kernel vendor(A14 编 kernel 6.1.172 + rk3588_u vendor,GRF 合并出 target-files)
→ rkbuild_merge(framework 与 vendor 的 target-files 合并)
→ rkbuild_mkupdate(afptool/rkImageMaker 打包)
→ 产物:<A16>/rockdev/Image-rk3588_u/update.img
→ 烧录验证 / release_smdt.sh 发布全部阶段由 build_ssi16.sh(v2)统一调度:分阶段执行,每个阶段写独立日志,按日志里的成功标记判定成败(不依赖退出码)。失败时脚本会自动摘录真实错误并给出修复提示。
GKI/GRF 模式下(GKI 即 Generic Kernel Image,内核与厂商模块分离打包;GRF 指 system、vendor 两棵树分别构建再合并的框架),dtb 打进 vendor_boot.img,不存在单独烧写 kernel.img / resource.img 的用法;resource.img 只出现在 fastboot zip 里,update.img 的 package-file 无 resource 条目属正常。
2. 硬件准备
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 编译主机 | x86_64 Linux(Ubuntu 22.04,内核 6.8 实测) | 1 | ≥64 线程;RAM ≥256GB(JOBS=256 峰值约 200GB);NVMe,空闲 ≥500GB |
| 目标板 | SMDT RK3588 3588A V3.1(dts:rk3588_smdt_3588a_v31) | 1 | 用于烧录验证 |
| 调试线 | USB 转 TTL(3.3V) | 1 | 串口 1500000 8N1 |
| 烧录线 | USB Type-C(OTG 口,peripheral 模式) | 1 | RKDevTool / upgrade_tool 烧录 |
3. 软件准备
3.1 安装依赖包(Ubuntu 20.04/22.04)
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl \
zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev \
x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev \
libxml2-utils xsltproc unzip python3-pyelftools \
device-tree-compiler libssl-dev liblz4-tool lz4 \
rsync sshpass p7zip-full说明:
- JDK 无需安装(AOSP prebuilts 自带);
jq由 rkbuild 自带(vendor/rockchip/prebuilts/third_party/jq/jq),脚本预检会校验。 rsync / sshpass / 7z仅供release_smdt.sh发布使用。device-tree-compiler / lz4用于 dts 反查与 vendor_ramdisk 解包验证。
3.2 源码树(无需 repo init/sync)
两棵树已经就位,路径本身就是权威配置(写在 config.json 里):
| 树 | 路径 | 说明 |
|---|---|---|
| A16 | /home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK | system 侧 + 三个脚本(build_ssi16.sh / deploy_board.sh / release_smdt.sh)+ SMDT 板卡资产唯一源;git 仓库(master) |
| A14 | /home/diskj/xyp/RK_Android14_SDK_Archive | vendor 侧全量 SDK;无版本控制,重建需重打 kernel 直接补丁(见 4.8) |
3.3 磁盘空间要求
| 项 | 占用 |
|---|---|
| A16 源码树 | ~92 GB |
| A14 源码树 | ~98 GB |
| out 编译输出 | 100–150 GB |
| /tmp(联编中转) | ≥50 GB |
| rockdev 产物 | ~8 GB |
build_ssi16.sh 预检:任一相关目录剩余空间少于 20G 直接拒跑;少于 120G(/tmp 少于 60G)时告警。
4. 操作步骤
4.1 前置检查(可选但建议)
cd /home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK
bash deploy_board.sh --check # 只校验板卡资产部署状态,不改动all 流程的第 1 阶段(deploy)会自动执行部署。部署是幂等的(重复执行结果一致,不会叠加出错),通常无需手工跑。
4.2 标准全量编译(唯一入口)
cd /home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK
bash build_ssi16.sh all- 全量约 50 分钟(首次含 kati regen 约 4 分钟);增量约 15 分钟。
- 长时间编译建议放后台跑:
nohup bash build_ssi16.sh all > /tmp/build_all.log 2>&1 &。 - 成功后自动打印产物汇总(路径 + md5 + 新鲜度检查),据此确认结果。
- 注意:不要把 rkbuild 输出接管道(
| tail等),统一看.build_logs/下的阶段日志。
可用环境变量覆盖:A14_ROOT / BUILD_NUMBER(默认 202609)/ JOBS(默认 256)/ VENDOR_LUNCH / SYSTEM_LUNCH / KERNEL_DTS。
4.3 七阶段说明
| # | 阶段 | 实际动作 | 执行树 | 成功标记(日志判定) | 实测耗时(增量) |
|---|---|---|---|---|---|
| 1 | deploy | deploy_board.sh 推板卡资产 A16→A14 | A16→A14 | 日志无 [FAIL] | ~0s |
| 2 | setup | rkbuild setup 写 config.json + 建软链 | A16 | config.json 的 kernel_dts 正确 | ~86s |
| 3 | ssi | rkbuild_build ssi:system 侧 make dist | A16 | Build ssi ok! | ~158s |
| 4 | uboot | rkbuild_build uboot | A14 | Build u-boot ok! | ~26s |
| 5 | vendor | rkbuild_build kernel vendor(GRF 合并) | A14 | Build kernel ok! + Build android ok! + Build vendor ok! 三者齐全且无 failed | ~431s |
| 6 | merge | rkbuild_merge:target-files 合并 | A16 | Merge finished successfully | ~133s |
| 7 | update | rkbuild_mkupdate:afptool/rkImageMaker 打包 | A16 | Making update.img OK. | ~89s |
vendor 阶段必须在一次调用里同时传
kernel vendor两个参数,才会走 GRF 合并路径;手工分开调用会走 kernel-only / vendor-only,语义不同。
4.4 失败续跑与单阶段
bash build_ssi16.sh all vendor # 从 vendor 阶段续跑(vendor→merge→update)
bash build_ssi16.sh ssi # 只跑单阶段可用阶段名:deploy | setup | ssi | uboot | vendor | merge | update。续跑和单阶段共享 12 小时的会话基准,用于产物新鲜度判定。
4.5 快速验证 dts(不打包)
bash build_ssi16.sh dts只在 A14 kernel 6.1.172 上编 rockchip/rk3588_smdt_3588a_v31.dtb,并自动复核「no rk628 chip / no MCU chip」disable 标记已编入。改了 dts 后先跑这一步确认能编过,再走 4.8 的编译路径出包。
4.6 日志离线分析
bash build_ssi16.sh analyze .build_logs/vendor_20261022_xxxx.log
# 也可分析任意历史大日志:bash build_ssi16.sh analyze /tmp/rkbuild_all.log脚本会逐阶段判定,输出过滤噪音后的错误摘录和已知故障的修复提示。
4.7 手动单步(bash build_ssi16.sh env 打印,供排查用)
cd /home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK
source build/envsetup.sh
lunch ssi_16_arm64-bp2a-userdebug
rkbuild setup -l rk3588_u-userdebug -p /home/diskj/xyp/RK_Android14_SDK_Archive \
-f 202609 -d rk3588_smdt_3588a_v31 -j 256
rkbuild_build ssi > /tmp/ssi.log 2>&1
rkbuild_build uboot > /tmp/uboot.log 2>&1
rkbuild_build kernel vendor > /tmp/vendor.log 2>&1 # 必须一次传两个参数!
rkbuild_merge > /tmp/merge.log 2>&1
rkbuild_mkupdate > /tmp/update.log 2>&1判定成败看日志标记(见 4.3 表),退出码不可靠。
4.8 常见改动类型的正确编译路径
| 改动类型 | 修改位置(唯一源) | 编译命令 |
|---|---|---|
| 板级 dts / SMDT 外设驱动 | A16 device/rockchip/rockchip_generic/board/rk3588_smdt_3588a_v31/ → deploy 自动推到 A14 | bash build_ssi16.sh all vendor(~11 分钟) |
| Android framework / 系统应用(system.img 内) | A16 AOSP 树(frameworks/、packages/ 等) | bash build_ssi16.sh all ssi |
| kernel 深层补丁(直接改 A14 树的 pm_domains.c、GPU 冻结补丁等,deploy 不覆盖) | A14 kernel-6.1/ 源文件 | bash build_ssi16.sh all vendor;重建 A14 树后需重打 |
| vendor HAL / device 配置 | A14 device/rockchip/、vendor/ | bash build_ssi16.sh all vendor |
4.9 编译产物与烧录
产物目录:/home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK/rockdev/Image-rk3588_u/
rockdev/Image-rk3588_u/
├── update.img # 整包(~2.3GB),烧这个
├── MiniLoaderAll.bin / uboot.img / parameter.txt
├── boot.img / init_boot.img / dtbo.img / vendor_boot.img / vbmeta.img
├── super.img # system/vendor/product 等 dynamic partitions
├── misc.img / resource.img / baseparameter.img / config.cfg
├── ssi_16_arm64-target_files-merged.zip # merge 产物
└── ssi_16_arm64-images-merged-fastboot.zip # merge 产物(mkupdate 的镜像来源)烧录方式(RKDevTool / upgrade_tool):
- 推荐:直接烧
update.img整包。 - 分区烧写:先烧
parameter.txt(分区表)和MiniLoaderAll.bin(loader),再烧各分区镜像。dtb 在vendor_boot.img内,没有单独的 kernel.img / resource.img 分区可烧。
4.10 发布(release_smdt.sh)
cd /home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK
./release_smdt.sh # 默认 = 先编译(build_ssi16.sh all)再推送
SKIP_BUILD=1 ./release_smdt.sh # 跳过编译,直接推送现有 rockdev 产物
DRY_RUN=1 ./release_smdt.sh # 干跑:本地收集 + md5 自查,不上传流程:收集 rockdev/Image-rk3588_u/*,写 Version.txt(含 git log),再用 rsync + sshpass 推到 share@192.9.50.66:/home/share/rockchip-rk3588/3588_Android16_SDK/<REPO_NAME>/update_<DATE>/,远端跑 md5sum -c 核对。不传源码与中间产物。
4.11 编译时长参考(实测)
| 场景 | 耗时 |
|---|---|
| 全量(含 kati regen) | ~50 分钟 |
| 增量(7 阶段全过) | ~15.5 分钟(2026-10-22 一次连跑七阶段实测:deploy 0s / setup 86s / ssi 158s / uboot 26s / vendor 431s / merge 133s / update 89s) |
| 仅 dts 验证 | <1 分钟 |
5. 代码详解
5.1 目录结构(双树)
/home/diskj/xyp/
├── ROCKCHIP_ANDROID16.0_SSI_SDK/ # A16:system 侧
│ ├── build_ssi16.sh / deploy_board.sh / release_smdt.sh
│ ├── config.json # rkbuild setup 写入,联编权威配置
│ ├── .build_logs/ # 各阶段构建日志(<stage>_<STAMP>.log)
│ ├── device/rockchip/rockchip_generic/
│ │ ├── board/rk3588_smdt_3588a_v31/ # SMDT 板卡资产唯一源
│ │ └── vendorsetup.sh # rkbuild_* 函数定义(bash,非二进制)
│ ├── device/rockchip/common -> A14 同名 # 软链
│ ├── RKTools -> A14 实体 # 软链(afptool/rkImageMaker)
│ ├── frameworks/ system/ art/ bionic/ … # AOSP system 侧源码
│ ├── out/ # A16 编译输出
│ └── rockdev/Image-rk3588_u/ # 唯一 update.img 输出点
└── RK_Android14_SDK_Archive/ # A14:vendor 侧
├── kernel-6.1/ # 6.1.172;SMDT dts/驱动部署目标
├── u-boot/ device/rockchip/rk3588/…
└── rkst/ RKTools/ # 打包工具实体5.2 config.json(权威分工)
| 字段 | 当前值 | 含义 |
|---|---|---|
| Android_SYSTEM_SDK | /home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK | system 侧树 |
| Android_VENDOR_SDK | /home/diskj/xyp/RK_Android14_SDK_Archive | vendor 侧树 |
| system_lunch | ssi_16_arm64-bp2a-userdebug | system 侧 lunch |
| vendor_lunch | rk3588_u-userdebug | vendor 侧 lunch |
| kernel_path | <A14>/kernel-6.1 | kernel 出在 A14 |
| images_dir | <A16>/rockdev/Image-rk3588_u | 唯一 update.img 输出点 |
| kernel_dts | rk3588_smdt_3588a_v31 | SMDT 板 dts |
| kernel_config | gki_defconfig rockchip_gki.config valhall_gpu_gki.config | GKI 内核配置 |
| uboot_config | rk3588_defconfig gki.config | u-boot 配置 |
| build_id | BP2A.250605.031.A3 | Android 16 build |
| build_number / build_thread | 202609 / 256 | 构建号 / 并发线程 |
任何阶段续跑前,脚本会校验 kernel_dts 与预期一致;不一致会要求重跑 setup。
5.3 build_ssi16.sh v2 判定机制
- 只认日志标记,不认退出码:rkbuild heredoc 里
./build.sh失败后仍可能打印Build vendor ok!(假象),因此 vendor 阶段要求三个 ok 标记齐全且无 failed。 - 失败时自动摘录真实错误行(过滤 toybox cpio WARNING 等噪音),并按已知故障模式给修复提示(
hints_for)。 - 产物新鲜度:以
.build_logs/.session_start会话基准(12 小时有效)判定 update.img / resource.img / uboot.img / vendor_boot.img / super.img 是否陈旧;zip 解包产物的 2008 归档时间戳跳过不查。
5.4 deploy_board.sh 资产清单(A16 → A14)
| 资产 | 部署目标(A14 kernel-6.1) |
|---|---|
rk3588_smdt_3588a_v31.dts | arch/arm64/boot/dts/rockchip/ |
drivers_smdt/*.c + Makefile | drivers/smdt/ + drivers/Makefile(obj-m) |
include_smdt/slog.h | include/smdt/(驱动头文件依赖,勿漏) |
motorcomm.c | 裕太以太网 PHY 驱动(vendor 整体替换版) |
patches/smdt_kernel_compat.patch | 7 文件小改动(bootargs 日志缓冲 / gki.config 模块开关 / 4G modem VID/PID) |
| multicodecs 适配 | 耳机检测走 ADC(6.1.172 独立适配) |
| vendorsetup.sh 5 行容错 patch | 部署到 A16(无 .repo 时跳过模块软链解析) |
wifi.load 是构建时 find 自动重写的产物,不部署,也不需要手工维护。
5.5 版本确认
# 联编配置(build/dts/lunch/线程数等一揽子)
cat /home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK/config.json
# kernel 版本(6.1.172)
head -5 /home/diskj/xyp/RK_Android14_SDK_Archive/kernel-6.1/Makefile
# A16 树定制提交
git -C /home/diskj/xyp/ROCKCHIP_ANDROID16.0_SSI_SDK log --oneline -106. 常见问题
6.1 明明失败,日志却打印 "Build vendor ok!"
现象: vendor 阶段 ./build.sh -CKAd 内部 ninja 失败后,heredoc 仍继续跑 mkimage/rsync 并打印 Build vendor ok!,最后在 merge 阶段报 Missing file: rk3588_u-target_files-*.zip 退出。这是误导性错误,真实错误埋在几百 KB 日志中部。
处置: 用 build_ssi16.sh(内置标记判定和错误摘录)或 bash build_ssi16.sh analyze <日志> 定位;不要只看 tail 几十行就下结论。
6.2 ninja: ... vendor_ramdisk/lib/modules/xxx.ko no known rule
原因: A14 kernel 模块清单与 .config 不同步(历史案例:pwm-fan.ko,CONFIG_HWMON 被关导致 .ko 没编出;后来复查确认是过期的 ninja 依赖图造成的偶发问题)。
处置:
cd /home/diskj/xyp/RK_Android14_SDK_Archive
source build/envsetup.sh && lunch rk3588_u-userdebug
make installclean
# 然后回 A16: bash build_ssi16.sh all vendor6.3 手工 cp 新镜像后 mkupdate 又被打回旧版
原因: rkbuild_mkupdate 打包前会从 ssi_16_arm64-images-merged-fastboot.zip 解包同名镜像覆盖 rockdev 目录,磁盘上的新版被 zip 里的旧版冲掉。
处置: 定向更新镜像时要同时刷新 zip 成员(zip <zip> vendor_boot.img)再 mkupdate;模块改动还需先拷入 target_files 暂存区。建议一律走 4.8 表的脚本路径,避免手工链路。
6.4 改了 framework / 系统应用,m systemimage 后产物没变
原因: m systemimage 只重打 system.img,不触发 services.core 等模块重编,也不重打 target_files。
处置: system.img 内容改动的正确链路就是 ssi 阶段(make dist 重打 target_files 和 system.img,merged zip 自动更新):bash build_ssi16.sh all ssi。
6.5 磁盘 / 内存耗尽
现象: No space left / OOM Killed / Cannot allocate。
处置: 预检会在剩余空间 <20G 时拒跑、<120G 时告警;遇到 OOM 把 JOBS=128(或更低)重跑;/tmp 需 ≥50GB。
6.6 交互 shell 手动 source envsetup 报错(ugrep / Missing config)
原因: 交互 shell 的用户 profile 把 grep 别名成 ugrep,污染 AOSP 脚本;且构建脚本禁用 set -u(AOSP envsetup 引用未初始化 $TOP)。
处置: 把流程写成独立 .sh 用 bash xxx.sh 跑(干净的非交互子进程);不要把 rkbuild 输出接管道。
6.7 afptool 解 >2GB 包报 "check crc failed"
原因: afptool 的 32 位限制(super.img 符号位溢出),不代表镜像坏了。
处置: 最终验证不依赖 afptool:用 RKFW 头 loaderEnd@0x21 加打包日志条目里的 offset/size,dd 出对应分区比 md5;zip 成员用 unzip -p <zip> <img> | md5sum。
6.8 烧录到 40% 左右失败
结论: 属于环境性偶发问题(线缆/接口/主机),与镜像无关。重试、换线或换 USB 口即可,不必怀疑镜像或回退版本。
6.9 烧录后不开机
排查顺序:
- dts 是否含 MCU / rk628 双 disable(用
bash build_ssi16.sh dts复核标记); - 是否误烧了旧 vendor_boot 或分区表不匹配;GKI 模式 dtb 在 vendor_boot.img,优先整包烧 update.img;
- 分区烧写前是否先烧了 parameter.txt;
- 设备无法启动(变砖)时走 Maskrom 恢复:短接 Maskrom 触点并按住 RECOVERY(K1)上电,RKDevTool 识别后整包重烧。
7. 相关文档
| 文档 | 说明 |
|---|---|
| README_SMDT_MODIFICATIONS.md(A16 顶层) | SMDT 定制总览 |
| SMDT_CHANGES_VS_STOCK.md(A16 顶层) | 与原厂 SDK 差异清单 |
| handoff_2026-09-21.md(A16 顶层) | 移交笔记(内核显示链/GPU 冻结等实战记录) |
| RK3588_ANDROID16_BUILD_NOTES.md(旧16 树) | 历史实战笔记 |
| ch02-android-build-system-incremental-build.md | 构建系统背景 |
| 05hardware-reference/00硬件事实基线.md | 硬件事实清单 |
