2. 开发环境搭建
RK3399 是 ARM64 架构的双核 Cortex-A72 + 四核 Cortex-A53 处理器,其显示子系统涉及 VOP、MIPI DSI、eDP、HDMI 等多个控制器。要在 x86_64 主机上编译出能在 RK3399 上运行的 U-Boot、内核与显示驱动,第一步必须建立一套稳定、可复现的交叉编译环境。本章围绕工具链选择、源码获取、环境变量配置与首次编译验证展开,为后续 FrameBuffer 驱动移植打好地基。
一、核心原理:为什么必须用交叉编译
主机(Host)是 x86_64 的 Ubuntu,目标机(Target)是 aarch64 的 RK3399,两者指令集不同。交叉编译工具链提供 aarch64-linux-gnu-gcc、ld、objcopy 等工具,在主机上生成 ARM64 可执行文件。工具链的 sysroot 决定了链接时使用的 C 库版本,必须与目标机根文件系统一致,否则会出现 GLIBC_2.xx not found 或内核模块加载失败。
对于内核与 U-Boot,推荐使用 Linaro 或 ARM 官方发布的 GNU Toolchain,而不是发行版自带的 gcc-aarch64-linux-gnu,因为后者版本更新频繁,容易与旧内核源码产生编译告警甚至错误。Rockchip 官方 SDK 通常配套 gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu,兼容性最好。
二、方法流程:从零搭建四步走
- 安装主机依赖:
build-essential、bc、bison、flex、libssl-dev、libncurses-dev、device-tree-compiler、python3、rsync、cpio。 - 部署交叉工具链:下载并解压到
/opt/toolchain,将bin目录加入PATH。 - 获取源码:U-Boot、Kernel、ATF(ARM Trusted Firmware)与 rkbin 四部分,版本需与 RK3399 匹配。
- 配置环境变量:导出
ARCH、CROSS_COMPILE,并验证工具链可用。
下面给出可直接执行的命令序列:
sudo apt update
sudo apt install -y build-essential bc bison flex libssl-dev \
libncurses-dev device-tree-compiler python3 rsync cpio
# 部署工具链
sudo mkdir -p /opt/toolchain
sudo tar -xf gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/toolchain
export PATH=/opt/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH
# 验证
aarch64-none-linux-gnu-gcc -v
源码获取建议使用 Rockchip 官方 GitHub 或 Linux SDK 发布包,避免使用过新的 mainline 内核导致 VOP 驱动缺失:
git clone -b linux-4.4-rk3399-linux https://github.com/rockchip-linux/kernel.git
git clone -b rk3399 https://github.com/rockchip-linux/u-boot.git
git clone https://github.com/ARM-software/arm-trusted-firmware.git
三、环境变量与编译验证
每次打开新终端都需要重新导出变量,建议写入 ~/.bashrc 或使用脚本 envsetup.sh 统一管理:
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-
export PATH=/opt/toolchain/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin:$PATH
内核编译验证:
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- rockchip_defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- rk3399-evb.dtb
make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- -j$(nproc) Image
若输出 arch/arm64/boot/Image 且无报错,说明工具链与内核源码匹配成功。U-Boot 编译同理,使用 make rk3399_defconfig 后执行 make,最终生成 u-boot.bin 与 trust.img。
四、关键配置对照表
| 组件 | 版本/分支 | 关键配置 | 产物 |
|---|---|---|---|
| 交叉工具链 | gcc-arm-10.3-2021.07 | aarch64-none-linux-gnu- | gcc/ld/objcopy |
| U-Boot | rk3399 分支 | rk3399_defconfig | u-boot.bin、trust.img |
| Kernel | linux-4.4-rk3399-linux | rockchip_defconfig | Image、rk3399-evb.dtb |
| ATF | master | PLAT=rk3399 | bl31.elf |
| rkbin | master | RK3399 固件 | ddr/bl31 二进制 |
五、案例场景与常见误区
场景:某工程师使用 Ubuntu 22.04 自带的 gcc-aarch64-linux-gnu 编译 RK3399 内核,出现大量 unrecognized command-line option '-mgeneral-regs-only' 报错。原因是发行版 GCC 版本过高,与 4.4 内核的编译选项不兼容。切换为 Linaro 10.3 工具链后问题消失。
误区一:只设置 CROSS_COMPILE 而忘记 ARCH=arm64,导致内核按 x86 配置编译,生成错误架构的 Image。
误区二:工具链路径未加入 PATH,编译时提示 aarch64-none-linux-gnu-gcc: not found,实际是环境变量未生效。
误区三:U-Boot 与内核使用不同版本工具链,导致 ATF 与 U-Boot 链接时 ABI 不一致,启动卡在 BL31 阶段。
envsetup.sh 中,团队协作时统一 source,避免“我这里能编译,你那里报错”的经典问题。