2. 搭建U-Boot交叉编译环境

任务目标

本案例要求你掌握U-Boot源码的顶层目录组织方式,能够准确说出每个核心目录的职责,并建立从目录到编译流程的映射关系。完成本案例后,你应能独立阅读任意版本的U-Boot源码树,快速定位与板级配置、驱动、命令、启动流程相关的文件。

环境准备

获取U-Boot源码(以v2024.01为例):

git clone https://github.com/u-boot/u-boot.git
cd u-boot
git checkout v2024.01

顶层目录结构与功能

执行 ls -F 查看顶层目录,核心目录及其职责如下表所示:

目录/文件功能定位关键内容示例
arch/体系结构相关代码,按CPU架构分子目录arch/arm/、arch/riscv/;含start.S启动汇编、dts/设备树
board/具体开发板相关代码,按厂商/板名组织board/raspberrypi/、board/rockchip/;含板级初始化board.c
common/与架构无关的核心命令与启动逻辑main.c(主循环)、command.c(命令注册)、board_f.c/board_r.c(init序列)
cmd/U-Boot命令行内建命令实现cmd/bootm.c、cmd/memory.c、cmd/nvedit.c
drivers/各类设备驱动,按外设类型分子目录drivers/net/、drivers/mmc/、drivers/mtd/、drivers/serial/
include/全局头文件与配置文件include/configs/(板级配置头文件)、include/u-boot/
lib/通用库函数(字符串、加密、显示等)lib/strto.c、lib/crc32.c、lib/display_options.c
net/网络协议栈(TFTP、NFS、DHCP等)net/tftp.c、net/net.c
fs/文件系统支持(ext4、fat、ubifs等)fs/ext4/、fs/fat/
tools/主机端工具(镜像处理、打包脚本)tools/mkimage、tools/dtoc
configs/板级默认配置文件(defconfig)configs/rpi_4_defconfig
doc/开发文档与READMEdoc/README.*
scripts/Kconfig/Makefile辅助脚本scripts/kconfig/
Makefile顶层构建入口定义目标、版本、链接脚本

关键文件与编译流程的对应关系

U-Boot的编译配置基于Kconfig,板级配置通过 make <board>_defconfig 生成 .config。编译流程中目录的参与方式如下:

  1. 配置阶段:configs/ 下的defconfig提供默认配置,scripts/kconfig/ 解析并生成 .config。
  2. 编译阶段:顶层 Makefile 根据 .config 决定编译哪些目录——arch/ 下的启动汇编、board/ 下的板级初始化、drivers/ 中使能的驱动、cmd/ 中开启的命令。
  3. 链接阶段:arch/<arch>/cpu/ 中的 u-boot.lds 链接脚本决定各目标文件的排列顺序,common/board_f.c 与 common/board_r.c 中的init序列决定运行时初始化顺序。

验证方法

在源码根目录执行以下命令,验证你对目录结构的理解是否正确:

# 1. 查看当前架构相关目录(以arm为例)
ls arch/arm/
# 预期输出:cpu/ dts/ include/ lib/ mach-*/ ...(含mach-前缀的SoC平台目录)

# 2. 查看板级目录(以树莓派4为例)
ls board/raspberrypi/
# 预期输出:Kconfig MAINTAINERS Makefile rpi-r4.c(板级初始化源文件)

# 3. 查看一个命令的实现位置
grep -r "cmd_bootm" cmd/ --include="*.c" -l
# 预期输出:cmd/bootm.c

# 4. 查看板级配置头文件
ls include/configs/ | grep rpi
# 预期输出:rpi.h(该头文件定义内存布局、外设地址等宏)

# 5. 确认defconfig位置
ls configs/ | grep rpi_4
# 预期输出:rpi_4_defconfig

通过标准:以上5条命令均能返回预期结果,且你能根据返回的目录名解释其对应功能(例如看到 mach-bcm283x 能说出这是博通SoC平台代码)。

常见误区

  • 混淆 arch/ 与 board/:arch/ 存放CPU架构通用代码(如ARM的启动汇编),board/ 存放具体开发板的外设初始化与引脚配置。同一架构的不同板子共享 arch/,但各自有独立的 board/ 目录。
  • 忽略 include/configs/:该目录下的头文件是板级硬件配置的核心,定义了DDR大小、外设基地址、环境变量偏移等关键宏,修改这些宏需要重新编译整个U-Boot。
  • 误以为 cmd/ 是唯一命令来源:部分命令实现在 common/(如 cmd_bdinfo)或 net/(如 tftpboot),查找命令时应使用 grep -r "cmd_" 全局搜索。