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,兼容性最好。

工具链三要素:前缀(aarch64-none-linux-gnu-)、sysroot(目标根文件系统头文件与库)、目标架构(aarch64)。三者必须匹配,缺一不可。

二、方法流程:从零搭建四步走

  1. 安装主机依赖:build-essential、bc、bison、flex、libssl-dev、libncurses-dev、device-tree-compiler、python3、rsync、cpio。
  2. 部署交叉工具链:下载并解压到 /opt/toolchain,将 bin 目录加入 PATH。
  3. 获取源码:U-Boot、Kernel、ATF(ARM Trusted Firmware)与 rkbin 四部分,版本需与 RK3399 匹配。
  4. 配置环境变量:导出 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.07aarch64-none-linux-gnu-gcc/ld/objcopy
U-Bootrk3399 分支rk3399_defconfigu-boot.bin、trust.img
Kernellinux-4.4-rk3399-linuxrockchip_defconfigImage、rk3399-evb.dtb
ATFmasterPLAT=rk3399bl31.elf
rkbinmasterRK3399 固件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,避免“我这里能编译,你那里报错”的经典问题。
RK3399 交叉编译环境搭建流程 x86_64 主机 (Host) Ubuntu 20.04/22.04 build-essential / bc / bison 交叉工具链 aarch64-none-linux-gnu- 环境变量 ARCH / CROSS_COMPILE / PATH 源码仓库 U-Boot / Kernel / ATF / rkbin 编译验证 编译产物 u-boot.bin trust.img Image rk3399-evb.dtb bl31.elf ATF 固件 显示驱动 .ko vop / dsi / edp RK3399 目标板 (Target) BootROM 加载 ddr.bin / bl31 U-Boot 引导内核与 DTB Linux Kernel VOP / DSI / HDMI 驱动 FrameBuffer /dev/fb0 显示输出 屏幕点亮验证 关键:工具链版本与内核源码匹配 → 环境变量正确导出 → 编译产物完整 → 目标板启动验证