1. U-Boot 概述与环境搭建
大家好,我是你们这趟 U-Boot 调试之旅的向导。咱们先聊聊 U-Boot 到底是什么,以及怎么把它跑起来。
1.1 U-Boot 的历史与作用
U-Boot,全称是 "Universal Boot Loader"。说白了,它就是一块芯片上电后,在操作系统内核跑起来之前,先执行的那一小段程序。它的任务很简单:初始化硬件、加载内核、传递启动参数。
我刚开始做嵌入式那会儿,用的还是 RedBoot 和旧版 U-Boot 1.1.x。那时候的代码风格跟现在差别很大,但核心逻辑没变过。U-Boot 从 2000 年左右发展到现在,已经成了嵌入式 Linux 世界的标准引导程序。为什么大家都选它?因为开源、支持芯片多、社区活跃。
1.2 源码获取
获取 U-Boot 源码,我建议直接从官方仓库拉。别去第三方下载,版本混乱,容易踩坑。
# 克隆主线仓库
git clone https://source.denx.de/u-boot/u-boot.git
# 或者指定版本,比如 v2024.01
git clone -b v2024.01 https://source.denx.de/u-boot/u-boot.git
我个人习惯用 git tag 查看所有版本,选一个长期支持版。为什么?因为主线开发分支可能不稳定,你调试到一半发现 bug,那就尴尬了。
1.3 交叉编译工具链配置
交叉编译,就是在 PC 上编译出能在 ARM、RISC-V 等目标芯片上运行的代码。工具链的选择很关键。
我推荐两种方式:
- Linaro GCC: 老牌工具链,稳定可靠。下载后解压,配置环境变量即可。
- Buildroot / Yocto: 如果你在搭建完整系统,它们会自动下载并配置工具链,省心。
配置环境变量,我一般这样写:
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
嗯,这里要注意:CROSS_COMPILE 后面一定要带短横线,不然编译会报错。我曾经在这个细节上浪费过半小时,后来才发现是少了个横线。
| 架构 | 工具链前缀示例 | 说明 |
|---|---|---|
| ARM 32位 | arm-linux-gnueabihf- | 最常用,支持硬浮点 |
| ARM 64位 | aarch64-linux-gnu- | 用于 Cortex-A53/A72 等 |
| RISC-V 64位 | riscv64-linux-gnu- | 新兴架构,越来越多 |
1.4 最小系统烧录
编译出 U-Boot 镜像后,怎么把它烧到板子上?这里分几种情况。
1.4.1 编译 U-Boot
make distclean
make <你的板子配置>_defconfig
make -j$(nproc)
编译完成后,你会得到 u-boot.bin 或 u-boot.img。具体文件名取决于你的配置。
1.4.2 烧录方式
- SD 卡: 用
dd命令直接写入。注意设备节点别写错,不然你的硬盘就废了。 - NAND / eMMC: 通过厂家提供的烧录工具,比如 Rockchip 的
rkdeveloptool。 - JTAG / 串口: 用于裸板调试,适合开发阶段。
# 以 SD 卡为例
sudo dd if=u-boot.bin of=/dev/sdb bs=1k seek=1
sync
这里的 seek=1 是什么意思?因为 SD 卡第一个扇区是分区表,U-Boot 要写在偏移 1KB 的位置。不同芯片要求不同,务必查手册。
1.5 本章知识体系
下面这张图,帮你理清 U-Boot 环境搭建的完整流程。
这张图把环境搭建的五个步骤串起来了。从源码到串口验证,每一步都有坑,但按流程走,基本不会出大问题。
1.6 小结
这一章我们聊了 U-Boot 是什么、怎么拿源码、怎么配工具链、怎么编译烧录。你想想看,其实核心就三件事:拿代码、配环境、烧进去。后面章节我们会深入 U-Boot 的命令行,那才是真正好玩的地方。