文章目录
- [1 U-Boot工程目录分析](#1 U-Boot工程目录分析)
-
- [1.1 arch文件夹](#1.1 arch文件夹)
- [1.2 board文件夹](#1.2 board文件夹)
- [1.3 configs文件夹](#1.3 configs文件夹)
- [1.4 .u-boot.xxx_cmd文件](#1.4 .u-boot.xxx_cmd文件)
- [1.5 Makefile文件](#1.5 Makefile文件)
- [1.6 u-boot.xxx文件](#1.6 u-boot.xxx文件)
- [1.7 .config文件](#1.7 .config文件)
- [1.8 README文件](#1.8 README文件)
- [2 U-Boot顶层Makefile分析](#2 U-Boot顶层Makefile分析)
-
- [2.1 版本号](#2.1 版本号)
- [2.2 MAKEFLAGS变量](#2.2 MAKEFLAGS变量)
- [2.3 命令输出](#2.3 命令输出)
- [2.4 静默输出](#2.4 静默输出)
- [2.5 设置编译结果输出目录](#2.5 设置编译结果输出目录)
- [2.6 代码检查](#2.6 代码检查)
- [2.7 模块编译](#2.7 模块编译)
- [2.8 获取主机架构和系统](#2.8 获取主机架构和系统)
- [2.9 设置目标架构,交叉编译器](#2.9 设置目标架构,交叉编译器)
- [2.10 配置文件](#2.10 配置文件)
- [2.11 调用scripts/Kbuild.include](#2.11 调用scripts/Kbuild.include)
- [2.12 交叉编译工具变量设置](#2.12 交叉编译工具变量设置)
- [2.13 make xxx_defconfig过程](#2.13 make xxx_defconfig过程)
- [2.14 make过程](#2.14 make过程)
1 U-Boot工程目录分析
使用经过编译后的uboot源码目录。因为编译后的源码目录会生成一些必要的文件。
uboot源码目录如下所示:
分析源码需要关注的文件或文件夹如下:
- arch文件夹
- board文件夹
- configs文件夹
- .u-boot.xxx_cmd文件
- Makefile文件
- u-boot.xxx文件
- .config文件
- README文件
1.1 arch文件夹
存放和架构相关的文件。
1.2 board文件夹
存放具体板子有关的内容。
1.3 configs文件夹
uboot配置文件夹,包含半导体或者开发板厂商提供的基础配置文件。用户可以在此文件夹中以某一个基础配置文件为蓝本,创建自己开发板的配置文件,这些配置文件的命名格式一般为xxx_defconfig。
1.4 .u-boot.xxx_cmd文件
.u-boot.xxx_cmd是一系列的文件,这些文件都是编译生成的,都是一些命令文件。
1.5 Makefile文件
U-Boot顶层Makefile文件,Makefile是支持嵌套的,也就是顶层Makefile可以调用子目录中的Makefile文件。Makefile嵌套在大项目中很常见,一般大项目里面所有的源代码都不会放到同一个目录中,各个功能模块的源代码都是分开的,各自存放在各自的目录中。每个功能模块目录下都有一个Makefile,这个Makefile只处理本模块的编译链接工作,这样所有的编译链接工作就不用全部放到一个Makefile中,可以使得Makefile变得简洁明了。
1.6 u-boot.xxx文件
u-boot.xxx同样也是一系列文件,包括u-boot、u-boot-dtb.bin、u-boot-nodtb.bin、u-boot.bin、u-boot.cfg、u-boot.dtb、u-boot.lds、u-boot.map、u-boot.srec、u-boot.stm32和u-boot.sym,这些文件的含义如下:
| 文件名 | 描述 |
|---|---|
| u-boot | 编译出来的ELF格式的uboot镜像文件 |
| u-boot-dtb.bin | 编译出来的含有设备树.dtb的uboot镜像文件 |
| u-boot-nodtb.bin | 编译出来的不含有设备树.dtb的uboot镜像文件,和u-boot.bin一样 |
| u-boot.bin | 编译出来的二进制格式的uboot可执行镜像文件 |
| u-boot.cfg | uboot的另外一种配置文件 |
| u-boot.dtb | uboot设备树编译后的.dtb文件 |
| u-boot.lds | 链接脚本 |
| u-boot.map | boot映射文件,通过查看此文件可以知道某个函数被链接到了哪个地址上 |
| u-boot.srec | S-Record格式的镜像文件 |
| u-boot.stm32 | 最终要写到STM32MP157的uboot文件 |
| u-boot.sym | uboot符号文件 |
1.7 .config文件
uboot配置文件,使用命令"make xxx_defconfig"配置uboot以后就会自动生成,通过使能文件中的宏可以达到选择使能某个功能,编译对应的源码文件。
1.8 README文件
README文件描述了uboot的详细信息,包括uboot该如何编译、uboot中各文件夹的含义、相应的命令等等。
2 U-Boot顶层Makefile分析
2.1 版本号
makefile
VERSION = 2020 # 主版本号
PATCHLEVEL = 01 # 补丁版本号
SUBLEVEL = # 次版本号
EXTRAVERSION = -stm32mp-r1 # 附件版本信息
NAME = # 名字相关
2.2 MAKEFLAGS变量
make是支持递归调用的,或者说makefile文件的嵌套。在Makefile中使用make命令来执行其他的Makefile文件,一般都是子目录中的Makefile文件。主目录的Makefile可以使用如下代码来编译这个子目录:
makefile
$(MAKE) -C subdir # -C 用于指定子目录
有时需要向子make传递变量,可以使用export来导出传递给子make的变量,使用unexport来声明不导出:
makefile
export HOSTARCH HOSTOS # 导出 HOSTARCH 和 HOSTOS 变量
unexport LC_ALL # 不导出 LC_ALL 变量
有两个特殊的变量:SHELL和MAKEFLAGS,这两个变量除非使用unexport声明否则的话在整个make的执行过程中,它们的值始终自动的传递给子make。
在uboot的主Makefile中有如下代码:
makefile
# += 追加变量值;
# -rR 表示禁止使用内置的隐含规则和变量定义
# --include-dir 指明搜索路径
# $(CURDIR) 表示当前目录
MAKEFLAGS += -rR --include-dir=$(CURDIR)
2.3 命令输出
uboot默认编译是不会在终端中显示完整命令,都是短命令,可以通过设置变量V=1来实现完整的命令输出,以观察uboot编译细节。
bash
make V=1 # 开启 uboot 编译细节
make V=0 # 默认编译输出,短命令,不配置 V 的值也是默认输出
2.4 静默输出
uboot编译过程不输出命令,使用make -s即可实现静默输出。
2.5 设置编译结果输出目录
uboot可以将编译出来的目标文件输出到单独的目录中。
bash
make O=out # 设置目标文件输出到 out 目录中,一般不指定
2.6 代码检查
uboot支持代码检查。通过变量C来实现。
bash
make C=1 # 使能代码检查,但只检查需要重新编译的文件
make C=2 # 用于检查所有的源码文件
2.7 模块编译
uboot允许单独编译某个模块。
bash
make M=dir # dir 是需要编译模块的路径
2.8 获取主机架构和系统
bash
uname -m
unama -s
2.9 设置目标架构,交叉编译器
bash
# 编译时使用
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabihf-
可以直接将变量内容添加到Makefile文件中。

2.10 配置文件
配置文件为.config,默认是没有的,需要使用make xxx_defconfig命令对uboot进行配置,配置完成以后就会在uboot根目录下生成.config文件。默认情况下.config和xxx_defconfig内容是一样的,因为.config就是从xxx_defconfig复制过来的。如果后续自行调整了uboot的一些配置参数,那么这些新的配置参数就添加到了.config中,而不是xxx_defconfig。相当于xxx_defconfig只是一些初始配置,而.config里面的才是实时有效的配置。建议在自行调整了uboot的配置参数后,将新的配置文件.config拷贝一份到configs/xxx_defconfig,避免执行make distclean将新配置文件.config删除。
2.11 调用scripts/Kbuild.include
顶层Makefile会调用scripts/Kbuild.include文件,scripts/Kbuild.include中包含了很多变量。
2.12 交叉编译工具变量设置
顶层Makefile中交叉编译工具变量的相关内容如下:
makefile
# Make variables (CC, etc...)
AS = $(CROSS_COMPILE)as
# Always use GNU ld
ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)
LD = $(CROSS_COMPILE)ld.bfd
else
LD = $(CROSS_COMPILE)ld
endif
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
2.13 make xxx_defconfig过程
主要目的就是生成.config文件。

2.14 make过程
make用于编译uboot,主要工作就是生成二进制的u-boot.bin文件和其他关于uboot的文化,比如u-boot.stm32等等。
