配置LDSCRIPT确定 U-Boot 链接脚本Linker Script的绝对路径BOARDDIR在根目录下config.mk中定义。CONFIG_SYS_LDSCRIPT是老的uboot遗留下来的这段现在不是对LDSCRIPT设置配置LDSCRIPT确定 U-Boot 链接脚本Linker Script的绝对路径$(wildcard ...)这是 GNU make 的内置函数。它会检查参数中匹配的文件是否存在并返回存在的文件的路径。如果文件不存在则返回空字符串。根目录下的config.mk文件被称为“全局编译规则编译器”或“变量大本营”。U-Boot 编译出来的固件体积与运行速度之间的关键权衡都是一些编译参数设置-fno-stack-protector剥离堆栈保护器-fno-delete-null-pointer-checks拦截空指针优化陷阱-g向编译器和汇编器统一注入-g参数。这意味着编译出来的 ELF 固件里会包含完整的调试符号表保留了原始的 C 语言行号、变量名映射-Wno-format-nonliteral过滤无意义的报警一个针对特定古董硬件架构Motorola 68000简称 m68k以及特定老版本 GCC 编译器GCC 3.4的“陈年陈条”和 Bug 修复兜底机制。include scripts/Makefile.extrawarn编译命令后面加上W1这个脚本就会彻底觉醒用最严苛的洁癖视角审视所有的驱动 C 代码帮你抓出隐藏的隐患。make KCFLAGS-O3 -DDEBUG_MY_DRIVER通过加算$(KCFLAGS)向开发者递出了全系统的最高指挥棒。UBOOTINCLUDE该变量使用 GCC 的-I参数按优先级从上到下显式指定了头文件的搜寻目录NOSTDINC_FLAGS切断宿主机依赖目的在于使编译环境与 PC 操作系统脱钩。cpp_flags组合了预处理器所需的全部资源全局预处理标志、平台预处理标志、刚才计算出的 U-Boot 头文件路径、以及屏蔽系统头文件的-nostdinc标志。c_flags将 C 编译器的专属参数如之前计算出的-O2优化级别、-g调试符号等与预处理器标志cpp_flags进行叠加。构建 U-Boot 编译阶段的核心目标库列表libs-y变量。它决定了接下来的 Kbuild 编译系统需要深入到源码树的哪些子目录中去编译驱动、文件系统、网络协议栈等模块并最终将它们打包成.a静态库文件以供链接。scripts/Makefile.build在 U-Boot 中顶层 Makefile 本身不负责直接编译具体的.c文件。当顶层 Makefile 决定要编译某个子目录例如你刚才看到的drivers/gpio/时它会通过make -f scripts/Makefile.build objdrivers/gpio命令把实际的编译重任委派给scripts/Makefile.build。u-boot-dirs清洗目录尾部斜杠并追加工具目录 tools。这个变量主要用于控制接下来make递归进入子目录编译的循环序列。去掉了斜杠Make 引擎才能结合scripts/Makefile.build精准定位到物理文件夹。u-boot-alldirs收集全量目录用于清理。这个变量包含了 U-Boot 工程下几乎所有的子目录。它最核心的用途是提供给make clean或make mrpropper命令。当执行清理工程时系统直接遍历u-boot-alldirs就能把所有目录不管有没有被编译底下的垃圾文件一次性全部扫除干净。u-boot-init来自于$(head-y)。在arch/arm/Makefile中它被赋值为arch/arm/cpu/armv7/start.o。这是 U-Boot 的第一行汇编代码所在的位置。由于它被拎出来作为u-boot-init链接脚本u-boot.lds会在最后组装时强行把它放在二进制镜像的最前端0x0偏移处。只有这样i.MX6ULL 芯片上电时Boot ROM 才能第一眼看到它并正确执行。u-boot-main就是刚才拼装完毕的、包含了各个驱动目录下built-in.o的libs-y列表。为 U-Boot 链接阶段引入底层数学与位运算支持库libgcc.a。动态链接交叉编译器自带的官方库正点原子默认构建链接脚本预处理器标志LDPPFLAGS变量。BOARD_SIZE_CHECK定义一个用于检测编译输出固件体积是否超标的 Shell 脚本变量。在嵌入式开发中特定硬件平台分配给 U-Boot 的存储空间如片内高速度 SRAM、内部 Flash 或特定的分区表边界是存在物理上限的。如果编译出的固件超出了这个限制强行烧录会导致覆盖其他数据区或硬件无法启动。定义一个对编译出的二进制固件进行“静态链接重定位修复”的 Shell 脚本宏变量DO_STATIC_RELA。在现代 64 位 CPU 架构如 ARM64中U-Boot 为了支持位置无关代码PIC/PIE即允许 U-Boot 镜像在运行期间动态地把自己从一个内存地址拷贝到另一个内存地址重定位会在 ELF 文件中生成一个动态重定位段.rel.dyn或.rela.dyn。但是在 U-Boot 刚刚上电、DDR 内存还没初始化、重定位代码还没运行的极早期裸机阶段这些位置无关的绝对地址指针是无效的。为了让 U-Boot 在最早期能正常读取全局变量必须在编译阶段通过外部工具把这些动态重定位关联的物理地址硬编码写入二进制文件中。这就是“静态重定位修复”。构建 U-Boot 编译结束时最终需要生成的“终极目标文件列表”ALL-y变量。在 Makefile 中一个庞大的工程最终会输出很多种格式的文件如纯二进制、符号表、配置文件等。Kbuild 通过ALL-y变量把这些需要输出的目标全部打包收集起来作为默认编译规则all:伪目标的依赖项。ALL-y无条件收集的核心基础目标CONFIG_ONENAND_U_BOOT如果板子采用的是三星的 OneNAND 闪存芯片作为启动介质CONFIG_SPL_FSL_PBLFSL飞思卡尔/NXP处理器引导加载构造分支spl/u-boot-spl.bin如果开启了二级启动CONFIG_SPLy则追加生成 SPL 的二进制镜像。u-boot.img如果使用了标准 SPL 架构外壳CONFIG_SPL_FRAMEWORKySPL 需要识别特定格式的 U-Boot 镜像。u-boot.img是在纯二进制的u-boot.bin前面加上了64 字节的 MKIMAGE 头部信息包含镜像类型、加载地址、校验和等专供 SPL 识别并引导。tpl/u-boot-tpl.bin三级引导目标。在某些片内 SRAM 空间极度严苛的芯片上先跑 SPL再跑 TPL最后才进 U-Boot。对于 i.MX6ULL此项未定义。u-boot.dtb如果开启了设备树分离模式CONFIG_OF_SEPARATEy这是正点原子 i.MX6ULL 的默认配置系统会将设备树源码.dts编译为独立的二进制设备树文件.dtb并将u-boot.dtb加入生成目标列表。u-boot-dtb.img当同时满足“使用 SPL 框架”且“设备树分离”时追加。该目标在后续规则中会把u-boot.bin和编译好的u-boot.dtb物理上拼接到一起然后再用mkimage工具加上 64 字节头部生成一个复合镜像供 SPL 一次性加载。CONFIG_OF_HOSTFILE这是 U-Boot 在 Sandbox沙盒模拟模式下直接读取宿主机 Linux 里的设备树文件时使用的配置。有些 SoC 原厂例如三星、TI 或部分 NXP 芯片的底层 Boot ROM 不认标准的u-boot-spl.bin需要特定格式如u-boot-spl.imx或MLO。原厂会在 Kconfig 中将这个特定的文件名写入CONFIG_SPL_TARGET字符串。u-boot.elf重新生成带完整符号表的 ELF 格式可执行文件。u-boot-app.efi/u-boot-payload.efi当把 U-Boot 配置为作为 UEFI 应用程序运行或者作为 UEFI 的 Stub存根载荷时追加生成符合 UEFI 规范的可执行文件。追加生成u-boot.rom。这是专门针对 X86 物理主板 BIOS 闪存颗粒的大小经过精密填充和对齐后生成的完整镜像可以直接用烧录器刷入主板的 Flash 芯片中。对于你的 ARM 架构平台此判断不成立。continues