尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

RK3588 SDK在Ubuntu 22.04上的环境搭建与离线编译实战指南

RK3588 SDK在Ubuntu 22.04上的环境搭建与离线编译实战指南 做RK3588开发的人十有八九都卡在“环境搭建”这一步上。板子还没点亮先把大半天时间耗在装依赖、解压SDK、踩老坑上了。尤其是Ubuntu 22.04刚上手那阵子跟SDK里默认适配的18.04/20.04环境存在一堆隐性的兼容差异一个包版本不对编译报错能把人整到怀疑人生。这篇东西不整虚的直接把我在Ubuntu 22.04上撸完瑞芯微RK3588 SDK全流程的经验倒出来包括离线包的准备思路和下载方案照着走能省下不少冤枉时间。适合刚拿到RK3588开发板、准备搞系统移植或者做BSP裁剪的兄弟参考。1. 搭建前的全局认知1.1 RK3588的SDK生态到底怎么回事瑞芯微的SDK跟很多芯片厂商的“阉割版demo”不一样它基本是把整个BSP开源体系都打包进来了。RK3588的SDK主要分两大流派一个是Android系统为主的全功能SDK包含kernel、u-boot、Android框架层、以及瑞芯微自研的RGA、MPP多媒体库等另一个是纯Linux方向的SDK走的是Buildroot或者Debian路线适合做边缘计算盒子、工控设备、NAS这类不用Android生态的产品。我这次搭建以Linux SDK为主线顺带讲Android12那条线。两条线的底层编译器、环境依赖差别不小最典型的就是交叉编译工具链——Android用Clang/GCC 4.9那套老古董Linux SDK用GCC 9/11交叉编译器混着用会出各种奇葩问题。1.2 为什么选Ubuntu 22.04截止我写这篇经验时瑞芯微官方文档推荐的环境还多是Ubuntu 18.04、20.04默认GCC版本比较老。但问题是新出的开发板、新的SDK版本很多工具脚本比如Python3写的打包脚本在老版本系统上反而有兼容问题。Ubuntu 22.04的GCC 11.2、Python 3.10、OpenJDK 11基础环境对编译RK3588的现代BSP更友好而且22.04的SSH、Samba、USB驱动等配套组件对开发板调试也更省心。不过这里有个核心矛盾得说透Ubuntu 22.04是“能用”但不是“开箱即用”。SDK里的很多脚本写死了老路径、老命令比如某个脚本调python而不是python3某个依赖库在老源里有、在新源里改名了。这些坑后面我会逐条展开你先有个心理预期就行。1.3 硬件配置焦虑什么机器能带得动先给你一个参考标准。我这边用的是一台X86主机AMD Ryzen 7 5800X、64GB内存、1TB NVMe SSD。RK3588的SDK全量编译包括Android是出了名的吃资源最夸张的时候编译线程一开内存直接吃到30GB以上CPU满载半小时起步。如果只编译Linux SDK的内核和根文件系统16GB内存加4核以上的CPU也能跑就是慢一点。磁盘空间一定要准备充足。我解压完Linux SDK是40GB左右Android SDK解压后能到150GB以上这还不算编译过程中产生的中间文件。编译完Android后整个SDK目录膨胀到250GB属于正常操作。建议至少给SDK预留300GB空间用单独分区挂载更稳妥。2. Ubuntu 22.04基础环境准备2.1 系统安装的几条硬建议Ubuntu 22.04的安装盘制作推荐用Rufus或balenaEtcher写盘方式选择DD模式不要选ISO镜像模式否则容易出现启动引导异常。分区的时候我习惯把SDK目录独立成一个分区挂载到/home/你的用户名/sdk或者/opt/rk3588好处是将来系统崩了要重装SDK数据不受影响直接重新挂载就能继续用。系统装完后第一个动作是换国内软件源。我用的是清华源顺手更新一下系统sudo sed -i s//.*archive.ubuntu.com//mirrors.tuna.tsinghua.edu.cng;s//security.ubuntu.com//mirrors.tuna.tsinghua.edu.cng /etc/apt/sources.list sudo apt update sudo apt upgrade -y有个反直觉的点官方源的某些老版本依赖包在22.04源里可能已经被替换了。这时候你反而需要保留部分默认源配置比如focal-updates、focal-security这类兼容源。我遇到过SDK依赖的libncurses5只在老版本源里有新源只有libncurses6导致menuconfig无法打开。这种情况后面排查章节细说。2.2 必装工具链清单RK3588 SDK编译需要的基础工具我整理了一份清单直接在终端分批安装即可# 基础编译工具 sudo apt install -y git ssh make gcc libssl-dev libncurses5-dev \ libncursesw5-dev g lzop u-boot-tools flex bison \ libgcc1 gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu \ bc cpio zip unzip rsync file wget # 后续经常用到的辅助工具 sudo apt install -y python3 python3-pip python3-distutils \ device-tree-compiler libudev-dev libusb-1.0-0 \ libgles2-mesa-dev libgl1-mesa-dev libx11-dev \ libjson-c-dev libssl-dev liblz4-tool注意libncurses5-dev在22.04的默认源里确实没有需要手动从Ubuntu 20.04源里下载deb包安装或者启用老版本源。我这边是直接下载了deb包因为就一个包手动装反而少折腾# 从Ubuntu 20.04仓库下载并手动安装 wget http://archive.ubuntu.com/ubuntu/pool/universe/n/ncurses/libncurses5-dev_6.2-0ubuntu2_amd64.deb sudo dpkg -i libncurses5-dev_6.2-0ubuntu2_amd64.deb2.3 Python环境坑必踩Ubuntu 22.04自带Python 3.10但SDK里部分脚本是用Python 2.7写的比如老版本Android SDK里的repo工具、mkimage.sh相关脚本。虽然新SDK大多做了Python3适配但保不齐哪个角落就有遗留。我的方案是安装python2并建立软链接# 安装Python2如果22.04源里没有用源码编译或者装miniconda的py2环境 sudo apt install -y python2 || true sudo ln -sf /usr/bin/python2.7 /usr/bin/python强烈不建议强行把python默认指向python3因为好多老脚本里用的是Python2语法你改了系统默认指向反而更容易暴雷。正确做法是按需切换哪个脚本需要Python2就在执行前临时export一下。3. SDK获取与离线包准备3.1 SDK获取的几条路径瑞芯微官方SDK一般通过两种方式分发百度网盘和Git仓库主要是gitlab.com上的rk3588仓库。国内开发者大概率走网盘路线因为官方Git仓库走起来速度感人一个repo仓库动辄几十GB同步到一半断连是常态。我搭环境时用的就是离线网盘包大概30GB的压缩文件解压后就是完整的SDK目录。如果你从Git仓库拉取核心命令是mkdir -p ~/rk3588-sdk cd ~/rk3588-sdk repo init -u [SDK仓库地址] -b [分支名] --no-repo-verify repo sync -c --no-tags -j4repo sync这里用-j4可能比-j8更稳因为瑞芯微的服务器性能一般并发太多会直接给你断开链接。这个坑我踩过当时一把梭用-j16结果拉到一半连接重置又要重新开始。3.2 离线包的结构与验证离线包解压前先看一眼目录结构是否完整。一个标准的RK3588 Linux SDK离线包应该包含以下核心目录目录名作用kernel/内核源码通常对应Linux 5.10版本u-boot/Bootloader源码buildroot/根文件系统构建系统device/rockchip/板级配置、设备树、分区表配置external/部分外部组件docs/开发文档、芯片手册app/部分应用层程序源码tools/打包工具、烧录工具prebuilts/预编译的工具链和二进制文件解压前先校验一下压缩包的完整性# 如果附带md5sum文件优先用md5校验 md5sum -c rk3588_sdk.md5sum # 解压 tar -xf rk3588_sdk_linux.tar.gz -C ~/sdk千万别跳过校验这一步。我试过一次网盘下载的压缩包解压到一半报gzip: invalid compressed data排查半天才发现是下载中断被自动续传软件搞出来的坏包。解压后顺手看一下SDK根目录下的README.md和docs/文件夹里面通常会写本SDK对应的编译环境要求、已知问题和更新记录先花10分钟过一遍能省后面2小时。3.3 目录权限与符号链接检查SDK解压完成后检查一遍关键目录是否有可执行权限。因为Windows和Linux混用的情况不少U盘或NTFS分区解压出来的文件可能丢权限位。chmod x build.sh chmod x make*.sh chmod x device/rockchip/common/*.sh另一个容易忽略的点是符号链接。SDK内部大量使用relativename形式的符号链接如果解压过程中这些链接没被正确保留比如在Windows下用WinRAR解压了zip格式的SDK包编译时会报一堆莫名其妙的“找不到文件”错误。还有一个简单的检查命令find $SDK_DIR -type l -exec test -e {} \; -print | wc -l正常情况这个数字应该接近0表示没有失效链接如果输出大量路径说明符号链接断了重新检查你的解压方式。4. 依赖环境搭建的手动与自动方案4.1 SDK自带一键配置脚本的坑绝大多数瑞幸的SDK根目录都有一个build.sh执行./build.sh -h能看到编译选项。但这个脚本不会帮你安装系统依赖它只负责编译层面的调度。部分版本SDK带了一个envsetup.sh执行后能配置一些环境变量比如交叉编译链路径、JAVA_HOME等。我的建议是把它跟当前shell环境绑定方便后续编译source envsetup.sh执行后有没有生效用echo $RK_BUILD_ROOT验证能输出路径说明环境变量设置成功。很多新手栽在“明明执行了source但编译时还是找不到命令”多半是开了新终端忘了重新source。4.2 在线安装依赖的完整记录如果网络条件不错我推荐用SDK自带的依赖检查脚本来装在线依赖。Linux SDK根目录下有scripts/或者docs/里会提供install_prerequisites.sh之类的脚本执行一下就能把大部分依赖补齐。如果不依赖脚本手动安装的核心依赖清单如下按顺序执行# 基础构建依赖 sudo apt install -y build-essential flex bison libncurses-dev \ device-tree-compiler bc lzop zip unzip \ libssl-dev libgmp-dev libmpc-dev \ gcc-aarch64-linux-gnu g-aarch64-linux-gnu # 文件系统构建依赖 sudo apt install -y mtd-utils gdisk parted \ dosfstools mtools python3-pyelftools \ libfile-which-perl libswitch-perl # 若编译Android主线 sudo apt install -y openjdk-11-jdk schedtool \ m4 lib32z1 lib32ncurses6 \ lib32stdc6 lib32gcc-s1 \ libx11-dev lib32readline-dev \ lib32z1-dev重点说下lib32系列Android编译强制要求32位兼容库Ubuntu 22.04在64位系统上默认不装这些缺了会在链接阶段报/usr/bin/ld: skipping incompatible ...错误。第一次编译Android时报了一堆这种错后来统一装完32位库才恢复正常。4.3 离线安装方案无网环境自救指南很多公司内网开发环境是隔离的或者开发者本机在复杂网络环境下apt源不稳定。这时候离线包的价值就体现出来了。我用的离线方案是“apt缓存转储deb包仓库”的组合核心思路是在一台能上网的同版本Ubuntu 22.04机器上把所有依赖下好做成离线安装包传递到目标机器。制作apt离线包有两种常见方式方式一利用apt缓存目录# 在可联网的Ubuntu 22.04机器上先执行apt安装 sudo apt install -y [所有需要的包] # 把apt缓存中的所有deb包导出 mkdir -p ~/apt-offline-packages cp /var/cache/apt/archives/*.deb ~/apt-offline-packages/ # 打包带走 tar -czf apt-offline-packages.tar.gz ~/apt-offline-packages目标机器上解压后用dpkg -i批量安装sudo dpkg -i *.deb这里有个坑dpkg -i处理依赖顺序时容易报“依赖关系未满足”需要多执行几遍。或者借助apt的--fix-broken修复一次sudo apt --fix-broken install -y方式二用apt-offline工具这个方案更优雅apt-offline能生成一个包含所有包名和依赖信息的文件在联网机器上下载后带回离线机器安装。不过实际体验中它对多架构支持、特殊源的处理有一些坑反正我是试过几次后还是老老实实用方式一。4.4 交叉编译工具链的落位技巧RK3588的交叉编译工具链通常SDK里会预置Linux SDK一般在prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/这类路径下。如果你是用git方式同步的SDK工具链一般会被repo sync一并同步下来不需要额外下载。关键是要把工具链路径加入PATHexport PATH$SDK_DIR/prebuilts/gcc/linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/:$PATH验证是否生效aarch64-none-linux-gnu-gcc --version如果没有工具链且离线包中没有预编译工具链就需要自己从ARM官网下载交叉编译器但在SDK编译时会出现版本匹配问题——官方SDK的Makefile很挑工具链版本不是随便一个aarch64-linux-gnu-gcc都能编出能跑的内核和u-boot。所以我还是推荐想方设法拿到SDK配套的预编译工具链这是省事的不二法门。5. 编译核心流程与参数选择5.1 选择编译目标别一上来就全量RK3588 Linux SDK的编译目标大体分内核、u-boot、Buildroot根文件系统三块。刚开始调试我建议分步编译别一上来全量。先编译内核cd kernel make ARCHarm64 rockchip_linux_defconfig make ARCHarm64 rk3588-evb1-lp4-v10.img -j16如果没有指定输出文件直接make ARCHarm64 -j16也可以会生成Image和dtbs。rk3588-evb1-lp4-v10.img对应官方EVB1参考板的设备树。如果你用的是第三方核心板设备树名称要改成厂商提供的那份。编译u-bootcd u-boot make rk3588_defconfig ./make.sh rk3588编译完会生成uboot.img、trust.img等镜像文件。编译Buildrootcd buildroot make rockchip_rk3588_defconfig make -j16整个Buildroot首次编译特别耗时因为要交叉编译大量应用组件快的机器也得1~2小时慢的可能要一晚上。建议首次编译时开着screen或tmux跑防止SSH断线导致编译中断。5.2 全量编译的命令套路当你确认三个核心组件都能各自编译通过后再回到SDK根目录执行全量编译./build.sh lunch # 选择编译配置 ./build.sh # 全量编译 ./build.sh updateimg./build.sh lunch会弹出一个菜单让选板型和系统配置跟Android的lunch逻辑类似。全量编译完成后输出镜像位于rockdev/目录下。这个顺序是我踩了几次坑才总结出来的。直接全量编译的问题在于一旦某个组件编译报错日志刷过去很难快速定位而且不同组件的依赖关系可能让你白编译半天。分步编译每个环节的验证目标都明确。5.3 内存与CPU资源的调度技巧RK3588 SDK编译极度吃内存尤其是Buildroot里的高并发编译任务。我习惯把-j参数设成物理核心数的一半再加一点比如8核机器用-j6或-j8但绝不盲目用-j32。之前在一台32核服务器上开-j32编译Buildroot直接触发OOM日志还很难定位到底卡在哪个包。内存不够时可靠方案是增加swap。我在编译RK3588之前把swap临时加到32GBsudo fallocate -l 32G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile编译完成后可以关掉swap释放磁盘空间sudo swapoff /swapfile sudo rm /swapfile5.4 首次编译的最短路径实战第一次上手我建议按下面的最短路径跑通一次不求编译出完整固件只求验证整个工具链没问题编译内核dts和Image检查交叉工具链是否正常单独编译u-boot的idbloader.img和u-boot.itb烧录到板子用串口看打印信息是否正常。内核编译时可以用make -j$(nproc)自动获取CPU核心数不过如果机器同时在跑其他任务还是手动指定一个小点的数值更稳。6. 常见问题与排查技巧实录6.1 问题排查的基本思路RK3588 SDK编译报错信息往往不是直接告诉你缺哪个包而是在中间某个环节爆出一段编译器输出需要你反推。我的排查顺序是先看日志尾部30行确认报错位置是编译、链接还是打包阶段再往前翻50行找第一个error:前缀的行最后根据报错内容回查依赖。build.sh的日志默认输出在终端建议重定向到文件方便回溯./build.sh 21 | tee build.log6.2 高频问题速查表我把实际工作中遇到的高频问题整理成了一张速查表每个项都是真实踩过的坑问题表现根本原因解决方案fatal error: libncurses.h: No such file or directoryUbuntu 22.04默认源缺ncurses5开发包手动下载20.04源里的libncurses5-dev/usr/bin/ld: cannot find -lz缺32位zlib库sudo apt install lib32z1-deverror: PATH_MAX undeclared内核编译时标准头文件冲突检查是否在非内核目录编译或清理include/generatedcc1: error: invalid option --no-integrated-as编译Android时用了系统GCC确认prebuilts里的工具链被正确加载不要用系统默认gccrepo sync: error: RPC failed; curl 56网络不稳定导致Git拉取失败降低并发数、换成网盘离线包No rule to make target modules_install内核配置未包含模块安装目标make modules_install前先make modulesError: DT compatible match not found设备树名称跟内核里的config不匹配检查arch/arm64/boot/dts/rockchip/Makefile确认设备树已编译Failed to connect to lunch缺少Python2环境或JDK配置错误重新source环境脚本检查java -versionmcopy: command not found缺mtools包sudo apt install mtoolsfile not recognized: File format not recognized交叉编译链版本与源码不匹配确认SDK配套的预编译工具链不要自行替换新版本Cannot find device for /dev/mmcblk0打包脚本跟实际存储介质不匹配检查打包配置文件里的StorageType参数6.3 独家排查技巧交叉工具链的“版本指纹”怀疑工具链版本有问题时最快的方式是直接看SDK里Makefile或scripts/目录里定义的版本期望值然后跟当前实际版本比对aarch64-none-linux-gnu-gcc -dumpversion比如SDK期望GCC 10.3你这里显示11.2那大概率会踩各种莫名其妙的内核编译错误。遇到这种情况别纠结着填坑直接找对版本的工具链替换回来更高效。6.4 编译时间太长挂掉的恢复方案典型场景Buildroot编译到70%SSH断了或者电源不稳导致编译进程被杀。重启后能接着编吗答案是大部分组件支持增量编译但Pipeline类构建可能产生部分残留文件导致冲突。我的做法是cd buildroot make clean make -j8有些时候make clean会把整套配置也清掉需要重新make rockchip_rk3588_defconfig。这里有个小技巧编译前把.config文件备份一份恢复时直接拷回来cp buildroot/.config ~/buildroot.config.bak # 下次恢复 cp ~/buildroot.config.bak buildroot/.config make olddefconfig make -j8这个操作能省掉重跑menuconfig的繁琐步骤。7. 离线包制作与分享的进阶心得7.1 SDK离线压缩的边界问题制作RK3588 SDK离线包时不是简单tar czf就完事。SDK内部有大量.git目录直接打包会异常巨大而且很多仓库里有历史对象文件完全没必要带走。我的做法是先同步完所有仓库后把.git目录清理或者仅保留当前分支find . -name .git -exec rm -rf {} \;这样打包后的体积能缩小30%到40%。但注意清理.git后后续想用repo sync更新代码就不行了需要重新从源头拉取。所以离线包一般用于一次性交付不适合长期迭代。7.2 apt离线依赖包的生成实践前面提到的apt离线包方案在实际操作中有几个细节要补充。/var/cache/apt/archives目录默认只保留apt-get install下载的deb包手动dpkg -i的包不会自动存入。如果想生成完整的离线仓库建议在联网机器上用apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts [包名] | grep ^\w | sort -u)批量下载依赖。但这种方式容易漏掉部分虚拟包或已经存在的包实操下来还是先安装、再把缓存目录打包来得可靠。7.3 离线包验证清单交付离线包前我习惯做一套完整验证用干净的Ubuntu 22.04虚拟机测试离线安装确认所有deb包能批量安装手动解压SDK离线包确认/kernel、/u-boot等关键路径可访问符号链接未损坏跑一次最小编译只编内核Image确认交叉工具链落位正确记录离线包MD5值发给对方时同步提供方便校验。这套验证流程虽然繁琐但能杜绝“对方拿到包后一套操作发现签名不对、链接断裂、依赖缺失”的尴尬场面。8. 写在最后的小技巧真正的环境搭好之后有几个容易忽略的小习惯强烈建议养成。第一所有编译命令都丢到tmux里跑SSH断开不中断任务第二在SDK根目录维护一份自己的env.sh把所有环境变量、工具链路径固化进去每次新终端source一下避免反复配置第三定期清理rockdev/和中间文件防止磁盘爆掉。我自己会把编译产生的所有镜像统一归档到一个带时间戳的目录方便回退。这个习惯在调试内核版本兼容性时帮了大忙。希望这篇经验对正在跟RK3588 SDK较劲的你有点帮助少踩几个我踩过的坑。
返回列表