U-Boot 源码获取与编译——适配 ARM 开发板全程实操
U-Boot 源码获取与编译——适配 ARM 开发板全程实操
本文由黒漂技术佬原创,首发于 CSDN,转载请注明出处。
一、引言
上一篇文章咱们把嵌入式开机流程捋了一遍,知道了 U-Boot 在整个启动链中扮演什么角色。但光看理论不过瘾,今天直接上手——从源码下载到交叉编译,再到生成能在 ARM 开发板上跑起来的u-boot.bin,一步不漏。不管你用的是 BeagleBone Black、树莓派、imx6ull,还是全志 H3/H5,流程都是相通的。
二、源码获取——三条路任你选
2.1 官方主线仓库(推荐)
U-Boot 的官方代码托管在 GitHub,主线仓库更新频繁,每个季度发一个稳定版本。
# 克隆主线仓库(体积较大,约 1GB+)gitclone https://github.com/u-boot/u-boot.gitcdu-boot# 切换到最新稳定版本(以 v2024.01 为例)gitcheckout v2024.01-bmy_uboot_dev如果你因为网络问题无法直接访问 GitHub,可以试试国内的镜像源。
2.2 芯片厂商 BSP 分支
绝大多数 SoC 厂商会基于主线 U-Boot 维护一个 BSP(Board Support Package)分支,打包了定制驱动和外设支持。
| 厂商 | 仓库地址示例 |
|---|---|
| NXP (i.MX) | https://source.codeaurora.org/external/imx/uboot-imx |
| TI (Sitara) | https://git.ti.com/cgit/ti-u-boot/ti-u-boot |
| 全志 (Allwinner) | https://github.com/linux-sunxi/u-boot-sunxi |
| Xilinx | https://github.com/Xilinx/u-boot-xlnx |
| Rockchip | https://github.com/rockchip-linux/u-boot |
选哪个好?如果你是做产品开发,用厂商 BSP 更稳妥,驱动适配到位。如果是学习研究,主线 U-Boot 紧跟社区,架构更规范。
2.3 直接下载压缩包
不想折腾 git 的话,直接去 ftp.denx.de/pub/u-boot 下载 tar 包就行。
wgetftp://ftp.denx.de/pub/u-boot/u-boot-2024.01.tar.bz2tar-xjfu-boot-2024.01.tar.bz2cdu-boot-2024.01三、U-Boot 源码目录结构一览
解压 / 克隆后,先别急着编译,把目录结构搞清楚,后面配置和调试才不迷路。
u-boot/ ├── arch/ # 架构相关代码 (arm/, mips/, riscv/, x86/...) │ └── arm/ │ ├── cpu/ # 各 ARM 核的实现 │ ├── dts/ # 设备树源文件 │ ├── mach-xxx/ # 各 SoC 平台的驱动代码 │ └── lib/ # ARM 架构专用库 ├── board/ # 开发板级配置和初始化代码 │ └── vendor/board_name/ ├── cmd/ # U-Boot 命令实现源代码 ├── common/ # 通用功能代码 ├── configs/ # 各板卡的默认配置文件 (defconfig) ├── doc/ # 文档 ├── drivers/ # 外设驱动 (net/, mmc/, spi/, usb/...) ├── fs/ # 文件系统支持 (ext4/, fat/, ubifs/...) ├── include/ # 头文件 │ └── configs/ # 板卡配置头文件 (逐步废弃,转向 Kconfig) ├── lib/ # 通用库函数 ├── net/ # 网络协议栈 ├── tools/ # 辅助工具 (mkimage 等) ├── Kconfig # 顶层配置菜单 ├── Makefile # 顶层 Makefile └── .config # 编译时生成的配置文件重点记住:configs/目录下的xxx_defconfig是你选择目标板卡的入口,后面我们会频繁用到。
四、交叉编译环境搭建
4.1 什么是交叉编译?
简单说,交叉编译就是在一个平台上编译出另一个平台能运行的二进制文件。你的开发机通常是 x86_64,而目标板是 ARM(armv7l / aarch64),这时候就需要交叉编译工具链。
4.2 安装 ARM 交叉编译工具链
方法一:Linux 发行版包管理器安装
# Ubuntu/Debian: 安装 32 位 ARM 工具链sudoaptinstallgcc-arm-linux-gnueabihf# 安装 64 位 ARM 工具链 (ARMv8/AArch64)sudoaptinstallgcc-aarch64-linux-gnu方法二:从 ARM 官网下载预编译工具链
# 下载 ARM GNU Toolchainwgethttps://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/\arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xztar-xfarm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xzexportPATH=$PWD/arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-linux-gnueabihf/bin:$PATH方法三:Linaro 工具链(兼容性好,很多老项目在用)
wgethttps://releases.linaro.org/components/toolchain/binaries/latest-7/\arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz4.3 验证工具链
arm-linux-gnueabihf-gcc--version# 输出应类似:arm-linux-gnueabihf-gcc (GNU Toolchain...) 13.2.1五、配置与编译 U-Boot
5.1 设置环境变量
exportARCH=armexportCROSS_COMPILE=arm-linux-gnueabihf-注意CROSS_COMPILE后面的连字符-不能省略,Makefile 会用这个前缀去拼接gcc、ld等工具名。
5.2 选择目标板卡配置
# 查看所有可用的板卡配置lsconfigs/|head-20# 以 BeagleBone Black 为例makeam335x_evm_defconfigmake xxx_defconfig的作用是将configs/xxx_defconfig中的配置项写入项目根目录的.config文件。这个.config文件就是最终的编译配置清单。
5.3 图形化微调配置(可选)
makemenuconfigmenuconfig会打开一个基于 ncurses 的图形配置界面,你可以在这里增删驱动、调整参数。需要安装libncurses-dev。对于学习阶段,直接用默认配置就行。
5.4 编译
# 多线程编译,-j 后面跟 CPU 核心数make-j$(nproc)编译成功后,你会看到以下几个重要产物:
| 产物文件 | 说明 |
|---|---|
u-boot.bin | 原始二进制,可直接烧录 |
u-boot.img | 带 U-Boot 头部的镜像 |
u-boot-nodtb.bin | 不含设备树的纯二进制 |
u-boot.dtb | 编译后的设备树文件 |
MLO/SPL | 第一级 Bootloader(少数平台) |
spl/u-boot-spl.bin | SPL 二进制 |
5.5 编译结果验证
fileu-boot.bin# 输出:u-boot.bin: datals-lhu-boot.bin# 查看文件大小六、常见编译问题与解决
问题1:arm-linux-gnueabihf-gcc: command not found
原因:工具链未安装或路径未添加到 PATH。
解决:检查安装和 PATH 环境变量。
问题2:make: *** No rule to make target 'xxx_defconfig'
原因:配置文件名写错或该板卡不支持。
解决:先去configs/目录确认准确的文件名。
问题3:编译报undefined reference to...
原因:某个依赖的驱动未选择。
解决:用make menuconfig检查相关选项是否启用。
七、总结
本文带你完成了 U-Boot 的全流程编译:
- 从官方仓库或厂商 BSP 获取源码。
- 理解目录结构,知道关键代码在哪。
- 安装交叉编译工具链并验证。
- 根据目标板卡选择和配置
defconfig。 - 编译生成
u-boot.bin等产物。
编译通过只是第一步,接下来我们要把 U-Boot 烧到板子上,用串口连上去,面对那个熟悉的=>提示符,开始用命令操作它。下一篇文章,我们来玩转 U-Boot 的基础指令!