3. Rockchip平台配置与编译:从defconfig到最终镜像

好,咱们进入正题。这一章要聊的是Rockchip平台U-Boot的配置与编译流程。说白了,就是怎么把源码变成能烧到板子上的二进制文件。我刚开始接触Rockchip时,也被那一堆配置文件搞得晕头转向——什么defconfig、menuconfig、itb、idbloader,每个都是坑。今天咱们一个一个捋清楚。

3.1 defconfig选择:找到你的“板子身份证”

每个Rockchip芯片都有对应的默认配置,存放在 configs/ 目录下。命名规则很直观:芯片型号_板卡型号_defconfig。比如 rk3399_defconfig 就是RK3399芯片的通用配置。

核心原则:先选最接近你硬件的defconfig,再微调。不要从零开始写配置,那是自找麻烦。

我列几个常见的Rockchip defconfig,方便你对照:

芯片型号 常用defconfig 适用场景
RK3399 rk3399_defconfig Firefly、Rock Pi 4等通用板
RK3328 rk3328_defconfig 电视盒子、NAS主板
RK3288 rk3288_defconfig 老款开发板、广告机
RK3568 rk3568_defconfig 新一代AIoT设备

我的习惯:拿到一块新板子,先看原理图确认主控型号,然后去 configs/ 目录下 ls | grep 芯片型号,看看有哪些现成配置。曾经有个项目用了RK3399Pro,我直接用了rk3399_defconfig,结果NPU驱动没开——后来才发现有专门的 rk3399pro_defconfig。嗯,这种低级错误犯一次就够了。

3.2 menuconfig配置:图形化的“手术台”

defconfig只是起点。实际项目中,你需要根据硬件裁剪功能。比如你的板子没有以太网,那就关掉网络驱动;或者你要启用某个SPI闪存,得手动选上对应的驱动。

这时候就要用 make menuconfig 了。它提供一个基于ncurses的图形界面,操作起来很直观:

# 先加载默认配置
make rk3399_defconfig

# 进入图形化配置界面
make menuconfig

进去之后你会看到这样的结构:

  • General setup — 通用选项,比如版本号、命令行参数
  • ARM architecture — ARM相关配置,包括SoC选择、DDR初始化
  • Boot media — 启动介质,比如SD卡、eMMC、SPI Flash
  • Device Drivers — 外设驱动,USB、GMAC、I2C、SPI等
  • Rockchip specific options — Rockchip特有功能,比如ATF集成、TEE支持

注意:menuconfig里改完配置后,保存会生成 .config 文件。但千万别直接提交这个文件到git!正确的做法是用 make savedefconfig 生成精简的defconfig,再重命名提交。

我曾经在调试一块RK3328板子时,为了测试某个USB功能,在menuconfig里翻来覆去改了好几次。每次都要重新编译,折腾了大半天。后来学乖了——先把所有要改的选项列个清单,一次性改完再编译。你想想看,编译一次U-Boot少说一两分钟,反复改反复编,时间全浪费了。

3.3 make命令详解:不只是“make”那么简单

配置搞定后,就是编译。但 make 命令在U-Boot里有很多变种,每个都有特定用途。我整理了一份速查表:

命令 作用 常用场景
make 完整编译,生成所有目标 日常开发,验证整体编译
make -j$(nproc) 多线程编译,加快速度 多核机器上必用
make u-boot.itb 只生成u-boot.itb 调试ATF或SPL时
make idbloader.img 只生成idbloader.img 单独更新一级引导
make clean 清理编译产物 换配置前必须做
make distclean 彻底清理,包括配置文件 从零开始重新配置

我的建议:日常开发用 make -j$(nproc) 就行。但如果改了 arch/arm/mach-rockchip/ 下的底层代码,最好先用 make clean 再编译,否则可能出现缓存导致的问题。我踩过这个坑——改了DDR时序参数,没clean直接编,烧进去板子起不来,查了半天发现是旧的目标文件在作祟。

3.4 编译产物分析:u-boot.itb 和 idbloader.img

编译完成后,在 当前目录 下会生成一堆文件。对于Rockchip平台,最重要的两个是 u-boot.itb 和 idbloader.img。它们到底是什么?我画个图你就明白了。

Rockchip 启动流程与编译产物对应关系 BootROM 芯片内部固化 idbloader.img SPL + DDR 初始化 u-boot.itb ATF + U-Boot proper idbloader.img 内部结构 组成: • TPL (tiny program loader) — 初始化DDR • SPL (secondary program loader) — 加载u-boot.itb • 合并方式:cat tpl.bin spl.bin > idbloader.img u-boot.itb 内部结构 组成: • ATF (ARM Trusted Firmware) — 安全监控 • U-Boot proper — 完整引导程序 • 打包方式:mkimage -f rk3399.its u-boot.itb 烧录位置(以SD卡为例) SD卡扇区布局: • 扇区 0-63 (0-32KB) : 分区表 / MBR • 扇区 64-2111 (32KB-1MB) : idbloader.img • 扇区 2112-7167 (1MB-3.5MB) : u-boot.itb • 扇区 7168+ : 内核 / 文件系统 / 用户数据 注:具体偏移量因芯片型号而异,RK3399常用0x40扇区(32KB)起始

简单来说:

  • idbloader.img — 一级引导。包含TPL和SPL,负责初始化DDR、时钟,然后加载u-boot.itb。它是Rockchip特有的格式,由 tools/mkimage 工具生成。
  • u-boot.itb — 二级引导。是一个FIT (Flattened Image Tree) 镜像,里面打包了ATF和U-Boot proper。ATF负责安全监控和PSCI,U-Boot proper才是我们熟悉的那个引导菜单。

调试技巧:如果板子完全没反应(串口无输出),问题大概率在idbloader.img。如果idbloader跑起来了但卡在“Starting kernel...”之前,那问题在u-boot.itb。我一般会先确认idbloader能否正常打印,再逐步排查u-boot.itb。这个思路帮我省了不少时间。

3.5 实战:完整编译一次RK3399 U-Boot

光说不练假把式。咱们走一遍完整流程:

# 1. 清理环境
make distclean

# 2. 选择配置
make rk3399_defconfig

# 3. 如果需要,进入menuconfig微调
make menuconfig

# 4. 保存精简配置(可选,用于版本管理)
make savedefconfig
cp defconfig configs/my_rk3399_defconfig

# 5. 编译(4线程)
make -j4

# 6. 检查产物
ls -lh u-boot.itb idbloader.img

编译完成后,你会看到类似这样的输出:

-rw-rw-r-- 1 user user 1.1M Mar 15 10:30 u-boot.itb
-rw-rw-r-- 1 user user 380K Mar 15 10:30 idbloader.img

常见问题:如果你遇到“No rule to make target 'idbloader.img'”的错误,说明你的defconfig没有启用Rockchip特有的构建规则。检查 CONFIG_ROCKCHIP=y 和 CONFIG_SPL=y 是否开启。我刚开始移植时,就因为漏了 CONFIG_SPL_FRAMEWORK,折腾了一下午才找到原因。