文章目录1 U-Boot工程目录分析1.1 arch文件夹1.2 board文件夹1.3 configs文件夹1.4 .u-boot.xxx_cmd文件1.5 Makefile文件1.6 u-boot.xxx文件1.7 .config文件1.8 README文件2 U-Boot顶层Makefile分析2.1 版本号2.2 MAKEFLAGS变量2.3 命令输出2.4 静默输出2.5 设置编译结果输出目录2.6 代码检查2.7 模块编译2.8 获取主机架构和系统2.9 设置目标架构交叉编译器2.10 配置文件2.11 调用scripts/Kbuild.include2.12 交叉编译工具变量设置2.13 make xxx_defconfig过程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.cfguboot的另外一种配置文件u-boot.dtbuboot设备树编译后的.dtb文件u-boot.lds链接脚本u-boot.mapboot映射文件通过查看此文件可以知道某个函数被链接到了哪个地址上u-boot.srecS-Record格式的镜像文件u-boot.stm32最终要写到STM32MP157的uboot文件u-boot.symuboot符号文件1.7 .config文件uboot配置文件使用命令“make xxx_defconfig”配置uboot以后就会自动生成通过使能文件中的宏可以达到选择使能某个功能编译对应的源码文件。1.8 README文件README文件描述了uboot的详细信息包括uboot该如何编译、uboot中各文件夹的含义、相应的命令等等。2 U-Boot顶层Makefile分析2.1 版本号VERSION 2020 # 主版本号 PATCHLEVEL 01 # 补丁版本号 SUBLEVEL # 次版本号 EXTRAVERSION -stm32mp-r1 # 附件版本信息 NAME # 名字相关2.2 MAKEFLAGS变量make是支持递归调用的或者说makefile文件的嵌套。在Makefile中使用make命令来执行其他的Makefile文件一般都是子目录中的Makefile文件。主目录的Makefile可以使用如下代码来编译这个子目录$(MAKE) -C subdir # -C 用于指定子目录有时需要向子make传递变量可以使用export来导出传递给子make的变量使用unexport来声明不导出export HOSTARCH HOSTOS # 导出 HOSTARCH 和 HOSTOS 变量 unexport LC_ALL # 不导出 LC_ALL 变量有两个特殊的变量SHELL和MAKEFLAGS这两个变量除非使用unexport声明否则的话在整个make的执行过程中它们的值始终自动的传递给子make。在uboot的主Makefile中有如下代码# 追加变量值 # -rR 表示禁止使用内置的隐含规则和变量定义 # --include-dir 指明搜索路径 # $(CURDIR) 表示当前目录 MAKEFLAGS -rR --include-dir$(CURDIR)2.3 命令输出uboot默认编译是不会在终端中显示完整命令都是短命令可以通过设置变量V1来实现完整的命令输出以观察uboot编译细节。makeV1# 开启 uboot 编译细节makeV0# 默认编译输出短命令不配置 V 的值也是默认输出2.4 静默输出uboot编译过程不输出命令使用make -s即可实现静默输出。2.5 设置编译结果输出目录uboot可以将编译出来的目标文件输出到单独的目录中。makeOout# 设置目标文件输出到 out 目录中一般不指定2.6 代码检查uboot支持代码检查。通过变量C来实现。makeC1# 使能代码检查但只检查需要重新编译的文件makeC2# 用于检查所有的源码文件2.7 模块编译uboot允许单独编译某个模块。makeMdir# dir 是需要编译模块的路径2.8 获取主机架构和系统uname-munama-s2.9 设置目标架构交叉编译器# 编译时使用makeARCHarmCROSS_COMPILEarm-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中交叉编译工具变量的相关内容如下# 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)objdump2.13 make xxx_defconfig过程主要目的就是生成.config文件。2.14 make过程make用于编译uboot主要工作就是生成二进制的u-boot.bin文件和其他关于uboot的文化比如u-boot.stm32等等。