3. u-boot基础与编译:u-boot简介、源码获取、配置与编译流程(以ARM架构vexpress-a9为例)

u-boot(Das U-Boot)是嵌入式Linux系统中使用最广泛的引导加载程序(Bootloader),负责初始化硬件、加载操作系统内核并传递启动参数。本章将系统讲解u-boot的核心概念、源码获取方式、针对ARM架构vexpress-a9开发板的配置与编译流程,以及编译生成的关键文件。

3.1 u-boot简介

u-boot是一个开源、多架构支持的引导加载程序,支持ARM、x86、RISC-V、MIPS等多种处理器架构。在嵌入式系统中,u-boot承担以下核心职责:

  • 硬件初始化:设置时钟、内存控制器、串口等外设,使系统达到可用状态。
  • 引导内核:从存储介质(Flash、SD卡、网络等)读取内核映像,跳转到内核入口。
  • 提供命令行接口:允许开发者交互式调试、修改启动参数、烧写固件。
  • 支持多种启动设备:NAND/NOR Flash、MMC/SD卡、USB、网络(TFTP)等。
提示:u-boot的“U”代表“Universal”,强调其跨平台通用性。在QEMU模拟环境中,u-boot作为第一级软件运行,为后续内核加载提供基础。
嵌入式系统启动流程(u-boot角色) ROM BootROM SPL/MLO u-boot Linux Kernel 说明: SPL(Secondary Program Loader)是u-boot的二级加载器,用于初始化内存并加载完整u-boot。 本课程聚焦于绿色节点:u-boot的编译与调试

3.2 源码获取

u-boot源码托管在多个公共仓库中,推荐使用官方Git仓库获取最新稳定版本。以下是常用的获取方式:

获取方式 命令/地址 说明
Git克隆(官方) git clone https://source.denx.de/u-boot/u-boot.git 获取主线最新开发版本
Git克隆(镜像) git clone https://github.com/u-boot/u-boot.git GitHub镜像,国内访问较快
下载稳定版tarball wget https://ftp.denx.de/pub/u-boot/u-boot-2024.01.tar.bz2 指定版本,适合教学环境
课程推荐:本课程使用u-boot 2024.01版本,该版本对vexpress-a9支持完善,且与QEMU 8.x兼容良好。

获取源码后,进入目录查看顶层结构:

cd u-boot-2024.01
ls -F
arch/      board/    configs/   doc/     drivers/   dts/
fs/        include/  lib/       net/     scripts/   tools/
Makefile   Kconfig   README

关键目录说明:

  • arch/:架构相关代码,ARM代码位于 arch/arm/。
  • board/:板级支持包,vexpress-a9相关代码位于 board/armltd/vexpress/。
  • configs/:默认配置文件,命名格式为 <board>_defconfig。
  • dts/:设备树源文件,vexpress-a9的设备树位于 arch/arm/dts/vexpress-v2p-ca9.dts。

3.3 配置与编译流程

u-boot采用Kconfig配置系统(类似Linux内核),配置流程分为两步:配置和编译。以下以vexpress-a9开发板为例,演示完整操作。

3.3.1 配置

vexpress-a9开发板对应的默认配置文件为 vexpress_ca9x4_defconfig。执行配置命令:

make vexpress_ca9x4_defconfig

该命令会读取 configs/vexpress_ca9x4_defconfig 文件,生成 .config 配置文件。如需自定义配置,可运行:

make menuconfig

menuconfig提供图形化界面,允许开发者调整驱动、命令、文件系统等选项。

