3. 开发环境搭建(下):RK SDK 源码获取与编译工具链配置
上一节我们把 Ubuntu 虚拟机跑起来了,也装好了基础工具。但说实话,那只是热身。真正的开发工作,是从拿到 RK SDK 源码开始的。
我记得第一次接触 RK 的 SDK 时,光是 repo sync 就等了快两个小时。那时候心里直打鼓——是不是我网络有问题?是不是哪里配错了?后来才发现,这很正常。RK 的 SDK 包含了从底层引导到上层应用的全部代码,体量确实不小。
好,我们一步步来。
3.1 获取 RK SDK 源码:repo init / sync
RK 的 SDK 用 Google 的 repo 工具管理。它本质上是对 Git 的封装,让你能一次性拉取几十个 Git 仓库。你想想看,一个完整的嵌入式 Linux 系统,内核是一个仓库,U-Boot 是一个仓库,Buildroot 又是一个仓库……手动一个个 clone 会疯掉的。
3.1.1 安装 repo 工具
先确认 repo 是否已安装:
which repo
如果没找到,按下面步骤装:
mkdir -p ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
export PATH=$PATH:~/bin
我个人习惯把 export PATH=$PATH:~/bin 加到 ~/.bashrc 里,这样每次打开终端就不用重新 export 了。
https://mirrors.tuna.tsinghua.edu.cn/git/git-repo,速度会快不少。
3.1.2 repo init:初始化工作目录
假设你从芯微官方拿到了 SDK 的 manifest 仓库地址(通常是一个 XML 文件,描述了所有子仓库的路径和分支)。执行:
mkdir rk_sdk && cd rk_sdk
repo init -u <manifest仓库地址> -b <分支名> --depth=1
--depth=1 这个参数我强烈建议加上。它只拉取最新一次提交的历史,能省下大量时间和磁盘空间。我在项目中遇到过有人没加这个参数,结果 SDK 占了 40 多 G,而加了之后只有 15G 左右。
3.1.3 repo sync:拉取全部代码
初始化完成后,执行:
repo sync -c -j4 --no-tags
解释一下这几个参数:
-c:只同步当前分支,不拉取所有分支的引用-j4:4 个任务并行拉取。网络好的话可以调成-j8甚至-j16--no-tags:不拉取标签,进一步减少数据量
这个过程会持续 20 分钟到 2 小时不等,取决于你的网速。期间如果中断了,重新执行 repo sync 会断点续传,不用担心。
3.2 SDK 目录结构解析
sync 完成后,我们来看看 SDK 里到底有什么。我以 RK3566/RK3568 的 SDK 为例,其他型号大同小异。
先放一张整体结构图,让你有个全局印象:
下面逐个说明每个核心目录的作用:
| 目录 | 作用 | 我常用的关注点 |
|---|---|---|
| kernel/ | Linux 内核源码,RK 基于主线内核做了大量芯片适配 | 关注 arch/arm64/boot/dts/rockchip/ 下的设备树文件 |
| u-boot/ | 引导加载程序,负责初始化硬件并加载内核 | 修改 board/rockchip/ 下的板级文件来适配新硬件 |
| buildroot/ | 构建根文件系统,生成你最终的 rootfs.img |
在 package/ 里添加自己的应用包 |
| app/ | 上层应用,比如 QT 界面、摄像头预览、NPU 示例 | 快速验证硬件功能时,直接跑这里的 demo |
| device/ | 芯片级配置,包括 dts、分区表、参数文件 | 改分区大小、调 DDR 参数都在这里 |
| rockdev/ | 打包脚本,把各个镜像拼成烧录包 | 量产时用的 mkupdate.sh 就在这里 |
核心理解: RK SDK 的目录设计遵循了「分层解耦」的思想。内核、引导、文件系统、应用各自独立,但又通过统一的构建脚本串联起来。你改内核不会影响文件系统,改应用不需要重新编译内核。这种结构在项目迭代中非常舒服。
3.3 编译工具链安装与配置
源码有了,目录结构也清楚了。但要让代码变成能在 RK 芯片上跑的二进制文件,还需要交叉编译工具链。
所谓交叉编译,就是在 x86 的 PC 上编译出 ARM 架构的可执行文件。你想想看,RK 芯片是 ARM 核的,而你的电脑是 x86 的,不用交叉编译的话,难道把编译器装到开发板上跑?那速度会慢到让你怀疑人生。
3.3.1 获取工具链
RK 官方推荐使用 ARM GCC 工具链。在 SDK 的 prebuilts/gcc/linux-x86/aarch64/ 目录下通常已经自带了一份。如果没有,可以从 ARM 官网下载:
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
tar -xf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
sudo mv gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu /opt/
我个人习惯把工具链放在 /opt/ 下,这样所有用户都能用,也方便在多个项目间共享。
3.3.2 配置环境变量
把工具链的 bin 目录加到 PATH 里:
export PATH=/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-
同样,建议把这 3 行加到 ~/.bashrc 里。不然每次打开终端都要 export 一遍,很烦。
aarch64-none-linux-gnu-gcc --version
如果能正常显示版本号,说明工具链已经就绪。
3.3.3 验证编译:编译一个最小内核
工具链配好了,我们来验证一下。进入 kernel 目录,编译一个最小配置的内核:
cd ~/rk_sdk/kernel
make ARCH=arm64 rockchip_linux_defconfig
make ARCH=arm64 rk3568-evb1-ddr4-v10.img -j4
如果一切顺利,你会在 arch/arm64/boot/ 下看到 Image 和 dtb 文件。看到它们,就说明你的开发环境已经彻底搭好了。
arm-linux-gnueabihf-gcc: not found,别慌。这通常是因为 SDK 里某些脚本硬编码了 32 位工具链路径。检查一下 Makefile 或 build.sh 里的 CROSS_COMPILE 变量,改成 aarch64-none-linux-gnu- 就行。我在 RK3399 项目上就踩过这个坑,折腾了半小时才发现是脚本里写死了 32 位工具链。
3.4 本章小结
到这步,你的开发环境算是真正「立」起来了。我们做了三件事:
- 用
repo init/sync拉取了完整的 RK SDK 源码 - 理清了 SDK 的核心目录结构——kernel、u-boot、buildroot、app 各司其职
- 安装并验证了交叉编译工具链,成功编译了内核
环境搭建是嵌入式开发里最枯燥但也是最关键的一步。环境没搭好,后面所有工作都无从谈起。好在 RK 的 SDK 体系比较成熟,只要按部就班来,基本不会出大问题。
嗯,环境准备好了。接下来就可以真正开始写代码、改驱动、调系统了。