接手一块正点原子的RK3588开发板,很多人的第一反应是赶紧把Android 12镜像构建出来,看看系统能不能跑起来。这个思路没问题,但如果你没搞过瑞芯微平台或者很久没碰AOSP,直接从“解压SDK然后敲./build.sh”开始,大概率会在环境、编译、烧录三个环节各卡一次。这篇博文我就按自己实际走通的路线,把RK3588 Android 12镜像构建从头到尾拆开讲,覆盖环境准备、源码编译、镜像打包、烧录验证和问题排查,尽量把我踩过的坑和验证过的做法都写进去。
先说下我这边的实验环境:正点原子ATK-RK3588开发板,8GB内存版本,eMMC 64GB,资料包里的Android 12 SDK版本。宿主机是Ubuntu 20.04.6,64位系统,内存32GB,磁盘预留了600GB。这套配置构建完整AOSP镜像比较舒服,如果你的机器配置低一些,后面我会单独讲资源不够时的应对方案。
1. 接手RK3588开发板:开工前先把资料盘清楚
1.1 正点原子RK3588这块板子的基本盘
RK3588这颗芯片是瑞芯微的旗舰级SoC,8核心设计,4个Cortex-A76大核加4个Cortex-A55小核,GPU是Mali-G610 MP4,自带6 TOPS算力的NPU,还集成了8K视频编解码单元。放到Android 12系统里,这套硬件组合意味着什么?简单说,它不像那些单核或双核的开发板,跑个精简Linux都费劲,而是具备完整旗舰手机级别的算力底座,所以Android系统的完整构建、启动、运行都有余量。
正点原子在这块板子上的做法比较“教科书”:把RK原厂的SDK拿过来,围绕自家硬件做适配,再配上详细的开发文档和资料包。所以你在正点原子的资料里看到的Android 12源码,本质上还是RK3588 Android 12 SDK,只不过正点原子把设备树、内核配置、预置APK、系统定制这些针对自家板子的改动都集成好了。
这意味着什么?意味着你在编译之前,不需要像从零适配一块新板子那样去改内核设备树、去适配显示屏驱动,正点原子已经把可用状态的东西全部放在了SDK里。你要做的,就是正确地把这份SDK构建成镜像,再正确烧录。这个定位很重要——大部分第一次做RK平台开发的人,问题往往不是出在“改代码”,而是出在“环境和流程”。
1.2 快照式资料包:先用哪些、后看哪些
正点原子随板子提供的资料包很大,通常几十GB起步,里面包含原理图、芯片手册、开发工具、系统源码、编译文档、烧录工具、驱动等一大堆东西。很多人拿到手就想着全部看一遍,其实没必要,构建镜像阶段你应该有选择性地提取信息。
我先列出构建镜像前必看的几样东西:
| 资料项 | 路径/来源 | 用途 |
|---|---|---|
| Android编译文档 | 正点原子提供的《RK3588 Android12开发指南》PDF | 官方推荐的编译环境版本、步骤、常见问题 |
| Android 12 SDK源码压缩包 | 资料包/源码目录下,通常是tar.gz或zip | 解压后作为构建根目录 |
| 烧录工具RKDevTool | 资料包/工具目录下,Windows版本 | 最终烧录镜像到开发板 |
| USB驱动DriverAssitant | 资料包/工具目录下 | Windows识别板子的Loader设备 |
| 串口调试工具 | 资料包/工具目录下,如SecureCRT或MobaXterm | 查看启动日志、进入Uboot命令行 |
先说结论:源码压缩包是最优先拿到的,其他资料可以等编译完再细看。因为源码解压需要时间,你可以让它在后台解压,同步去读编译文档。
这里重点提醒一句:资料包里如果同时存在多个版本的SDK压缩包,先确认你要编译的是哪个版本,以及对应的烧录工具版本。RK的SDK和烧录工具之间有微妙的关系,工具太老可能不识别新镜像格式,工具太新有时反而会因为默认配置变化导致分区表不匹配。我习惯把源码压缩包的名称、MD5值记录下来,避免解压后才发现文件损坏,白白浪费几个小时。
1.3 构建流程的整体认知框架
在动手之前,我建议你把整个构建流程像看地图一样先过一遍。RK3588的Android 12镜像构建,不是简单的“运行一条make命令”就完事,而是三段式结构:
- U-Boot编译:生成引导加载程序,负责初始化DDR、加载内核。
- 内核编译:生成kernel镜像和设备树,负责驱动硬件。
- Android系统编译:生成system、vendor、boot等分区镜像,承载整个用户空间系统。
RK官方SDK提供的build.sh脚本就是把这三个阶段串联起来,并且负责最后的镜像打包。我见过很多第一次接触的人直接跳进源码目录敲make,结果因为没有先设置环境变量和lunch目标而报错——不是命令不对,而是你不该绕开SRK提供的构建入口。认清这个三段式结构,后面看编译日志时你会非常清楚当前进行到哪一步,报错时也能快速定位是哪一段出了问题。
2. 宿主机环境配置:AOSP不是随便一台电脑就能跑的
2.1 硬件门槛到底有多高
AOSP(Android Open Source Project)的构建对机器配置有明确的下限要求,而RK3588的Android 12 SDK由于包含完整的U-Boot、内核和Android用户空间,对资源的需求只会更高,不会更低。
先说结论性的配置建议:
| 配置项 | 最低要求 | 推荐配置 | 备注 |
|---|---|---|---|
| CPU | 8核 | 16核及以上 | 影响全量编译耗时 |
| 内存 | 16GB | 32GB | 低于16GB极易OOM(内存耗尽) |
| 磁盘空间 | 250GB空闲 | 500GB以上 | 源码+编译产物约200-300GB |
| 操作系统 | Ubuntu 18.04/20.04 64位 | Ubuntu 20.04 64位 | 正点原子官方推荐20.04 |
| 文件系统 | ext4 | ext4 | 不建议用NTFS/FAT挂载源码 |
磁盘这一项特别容易被低估。很多人以为源码包解压出来可能就几十GB,够用了,实际上编译过程中生成的中间文件、obj目录、镜像文件、ccache缓存加起来,轻轻松松到200GB以上。我自己的环境中,一次完整构建后out目录占用大约180GB,加上源码本身的90GB,总占用已经接近300GB。所以预留500GB真不是浪费。
另外还有个隐藏问题:源码必须放在Linux原生的ext4文件系统上。如果你是在Windows下用虚拟机共享文件夹方式挂载,或者挂在移动硬盘的NTFS分区上,编译过程中会碰上各种奇怪的符号链接错误和权限问题。我最初贪方便把源码放在挂载的移动硬盘上,结果编译到一半遇到“Too many levels of symbolic links”,排查半天发现是文件系统兼容性问题,最后老老实实把源码拷回本地磁盘才顺利通过。
2.2 Ubuntu环境依赖安装清单
正点原子官方文档里给了一串依赖包安装命令,我在实践中发现直接照抄没问题,但你也得知道每条命令背后的作用,这样出问题时才好排查。以下是我在Ubuntu 20.04.6上验证可用的完整依赖安装命令:
sudo apt update sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev \ libc6-dev-i386 libncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev \ libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig这里有个细节:libncurses5-dev在Ubuntu 20.04的源里已经移除了,但RK的某些编译脚本还依赖它。如果安装时报错找不到这个包,可以这样处理:
sudo apt install -y libncurses5-dev || sudo apt install -y libncurses-devlibncurses-dev是兼容版本,实测对编译没有影响。
除了这些基础依赖,还有两个工具需要单独确认:python2和repo。RK的编译脚本中有一部分工具链还是基于Python 2的,Ubuntu 20.04默认装的是Python 3,所以你要手动确认Python 2存在。可以这样检查:
python2 --version如果没有,安装方式如下:
sudo apt install -y python2如果源里找不到python2包,可以下载源码编译安装,或者用符号链接方式指向系统中的Python 3(不推荐,因为部分脚本语法不兼容Python 3)。更稳妥的方式是直接从正点原子资料包里的工具目录中找到他们提供的Python 2相关文件。
repo是AOSP多仓库管理的核心工具,RK的SDK使用它来组织上百个Git仓库。安装方式:
mkdir -p ~/bin curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo export PATH=~/bin:$PATH这里需要提醒的是,repo本质上是一个Python脚本,它会从配置的manifest仓库中拉取所有子仓库。由于网络环境的差异,很多人执行repo sync时会遇到连接超时或者仓库拉取失败,这个我在后面的排查章节专门讲。
2.3 磁盘规划与ccache的取舍
构建Android镜像是一个非常吃磁盘IO的过程,所以磁盘规划直接决定你后面编译是否顺利。我自己习惯的做法是:
# 创建一个专门用于Android构建的目录 sudo mkdir -p /opt/rk3588 sudo chown -R $USER:$USER /opt/rk3588这种方案的核心思路是把源码放在系统盘上,避免跨文件系统操作。如果你有独立的大容量固态硬盘,也可以挂载到/opt/rk3588路径,用fdisk分区后挂载:
sudo mount /dev/sdb1 /opt/rk3588关于ccache,这是一个编译缓存工具,可以加速重复构建。对于AOSP这种大型项目,ccache确实能显著提升增量编译速度,但代价是额外占用磁盘空间。我建议如果你磁盘空间充足(1TB以上),可以开启ccache并把缓存上限调大:
export USE_CCACHE=1 export CCACHE_EXEC=/usr/bin/ccache ccache -M 100G如果磁盘只有500GB,我建议干脆不要开ccache。因为首次构建的缓存写入会占用大量磁盘,而增量编译在SDK改动不频繁时收益并不明显,反而可能因为缓存占满磁盘导致构建失败。
2.4 repo初始化与仓库同步的实操
正点原子的Android 12 SDK,通常有两种获取方式:一是直接解压他们提供的完整源码压缩包,二是通过repo从远端仓库同步。如果你拿到的是压缩包,解压完后源码目录里已经包含了.repo目录,这样其实已经完成了repo初始化的过程。我来说说解压这种更常见的情况。
解压SDK时我强烈建议用tar命令而不是图形界面右键解压,因为完整SDK压缩包通常有几十GB,图形界面解压不仅慢,还可能在过程中卡死。
tar -xzf rk3588-android12-sdk.tar.gz -C /opt/rk3588解压完成后,进入源码根目录,你会看到.repo目录存在,说明这个SDK是经过repo工具组织的。这时可以运行一次repo sync确保所有仓库都在正常状态:
cd /opt/rk3588 .repo/repo/repo sync -j8 -c-j8表示并行8个任务,-c表示只同步当前分支。如果你的网络状况不好,可以改成-j4降低并发,减少超时概率。这一步不是必需的,但它能提前暴露仓库问题,避免你在编译到一半时才发现某个仓库损坏。
我把这个阶段总结成一句话:环境配置的本质,是给编译器提供一个干净、确定、不被打扰的工作空间。很多人编译失败,不是代码问题,而是环境问题——依赖缺失、磁盘不足、文件系统不兼容,这些坑完全可以在按下编译键之前就排掉。
3. 源码结构与构建脚本:正点原子帮你封装好的那层胶水
3.1 源码目录核心结构速览
在编译时能准确知道自己在哪个目录下操作是很重要的。RK3588 Android 12 SDK的源码根目录结构大致如下:
rk3588-android12/ ├── .repo/ # repo仓库元数据 ├── kernel/ # Linux内核源码(5.10版本) ├── u-boot/ # U-Boot引导加载程序源码 ├── device/rockchip/ # 瑞芯微平台设备配置 ├── frameworks/ # Android框架层 ├── packages/ # 系统应用 ├── vendor/ # 厂商定制内容 ├── build/ # AOSP构建系统 ├── build.sh # 一键构建脚本 ├── mkimage.sh # 镜像打包脚本 └── Makefile # 顶层Makefile其中device/rockchip目录是RK平台的核心配置文件所在,你要关注的板级配置在类似device/rockchip/rk3588/这样的路径下。正点原子的板级定制,通常会在device/rockchip/rk3588/下新增一个针对自家板子的配置文件目录,包含BoardConfig.mk、AndroidBoard.mk、device.mk等文件。
3.2 build.sh里到底干了什么
很多教程直接告诉你“执行./build.sh就行”,但如果你不理解脚本内部逻辑,遇到问题会很被动。我摘录了RK标准build.sh的关键逻辑(不同版本可能略有差异):
#!/bin/bash # 设置编译环境 source build/envsetup.sh # 设置lunch目标 lunch rk3588_s-userdebug # 编译u-boot ./build.sh -U # 编译内核 ./build.sh -K # 编译Android系统 ./build.sh -A # 打包镜像 ./mkimage.sh实际执行的时候,你只需要运行:
./build.sh -U -K -A这个命令会依次编译U-Boot、内核和Android系统。编译完成后,mkimage.sh会把产物打包成最终烧录使用的镜像文件。
让我拆解一下这个流程背后的逻辑:U-Boot编译时,会根据u-boot/configs/rk3588_defconfig生成uboot.img;内核编译时,会基于kernel/arch/arm64/configs/rockchip_linux_defconfig和对应的设备树文件生成boot.img(内核和ramdisk合在一起);Android系统编译则负责生成super.img(包含system、vendor、product等分区)。
正点原子在SDK里做的适配工作,就体现在这些默认配置已经被预设成了自家板子的参数。你不需要去手动指定设备树文件或者U-Boot配置,脚本已经选好了。
3.3 单独编译u-boot、kernel、Android的分工逻辑
虽然一键编译很方便,但实际开发中你一定会遇到“只改了内核,不想全量编译”的场景。这时单独编译就非常实用。
单独编译内核:
cd /opt/rk3588/kernel make ARCH=arm64 rockchip_linux_defconfig make ARCH=arm64 rk3588-evb1-lp4-v10.img -j16这里rk3588-evb1-lp4-v10.img是RK默认的镜像目标,但正点原子板子的实际设备树可能在kernel/arch/arm64/boot/dts/rockchip/目录下,文件名类似rk3588-atk.dts或者rk3588-evb*.dts。你需要确认SDK里device/rockchip/rk3588/下用的是什么设备树文件名,然后对应修改编译目标。
判断方法很简单,查看device/rockchip/rk3588/BoardConfig.mk:
# 如果看到类似这样的配置,就说明设备树是rk3588-evb1-lp4-v10.dts PRODUCT_KERNEL_DTS := rk3588-evb1-lp4-v10单独编译U-Boot:
cd /opt/rk3588/u-boot make rk3588_defconfig make -j16编译产物是uboot.img和trust.img。
单独编译Android系统:
cd /opt/rk3588 source build/envsetup.sh lunch rk3588_s-userdebug make -j16这种分段编译的意义是,当你发现问题出在哪一层时,可以只重编那一层,然后重新打包。比如你改了内核驱动,只需要重编内核,再把新的boot.img烧进去,不需要重新编译整个Android系统,节省大量时间。
我自己在开发中更习惯用分段编译,因为RK3688这种平台的Android全量编译一次,在32GB内存、16核CPU的环境下也需要2小时左右,而单独编内核只要几分钟。做板级开发,这个节奏差异是决定性的。
4. 全量构建与产物解读:从编译日志到镜像文件
4.1 lunch目标与设备配置
lunch是AOSP构建系统的核心命令,它决定了你要为哪个设备、哪个构建类型生成镜像。在RK3588的SDK里,默认的lunch目标是类似这样的:
source build/envsetup.sh lunch rk3588_s-userdebug你可能会问:为什么不是aosp_arm64-userdebug?因为RK SDK对AOSP构建系统进行了定制,rk3588_s是一个自定义的产品名称,s代表的是RK对单系统(仅Android,不含Linux)的称呼。userdebug是构建类型,表示这是一个带调试权限的用户版本,允许adb root。
查看所有可选的lunch目标:
lunch这会列出一个菜单,你可以在其中选择RK预置的各个板型。在正点原子SDK中,你通常只需要选择他们默认配置的RK3588目标即可。
构建类型有三个选择:user、userdebug、eng。这里我建议开发和验证阶段都用userdebug,因为它兼顾性能和调试能力。eng类型会额外包含大量调试工具,镜像体积大,不适合日常使用;user类型则缺少root权限,不方便开发调试。
4.2 全量编译过程中的资源监控点
当你执行./build.sh -U -K -A后,编译就正式开始了。这一步会持续1.5到3小时不等,取决于机器性能。在这个过程中,我建议你做三件事:
第一,不要频繁切换终端或者打开大量窗口。AOSP构建是多进程并行,每个GCC/Clang进程都是内存大户,本身就已经把内存用到极限。此时如果你再打开几个浏览器标签页或者IDE,很可能直接触发OOM。
第二,监控磁盘空间。在另一个终端里执行:
watch -n 60 df -h如果发现/opt/rk3588对应的分区空间使用率超过90%,要立即停止编译,处理空间问题。编译中途磁盘写满会留下大量不完整文件,后续检查很麻烦。
第三,监控内存和CPU:
htop正常情况下,16核CPU的负载应该在1400%到1600%之间,内存使用率会逐步攀升到90%以上。如果你的内存使用率到100%,而系统开始大量使用交换分区,那编译速度会呈指数级下降,这时候就需要考虑增加 swap 空间了。
关于swap的应急方案,如果编译过程中内存吃紧,可以临时增加一个swap文件:
sudo fallocate -l 32G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile这样能给系统一点缓冲,避免OOM直接杀死编译进程。
4.3 产物镜像解读:哪些要烧、哪些不用管
编译完成后,RK的脚本会把所有镜像输出到rockdev/Image-rk3588_s/目录。这里面的文件很多,但你需要烧录的只有几个关键文件:
| 镜像文件 | 作用 | 是否必须烧录 |
|---|---|---|
uboot.img | U-Boot引导程序 | 是 |
trust.img | ATF可信固件 | 是 |
boot.img | 内核+ramdisk | 是 |
super.img | system、vendor、product等系统的合并镜像 | 是 |
baseparameter.img | 分区参数和系统配置 | 建议烧录 |
MiniLoaderAll.bin | 一级引导加载器 | 是 |
parameter.txt | 分区表描述 | 是 |
misc.img | 启动模式相关 | 可选 |
recovery.img | 恢复模式镜像 | 可选 |
这里super.img是Android 10之后引入的动态分区概念,把system、vendor、product等分区合并到一个镜像里。RK板子依然在烧录工具里保留了单独烧录分区的能力,但对于完整刷机,烧录super.img就够了。
为什么MiniLoaderAll.bin和parameter.txt很重要?因为RK3588的启动流程是:SoC ROM代码先加载MiniLoaderAll.bin,然后由它根据parameter.txt里的分区表加载uboot.img和trust.img,最后加载boot.img启动内核。如果分区表和烧录地址不对,后面的所有镜像都白烧。
4.4 验证产物完整性的快速方法
在把镜像拷贝到Windows烧录之前,我建议先在Linux下做一次完整性检查:
cd rockdev/Image-rk3588_s/ ls -lh *.img *.bin *.txt重点确认每个镜像文件的大小不为0,且parameter.txt文件存在。我遇到过编译成功但super.img生成不完整的情况,此时编译日志末尾显示“OK”,实际上镜像文件只有几十MB,明显不对。正常的super.img取决于你SDK中预置的Android应用数量,通常在2GB到4GB之间。如果你看到文件大小异常,别急着烧录,先检查编译日志。
另外,编译日志的结尾阶段会打印出一个“Combined超级镜像”的摘要,说明哪些分区被合并进了super.img。我建议把这个摘要截图保存,后面排查启动问题时会很有用。
5. 烧录验证:编译成功只是开始,跑起来才算数
5.1 RKDevTool烧录工具准备与驱动安装
RK3588开发板的烧录,最常用的是Windows平台上的RKDevTool(瑞芯微开发工具)。正点原子资料包里通常提供V3.x版本,这个版本对RK3588支持完善。
第一步是安装驱动。打开资料包中DriverAssitant目录,运行DriverInstall.exe,点击“驱动安装”。这一步经常被忽略,但如果不装驱动,开发板接入电脑后无法识别为烧录设备,RKDevTool也就看不到设备。
安装完成后,用USB Type-C数据线连接开发板的Type-C烧录口和电脑的USB口,同时给开发板上电。正常情况下,Windows设备管理器里会出现一个新的设备节点,名称类似“Rockusb Device”。
5.2 进入Loader/MaskROM模式的完整姿势
RK3588烧录的前提是让芯片进入烧录模式,常见的有两种:
Loader模式:开发板上电时,按住板子上的Loader键(或Recovery键)不松,同时按一下复位键或重新上电,保持按键两三秒后松开。正常进入Loader模式后,RKDevTool的界面会变成“发现一个设备”。
MaskROM模式:如果Loader模式进不去,比如U-Boot损坏,就需要进入MaskROM模式。操作方法是:按住板上的MaskROM键(可能标记为MASK),同时重新上电。MaskROM模式下,RKDevTool同样能识别到设备,但此时只能烧录MiniLoaderAll.bin,等Loader恢复后再烧其他镜像。
我把两种模式的操作步骤整理了对比,方便你对照:
| 操作 | Loader模式 | MaskROM模式 |
|---|---|---|
| 按键 | 按住Loader/Recovery键 | 按住MaskROM键 |
| 上电 | 按一下Reset键 | 重新上电 |
| 识别现象 | 设备管理器出现Rockusb Device | 设备管理器出现Rockusb Device |
| 烧录范围 | 所有分区均可烧录 | 必须先烧MiniLoaderAll.bin |
5.3 分区粒度烧录与地址关系
打开RKDevTool后,你会看到默认的烧录配置表,这个表是根据parameter.txt解析出来的。不同工具版本可能显示为“地址”和“文件”两列,常见配置如下:
| 分区 | 地址 | 文件 | 说明 |
|---|---|---|---|
| loader | 0x0 | MiniLoaderAll.bin | 一级引导 |
| parameter | 0x0 | parameter.txt | 分区表 |
| uboot | 0x4000 | uboot.img | U-Boot |
| trust | 0x6000 | trust.img | ATF固件 |
| boot | 0x8000 | boot.img | 内核和ramdisk |
| super | 0x10000 | super.img | 系统镜像 |
| baseparameter | 0x0 | baseparameter.img | 系统配置 |
在烧录之前,请务必核对每个分区对应的文件是否正确。尤其是parameter.txt和super.img,很多人会把其他板子的配置表带进来,导致分区大小不匹配,烧录后系统起不来。
选择好所有镜像文件后,点击“执行”按钮,工具会开始逐个分区烧录,进度条会依次走完。烧录完成后,工具会提示“下载成功”,此时可以断开USB线,重新给开发板上电。
5.4 首启验证清单:串口日志、adb、关键外设
烧录成功后,第一次启动系统,我建议按以下顺序验证:
第一步,看串口日志。用USB转串口模块连接开发板的调试串口(通常是TTL电平,波特率1500000,RK平台专用波特率),上电后观察串口输出。正常的启动日志会依次出现U-Boot开机Logo、内核启动信息(包含“Booting Linux on physical CPU”)、Android init进程启动信息。如果你在串口里看到完整的init启动流程并且最后出现console:/ #或者Android的日志,说明系统已经起来。
第二步,验证adb。开发板通过网络或者USB连接电脑,执行:
adb devices正常情况下能看到设备的序列号,并且状态是device而不是unauthorized。此时执行:
adb shell getprop ro.build.version.release如果返回12,说明Android 12系统正常启动。
第三步,验证关键外设。插入HDMI线到显示器,确认桌面正常显示;连接USB鼠标键盘,确认输入正常;检查千兆网口,确认网络连通。对于RK3588来说,NPU、GPU这些硬件模块通常在系统启动时就会初始化完毕,从串口日志中搜索rknpu、mali关键字可以确认它们是否正常注册。
关于RK3588平台的特殊点,这里补充一个实操技巧:串口波特率不要按常规的115200去试,RK平台的调试串口默认波特率是1500000,很多新人在这一步卡住,以为串口没接好,实际上是波特率不对。
6. 高频问题排查与工程化建议
6.1 编译中途OOM崩溃排查链路
这是我在RK3588 Android 12构建中遇到频率最高的问题,尤其是内存低于16GB的机器。OOM崩溃的现象很典型:编译日志突然卡住,接着出现类似Killed或signal 9的错误,然后整个build.sh进程退出。
排查链路如下:
第一,确认是不是真的OOM。查看系统日志:
dmesg | grep -i "out of memory"如果出现Out of memory: Killed process字样,就确认是OOM。
第二,找出内存消耗大户。AOSP构建中最耗内存的是C++编译任务,clang++进程每个可以吃掉1-2GB内存,16核并行就意味着16-32GB的内存消耗。此时需要降低并行度:
./build.sh -U -K -A -j8或者如果你使用make命令,直接指定:
make -j8-j8表示同时运行8个编译任务,这样内存峰值会显著下降。虽然编译时间会拉长,但总比编译到一半崩溃强。
第三,增加swap空间作为兜底。我已经在前面提过怎么增加swap文件,这一步能有效缓解OOM,但不要完全依赖它,因为swap读写速度远慢于内存,会拖慢编译速度。
6.2 repo sync中断与容错策略
如果你是通过repo同步源码(而不是解压压缩包),大概率会遇到repo sync中断的问题。常见报错包括连接超时、服务器拒绝连接、以及某个仓库无法完整克隆。
我的处理思路是这样的:
遇到中断后,不要急着重新执行完整同步,而是用断点续传的方式:
.repo/repo/repo sync -j4 -c --force-sync--force-sync参数会强制将本地仓库状态对齐远端,即使本地有未提交的改动也会被覆盖(执行前确认你本地没有需要保留的修改)。
如果某个仓库反复失败,单独同步那个仓库:
.repo/repo/repo sync -j4 -c <仓库路径>还有一个容易忽略的点:确保源码根目录路径中不含中文和空格。repo工具对路径里的特殊字符非常敏感,路径不规范会引发各种诡异问题。我见过有人把SDK放在D:\软件\正点原子\RK3588这种路径下,repo sync直接报错无法创建符号链接。
6.3 烧录失败最容易忽略的两个细节
烧录阶段两个高频问题,我都踩过:
第一个是驱动冲突。Windows上如果装过其他设备的驱动,或者RKDevTool版本换过,可能导致Rockusb设备驱动异常。现象是:RKDevTool打开后,界面显示“没有发现设备”,但Windows设备管理器里明明有未知设备。解决办法是:先在设备管理器里卸载该设备并勾选“删除此设备的驱动程序软件”,然后重新安装DriverAssitant里的驱动,重启电脑再试。
第二个是USB线质量。RK3588烧录使用的是USB Type-C接口,但并不是所有Type-C线都支持数据传输,有些线只能充电。如果你发现设备始终无法识别,换一根短线、高规格的USB线试试。我这里还遇到过一种情况:用前置USB口供电不稳定导致设备反复断开,换到主板后置USB口后问题消失。
6.4 版本管理:将自己的修改落到Git里
最后聊一个很多人忽视的话题。当你拿到SDK后,如果直接在里面改代码、改配置,却不做版本管理,那么一次错误修改可能导致你无法回到之前可用的状态。
RK的SDK本身是基于Git仓库组织的,所以你应该充分利用这一点。我建议这样管理:
# 在修改前,先创建自己的分支 cd /opt/rk3588 git checkout -b my-dev-kernel kernel/ git checkout -b my-dev-device device/每条分支对应你可能会修改的模块。每完成一个功能点或者修复一个bug,及时提交:
git add -A git commit -m "feat: 修改设备树适配正点原子RK3588显示面板"这样做的好处有两个:第一,你可以随时回退到之前的可用状态;第二,当正点原子或瑞芯微发布SDK更新时,你可以用git rebase把自己的修改迁移到新版本上,而不是重新手动打补丁。
我自己的习惯是,在编译成功并验证通过的这个节点,立刻打一个tag:
git tag -a v1.0-initial-build -m "首次全量编译通过"这样后面不管怎么折腾,都能快速回到这个已验证可用的基线。
最后分享一点个人体会。RK3588 Android 12的镜像构建,整个链路不算复杂,但每一步都讲究“确定性”:环境是确定的、源码是确定的、构建脚本是确定的,烧录工具和分区表也必须是确定的。任何一个环节引入了不确定性,后面排查问题的成本就会成倍增加。所以每次构建前,我习惯用几分钟快速确认磁盘空间、依赖工具、源码分支状态这三件事,看起来多花了时间,实际上是在给后面两三个小时的编译过程上保险。
如果你也是第一次接触RK3588或者正点原子平台,建议严格按照本文的顺序走一遍:先盘资料,再配环境,然后编译、烧录、验证。走通一次之后,你对整个流程就有了完整的掌控感,后面的二次开发也好、系统裁剪也好,都会有坚实的基础。