第二章 开发环境搭建:Ubuntu交叉编译环境、SDK下载与解压、Buildroot与Yocto构建系统选择
好,咱们直接进入正题。搭建开发环境这件事,说难不难,说简单吧,我第一次搞的时候也踩了不少坑。你想想看,瑞芯微的芯片那么多,每个平台的SDK结构还不完全一样,要是环境没搭对,后面编译起来全是泪。
这一章,我就带你一步步把环境捋顺。咱们的目标很明确:让你的电脑能编译出能在RK芯片上跑的程序。
2.1 Ubuntu交叉编译环境搭建
为什么非要用Ubuntu?说白了,瑞芯微官方提供的工具链和SDK,都是在Ubuntu上验证过的。我个人习惯用Ubuntu 18.04或20.04 LTS,这两个版本最稳。你非要用22.04也行,但有些老SDK的依赖包可能会报错,到时候别来找我哭(笑)。
2.1.1 安装基础依赖包
拿到一台新装的Ubuntu,第一件事就是装包。别偷懒,少了哪个后面编译都会卡住。我一般直接跑下面这条命令,把常用的全装上:
sudo apt-get update
sudo apt-get install -y \
build-essential \
git \
repo \
wget \
curl \
python3 \
python3-pip \
libssl-dev \
libncurses5-dev \
u-boot-tools \
device-tree-compiler \
flex \
bison \
gawk \
texinfo \
gettext \
zlib1g-dev \
libglib2.0-dev \
libpixman-1-dev \
libtool \
autoconf \
automake \
cmake \
meson \
ninja-build \
pkg-config \
libudev-dev \
libusb-1.0-0-dev
python 软链接到 python3。有些老脚本写死了 #!/usr/bin/env python,找不到就会报错。我当初就被这个坑过,查了半天。
2.1.2 安装交叉编译工具链
瑞芯微官方推荐用 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu 这个版本。为什么是10.3?因为Buildroot和Yocto的某些组件对GCC版本有要求,太新或太旧都可能出问题。
下载解压的步骤很简单:
# 下载工具链
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz
# 解压到 /opt 目录
sudo tar -xf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/
# 配置环境变量(建议写到 ~/.bashrc 里)
export PATH=/opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH
export CROSS_COMPILE=aarch64-none-linux-gnu-
export ARCH=arm64
CROSS_COMPILE 写成了 aarch64-linux-gnu-,结果编译出来的程序在板子上跑不起来。检查一下:aarch64-none-linux-gnu-gcc --version 能正常输出版本号才算成功。
2.2 SDK下载与解压
瑞芯微的SDK通常通过 repo 工具来管理。repo是Google为Android开发的一套Git仓库管理工具,瑞芯微把它拿来管理BSP(板级支持包)了。我第一次用repo的时候也觉得麻烦,但用习惯了会发现,它确实能帮你省掉很多手动拉分支的活。
2.2.1 初始化repo环境
# 安装repo工具
sudo apt-get install -y repo
# 创建一个工作目录,比如 ~/rk3588_sdk
mkdir ~/rk3588_sdk
cd ~/rk3588_sdk
# 初始化repo(这里以RK3588为例)
repo init -u https://github.com/rockchip-linux/manifests -b master -m rk3588_linux.xml
# 同步代码(这一步会下载所有子仓库,时间比较长)
repo sync -c --no-tags -j4
这里有个关键点:-j4 表示用4个线程并行下载。如果你的网络带宽够大,可以改成 -j8 甚至 -j16。但别贪心,线程太多反而容易因为网络抖动导致失败。我一般用 -j4,稳。
2.2.2 解压与目录结构
同步完成后,你会看到类似这样的目录结构:
rk3588_sdk/
├── app/ # 上层应用
├── buildroot/ # Buildroot构建系统
├── device/ # 板级配置
├── docs/ # 文档
├── external/ # 第三方库
├── kernel/ # Linux内核
├── prebuilts/ # 预编译工具
├── rkbin/ # 瑞芯微二进制文件(如ATF、DDR初始化)
├── tools/ # 烧录工具、打包脚本
├── u-boot/ # U-Boot引导程序
└── yocto/ # Yocto构建系统(部分SDK有)
rkbin/ 目录下的文件是瑞芯微提供的闭源二进制,比如ATF(ARM Trusted Firmware)和DDR初始化代码。这些文件不能修改,但必须存在。如果你编译出来的固件启动不了,先检查 rkbin/ 是不是完整。
2.3 Buildroot与Yocto构建系统选择
这个问题我几乎每次培训都会被问到:到底用Buildroot还是Yocto?我的回答是:看你的产品需求。
咱们先看看两者的区别:
| 特性 | Buildroot | Yocto |
|---|---|---|
| 构建速度 | 快(30分钟~1小时) | 慢(2~4小时,首次甚至更久) |
| 定制灵活性 | 中等 | 高(通过Layer和Recipe) |
| 包管理 | 无(编译时静态选择) | 有(支持RPM/DEB/IPK) |
| 学习曲线 | 平缓 | 陡峭 |
| 适用场景 | 嵌入式设备、IoT、简单产品 | 复杂产品、需要长期维护、多平台 |
2.3.1 什么时候选Buildroot?
我个人习惯:原型验证阶段,或者产品功能比较固定的时候,用Buildroot。比如你做一个智能摄像头,功能就是采集视频、编码、上传,不需要频繁更新软件包。Buildroot编译一次,烧进去就能跑,省心。
编译命令也很简单:
cd buildroot/
make rockchip_rk3588_defconfig
make -j4
编译完成后,在 output/images/ 目录下会生成 rootfs.ext4、boot.img 等镜像文件。直接拿去烧录就行。
BR2_PACKAGE_QT5 的某些选项,导致它把整个Qt源码都编译了一遍。所以,用Buildroot时,尽量只选你需要的包,别贪多。
2.3.2 什么时候选Yocto?
Yocto适合那种需要长期维护、频繁更新、或者要支持多种硬件平台的项目。比如你做一款商显主板,客户可能今天要换WiFi模块,明天要加个4G模组。用Yocto的话,你只需要加一个Layer,改几行配置,就能重新生成固件。
Yocto的编译流程稍微复杂一点:
cd yocto/
source oe-init-build-env build-rk3588
bitbake core-image-minimal
第一次编译Yocto,我建议你做好心理准备。它会把整个工具链、交叉编译环境、所有依赖包都从源码编译一遍。我第一次编译RK3588的Yocto,用了将近5个小时。但第二次以后,因为有缓存,就快多了,大概1小时左右。
2.3.3 我的选择建议
如果你还在犹豫,我给你一个简单的判断标准:
- 团队人数少于3人,产品功能固定 → 选Buildroot
- 团队人数多于5人,产品需要持续迭代 → 选Yocto
- 只是学习、做实验 → 选Buildroot,快
嗯,其实没有绝对的对错。我见过有人用Buildroot做出了量产产品,也见过有人用Yocto做原型验证。关键是你熟悉哪个,哪个就能帮你快速出活。
2.4 验证环境是否搭建成功
环境搭好了,怎么知道对不对?写一个最简单的Hello World,交叉编译一下,放到板子上跑。
// hello.c
#include <stdio.h>
int main() {
printf("Hello, RK3588!\n");
return 0;
}
# 交叉编译
aarch64-none-linux-gnu-gcc -o hello hello.c
# 查看文件信息
file hello
# 输出应该是:ELF 64-bit LSB executable, ARM aarch64, ...
把编译好的 hello 文件通过ADB或SCP传到板子上,运行:
./hello
# 输出:Hello, RK3588!
看到这行输出,恭喜你,环境搭建成功了!
好,今天就到这儿。有什么问题,咱们下节课见。