3、U-Boot编译与烧录:U-Boot源码结构、RK平台适配、编译配置、烧录工具使用
U-Boot 是嵌入式 Linux 系统的第一道门槛。说白了,它就是上电后第一个跑起来的程序,负责初始化硬件、加载内核。Rockchip 平台对 U-Boot 做了大量定制,如果你直接拿主线 U-Boot 去编译,大概率是起不来的。这一章,我就带你捋一遍 RK 平台下 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 板子,通常需要改三个地方:
- 设备树(DTS):描述硬件资源,比如 GPIO、I2C、SPI 的引脚复用。
- 板级配置文件:
include/configs/下的头文件,定义内存大小、环境变量分区等。 - 默认配置:
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. 设置工具链(以 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 从源码到运行的完整链路。你想想看,每一步都环环相扣:
从源码到烧录,再到 BootROM 加载,每一步都有坑。但只要你理解了 RK 的分仓结构和打包逻辑,其实并不难。嗯,这一章的内容就到这里。记住,烧录前一定要确认 idbloader.img 和 u-boot.itb 的路径和偏移,这是最常出问题的地方。