注意:配置前需确保已安装交叉编译工具链。本课程使用 arm-linux-gnueabihf- 工具链,可通过 apt install gcc-arm-linux-gnueabihf 安装。
u-boot配置与编译流程(vexpress-a9) 步骤1:获取源码 git clone / wget 步骤2:配置 make xxx_defconfig 步骤3:编译 make -j$(nproc) 中间产物: .config(配置文件) → autoconf.mk(自动生成的Makefile包含) → include/configs/*.h(板级头文件) 编译输出关键文件 u-boot.bin — 纯二进制映像,可直接烧录 u-boot.elf — ELF格式,含调试符号,用于GDB调试

3.3.2 编译

配置完成后,执行编译命令。需指定交叉编译工具链前缀:

export CROSS_COMPILE=arm-linux-gnueabihf-
make -j$(nproc)

编译过程会依次执行:编译设备树、编译架构代码、编译驱动、链接生成最终映像。成功编译后,终端输出类似:

  LD      u-boot
  OBJCOPY u-boot.srec
  OBJCOPY u-boot.bin
  SYM     u-boot.sym
  CFG     u-boot.cfg
  MKIMAGE u-boot.img
关键编译变量:
CROSS_COMPILE:指定交叉编译工具链前缀,必须与目标架构匹配。
ARCH:指定目标架构,ARM架构设置为 ARCH=arm(通常由defconfig自动设置)。
-j$(nproc):并行编译,加速构建过程。

3.4 生成的关键文件

编译完成后,在源码根目录下生成多个重要文件。下表列出核心输出及其用途:

文件名 格式 大小(典型值) 用途
u-boot.bin 纯二进制 ~500KB 可直接烧录到Flash或由QEMU加载的原始映像
u-boot.elf ELF ~2MB 包含调试符号,用于GDB调试、QEMU -kernel加载
u-boot ELF(无扩展名) ~2MB 链接生成的原始ELF文件,与u-boot.elf等价
u-boot.img uImage格式 ~500KB 包含u-boot头部的映像,用于某些启动方式
u-boot.srec Motorola S-record ~1.5MB ASCII格式的映像,用于串口烧录
u-boot.sym 符号表 ~100KB 函数符号地址映射,辅助调试

3.4.1 u-boot.bin 与 u-boot.elf 的差异

这两个文件是调试过程中最常使用的,理解其差异至关重要:

  • u-boot.bin:去除了所有调试信息和ELF头部,是纯粹的机器码映像。QEMU加载时直接将其内容放到指定内存地址,不解析任何元数据。
  • u-boot.elf:保留ELF文件格式,包含段表、符号表、调试信息(如DWARF)。QEMU的 -kernel 选项可以解析ELF文件,自动将各段加载到正确地址,并读取入口点。
调试建议:在QEMU中联合调试时,使用 -kernel u-boot.elf 加载,配合GDB的 symbol-file u-boot.elf 加载符号,可实现源码级调试。

3.4.2 验证编译产物

使用以下命令检查生成文件的格式和入口地址:

# 查看u-boot.elf的入口地址
arm-linux-gnueabihf-readelf -h u-boot.elf | grep Entry

# 查看u-boot.bin的起始内容(前16字节)
hexdump -C u-boot.bin | head -2

# 查看符号表,定位start_code
arm-linux-gnueabihf-nm u-boot.elf | grep start_code

典型输出示例:

  Entry point address:               0x60000000
  00000000  13 00 00 ea 14 f0 9f e5  14 f0 9f e5 14 f0 9f e5  |................|
  60000000 T _start
  60000020 T _main

入口地址 0x60000000 对应vexpress-a9开发板的DDR起始地址,u-boot被编译为从该地址运行。

3.5 常见编译问题与解决

问题现象 可能原因 解决方案
arm-linux-gnueabihf-gcc: command not found 交叉编译工具链未安装 sudo apt install gcc-arm-linux-gnueabihf
*** Your GCC is too old 主机GCC版本过低 升级GCC或使用容器化编译环境
undefined reference to `__aeabi_*' 工具链与架构不匹配 确认使用arm-linux-gnueabihf而非arm-linux-gnueabi
make: *** No rule to make target 'vexpress_ca9x4_defconfig' 拼写错误或版本不支持 执行 make help 查看支持的defconfig列表
重要:vexpress-a9的u-boot配置要求主机Python版本≥3.6,否则设备树编译可能失败。使用 python3 --version 检查版本。

3.6 本章小结

本章完成了u-boot的基础知识学习,包括:

  • u-boot在嵌入式启动流程中的核心地位
  • 从官方仓库获取源码的多种方式
  • 针对vexpress-a9开发板的配置与编译完整流程
  • 编译生成的关键文件(u-boot.bin、u-boot.elf等)及其用途
  • 常见编译问题的排查方法