3、U-Boot编译与烧录:U-Boot源码结构、RK平台适配、编译配置、烧录工具使用

U-Boot 是嵌入式 Linux 系统的第一道门槛。说白了,它就是上电后第一个跑起来的程序,负责初始化硬件、加载内核。Rockchip 平台对 U-Boot 做了大量定制,如果你直接拿主线 U-Boot 去编译,大概率是起不来的。这一章,我就带你捋一遍 RK 平台下 U-Boot 的源码结构、适配方法、编译配置和烧录工具的使用。

本章核心目标: 理解 Rockchip U-Boot 的分仓结构,掌握从源码到烧录的完整链路。

3.1 U-Boot 源码结构:RK 的分仓哲学

Rockchip 官方维护的 U-Boot 并不是一个单一的仓库。我个人习惯把它分成三个层次:

  • 官方 U-Boot 主线:denx.de 的通用版本,支持基础框架。
  • Rockchip 官方 BSP:在主线基础上,增加了 RK 全系列 SoC 的板级支持包。
  • 芯片级补丁:针对具体型号(如 RK3588、RK3568)的 DDR 初始化、时钟、电源管理等代码。

你从 Rockchip 官方 SDK 拉下来的 U-Boot 目录,结构大致如下:

u-boot/
├── arch/                # 架构相关代码
│   └── arm/
│       ├── mach-rockchip/   # RK 平台核心代码
│       ├── dts/             # 设备树文件
│       └── include/         # 头文件
├── board/               # 板级支持
│   └── rockchip/        # 各开发板配置
├── configs/             # 默认配置文件
│   └── rockchip_*.defconfig
├── drivers/             # 驱动
│   ├── clk/rockchip/
│   ├── mmc/rockchip_sdmmc.c
│   └── pinctrl/rockchip/
├── include/configs/     # 板级配置头文件
└── tools/               # 烧录与打包工具
    └── rk_tools/        # RK 专属工具链

嗯,这里要注意 arch/arm/mach-rockchip 这个目录。它包含了 SoC 级别的初始化代码,比如 DDR 训练、时钟树配置。我在项目中遇到过,如果 DDR 参数配错了,U-Boot 根本跑不到打印信息,直接死机。所以这块代码,非必要不要动。

3.2 RK 平台适配:从芯片到板卡

适配一块新的 RK 板子,通常需要改三个地方:

  1. 设备树(DTS):描述硬件资源,比如 GPIO、I2C、SPI 的引脚复用。
  2. 板级配置文件:include/configs/ 下的头文件,定义内存大小、环境变量分区等。
  3. 默认配置:configs/ 下的 rockchip_xxx_defconfig,决定哪些驱动被编译进去。

举个例子,RK3588 EVB 的适配流程:

文件 作用 常见修改点
arch/arm/dts/rk3588-evb.dts 设备树源文件 修改网卡型号、LCD 时序、USB 端口
include/configs/rk3588_common.h 公共配置头文件 调整 CONFIG_SYS_TEXT_BASE 加载地址
configs/evb-rk3588_defconfig 默认配置 使能 CONFIG_ETH_DESIGNWARE 等驱动
我的经验: 设备树里的 pinctrl 节点最容易出错。我曾经因为一个 GPIO 的 pull-up 没配,导致 eMMC 识别失败,查了整整两天。建议先用 Rockchip 官方的 dts 模板,再逐步裁剪。

3.3 编译配置:三步走流程

编译 RK 的 U-Boot 其实不复杂。我习惯用以下三步:

  1. 设置交叉编译工具链
  2. 加载默认配置
  3. 执行编译

具体命令如下:

# 1. 设置工具链(以 RK3588 为例)
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64

# 2. 加载默认配置
make evb-rk3588_defconfig

# 3. 编译
make -j$(nproc)

编译完成后,你会得到 u-boot.bin 和 u-boot.dtb。但注意,RK 平台不能直接烧录 u-boot.bin,它需要经过打包。

避坑指南: 我曾经直接用 dd 命令把 u-boot.bin 写到 eMMC 的起始扇区,结果板子变砖。后来才知道,RK 的 U-Boot 需要加上头部信息(IDB block),否则 BootROM 不认。

3.4 烧录工具使用:RK 的专属武器

Rockchip 提供了两套烧录方案:

  • Loader 模式烧录:通过 USB 连接,使用 rkdeveloptool 或 Windows 下的 Rockchip Flash Tool。
  • SD 卡启动烧录:把 U-Boot 写入 SD 卡,从 SD 卡启动后再烧录到 eMMC。

我个人更推荐 rkdeveloptool,因为它跨平台,而且可以精确控制烧录位置。基本用法:

# 1. 进入 Loader 模式(按住 RECOVERY 键上电)
# 2. 检测设备
sudo rkdeveloptool ld

# 3. 烧录 U-Boot(注意:不是 u-boot.bin,而是打包后的 idbloader.img)
sudo rkdeveloptool db idbloader.img
sudo rkdeveloptool wl 0x4000 u-boot.itb

# 4. 重启
sudo rkdeveloptool rd

这里解释一下 idbloader.img 和 u-boot.itb 的区别:

文件 内容 烧录位置
idbloader.img 一级 BootROM + DDR 初始化 + TPL 0x0(起始扇区)
u-boot.itb U-Boot 主程序 + 设备树 + FIT 结构 0x4000(偏移 16MB)
关键点: idbloader.img 必须放在 0 扇区,u-boot.itb 放在 0x4000 扇区。位置错了,板子就起不来。

3.5 知识体系:U-Boot 编译与烧录全流程

下面这张图,是我自己总结的 RK 平台 U-Boot 从源码到运行的完整链路。你想想看,每一步都环环相扣:

Rockchip U-Boot 编译与烧录流程 RK U-Boot 编译与烧录全流程 U-Boot 源码 make xxx_defconfig make -j$(nproc) 打包 idbloader.img 打包 u-boot.itb rkdeveloptool 烧录 BootROM 加载执行 注意: idbloader.img 烧录到 0x0 u-boot.itb 烧录到 0x4000 位置错误 → 变砖

从源码到烧录,再到 BootROM 加载,每一步都有坑。但只要你理解了 RK 的分仓结构和打包逻辑,其实并不难。嗯,这一章的内容就到这里。记住,烧录前一定要确认 idbloader.img 和 u-boot.itb 的路径和偏移,这是最常出问题的地方。