3、U-Boot源码获取与编译:从官方仓库获取源码、配置默认板型、编译流程解析

好,咱们进入正题。这一章要解决的是「怎么把U-Boot弄到手,并且让它跑起来」的问题。

很多新手上来就卡在这一步——源码下载了,make一敲,报一堆错。别急,我带你一步步走通。

3.1 从官方仓库获取源码

U-Boot的官方仓库在 denx.de 的Git服务器上。我个人习惯用 git://git.denx.de/u-boot.git 这个地址。

克隆命令很简单:

git clone git://git.denx.de/u-boot.git
cd u-boot

嗯,这里要注意。如果你在公司内网,或者网络环境不太好,建议用 https:// 协议:

git clone https://git.denx.de/u-boot.git

为什么?因为有些防火墙会封掉git协议端口。我在项目里遇到过,明明网络通着,就是克隆不下来,换成https秒搞定。

克隆完成后,你会看到一堆分支和标签。我个人建议先切到一个稳定的发布版本,比如 v2024.01:

git checkout v2024.01

为什么要用发布版?因为主线上的代码可能正在开发中,说不定哪天就编译不过了。你想想看,做产品移植,稳定第一。

3.2 配置默认板型

源码拿到了,接下来要配置。U-Boot支持几百种开发板,每种板子都有自己的配置。

先看看你的板子有没有现成的支持:

ls configs/ | grep <你的芯片型号>

比如我用的是 stm32mp157,就会看到:

stm32mp15_defconfig
stm32mp15_basic_defconfig
stm32mp15_trusted_defconfig

配置命令很简单:

make stm32mp15_defconfig

执行后,U-Boot会生成 .config 文件。这个文件里记录了所有配置选项,说白了就是你的板子「长什么样」。

核心概念: defconfig 是板级配置的「模板」,.config 是最终生效的「实际配置」。两者之间通过 make menuconfig 可以微调。

如果你需要调整配置,比如打开某个驱动:

make menuconfig

这个界面是图形化的,用方向键操作。我曾经在调一个网卡驱动时,就是在这里把 CONFIG_ETH_DESIGNWARE 勾上,才让网络跑起来的。

3.3 编译流程解析

配置好了,编译就简单了:

make -j$(nproc)

-j$(nproc) 表示用所有CPU核心并行编译,能快不少。我第一次编译时没加这个参数,等了快10分钟,后来同事提醒才加上,速度直接翻倍。

编译完成后,你会得到几个关键文件:

文件 说明
u-boot.bin 纯二进制镜像,直接烧写到Flash
u-boot.img 带U-Boot头部的镜像,用于网络启动
u-boot-spl.bin SPL(第一阶段引导),用于启动主U-Boot
u-boot.dtb 设备树文件,描述硬件信息

这里有个坑:如果你的板子需要SPL,那 u-boot-spl.bin 才是烧写到Flash的第一个文件。主U-Boot由SPL加载到内存中运行。

注意: 编译前一定要确认交叉编译工具链。比如ARM板子,需要设置 CROSS_COMPILE=arm-linux-gnueabihf-。我见过有人用x86的gcc编译ARM代码,结果一堆「未定义的指令」错误。

3.4 编译流程的底层逻辑

你可能好奇,make 背后到底干了什么?我画了一张图,帮你理清思路:

U-Boot编译流程 1. 配置阶段 make xxx_defconfig 2. 编译阶段 make -j$(nproc) 3. 链接阶段 生成u-boot.bin 各阶段具体工作: • 配置阶段:读取 defconfig → 生成 .config → 生成 autoconf.mk • 编译阶段:编译所有 .c/.S 文件 → 生成 .o 目标文件 • 链接阶段:链接所有 .o 文件 → 生成 u-boot 可执行文件 • 后处理阶段:生成 u-boot.bin / u-boot.img / u-boot-spl.bin 注:SPL和主U-Boot是分开编译的,SPL先编译,主U-Boot后编译

这张图展示了编译的三个主要阶段。实际执行时,Makefile会递归调用子目录的Makefile,一层层编译。

如果你想知道具体编译了哪些文件,可以加 V=1 参数:

make V=1 -j$(nproc)

这样会打印出每条编译命令。我在调试编译错误时,经常用这个参数来定位问题。

3.5 常见问题与避坑

小技巧: 如果你改了配置,想重新编译,记得先 make clean 清理旧文件。不然可能残留旧的 .o 文件,导致奇怪的问题。

我曾经犯过一个错误:改了设备树,但没重新编译,结果板子启动时设备树还是旧的,外设全没初始化。折腾了半天才发现是缓存问题。

另外,如果你用的是 git 管理的源码,建议每次编译前先 git status 看看有没有未提交的修改。这样出了问题也好回退。

嗯,这一章的内容就到这里。源码获取、配置、编译,这三步走通了,你的U-Boot移植之路就迈出了最关键的一步。

可可精品资料库