news 2026/4/17 21:07:18

U-Boot中make命令会发生什么?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
U-Boot中make命令会发生什么?

大家好,我是嵌入式兔哥。在嵌入式开发中,U-Boot的编译构建是核心基础环节,不少朋友对make命令的执行链路、中间文件生成及最终链接过程存在困惑。今天兔哥就带大家逐层拆解,把这些底层逻辑讲透,全是干货,建议收藏备用。

执行make命令会发生的流程如图:

一、U-Boot中make命令的完整执行流程

make无参数执行的核心目标是生成最终可烧录的二进制文件u-boot.bin,整个流程严格遵循顶层Makefile的依赖链,从默认目标开始逐层拆解,依次完成编译、链接、格式转换等操作,增量构建的核心就在于依赖关系的精准判断。

1.1 默认目标的触发与依赖传递

顶层Makefile首先定义默认目标为_all,核心代码如下:

PHONY := _all _all: # KBUILD_EXTMOD为空(不编译外部模块)时,_all依赖all目标 _all: all

由此形成“_all→all”的第一层依赖关系,all目标的核心依赖是$(ALL-y)集合,对应的Makefile代码的:

all: $(ALL-y) # 默认核心目标清单,随板级配置追加产物 ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg binary_size_check

该清单会根据板级配置(如CONFIG_SPL、CONFIG_ONENAND_U_BOOT)追加对应产物,整个流程最终围绕u-boot.bin的生成展开。

all目标的核心依赖是$(ALL-y)集合,这是编译的核心目标清单,默认包含u-boot.srec、u-boot.bin、u-boot.sym、System.map、u-boot.cfg等文件,同时会根据板级配置xxx_deconfig文件(如CONFIG_SPL、CONFIG_ONENAND_U_BOOT)追加对应产物,整个流程最终围绕u-boot.bin的生成展开。

1.2 u-boot.bin的生成链路拆解

u-boot.bin并非直接编译生成,而是经过多步格式转换和依赖联动得到,核心链路如下:

第一步:u-boot-nodtb.bin→u-boot.bin:当未启用设备树分离配置(CONFIG_OF_SEPARATE≠y)时,u-boot.bin的生成依赖u-boot-nodtb.bin,对应Makefile代码:

u-boot.bin: u-boot-nodtb.bin FORCE $(call if_changed,copy)

其中$(call if_changed,copy)调用scripts/Kbuild.include中的if_changed函数,仅当u-boot-nodtb.bin更新或命令变化时,执行copy操作生成u-boot.bin,实现增量构建。

第二步:u-boot(ELF文件)→u-boot-nodtb.bin:u-boot-nodtb.bin由ELF格式的u-boot经格式转换生成,Makefile代码如下:

u-boot-nodtb.bin: u-boot FORCE $(call if_changed,objcopy) $(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE)) $(BOARD_SIZE_CHECK)

核心逻辑是通过objcopy将ELF文件转为纯二进制文件,同时执行静态重定位(依赖CONFIG_SYS_TEXT_BASE指定的链接地址,如0x87800000)和板级大小检查,确保文件符合硬件限制。

第三步:核心依赖→u-boot(ELF文件):ELF格式的u-boot是链接核心产物,依赖启动目标码、合并目标文件和链接脚本,Makefile代码:

u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE $(call if_changed,u-boot__)

三大核心依赖分别是:u-boot-init(即(head−y),对应arch/arm/cpu/armv7/start.o启动目标码)、u−boot−main(即(head-y),对应arch/arm/cpu/armv7/start.o启动目标码)、u-boot-main(即(heady),对应arch/arm/cpu/armv7/start.o启动目标码)、ubootmain(即(libs-y),各子目录built-in.o集合)、u-boot.lds链接脚本;$(call if_changed,u-boot__)封装链接命令,最终通过链接器组合生成ELF文件。

第四步:链接脚本u-boot.lds的生成:链接脚本决定内存布局,由模板经预处理生成,Makefile代码:

u-boot.lds: $(LDSCRIPT) prepare FORCE $(call if_changed_dep,cpp_lds)

其中$(LDSCRIPT)是板级指定的链接脚本模板,prepare目标完成编译准备(如生成配置头文件),cpp_lds通过C预处理器展开模板中的宏定义和条件编译,生成最终可用的u-boot.lds。

二、目标文件(.o)

2.1 .o文件的生成来源

所有.o文件均由源代码编译生成,分为两类:一是单个模块.o文件,由.c源文件或.S汇编文件通过交叉编译器编译得到,核心命令如下:

# 简化命令,实际含-I(头文件路径)、-O(优化等级)等参数arm-linux-gnueabihf-gcc -c -o mxc_gpio.o mxc_gpio.c

比如drivers/gpio/mxc_gpio.c编译生成mxc_gpio.o;二是合并后的built-in.o文件,由各子目录下所有单个.o文件经部分链接生成,是后续顶层链接的核心输入。

2.2 built-in.o的合并过程

每个核心子目录(如cmd/、drivers/、fs/)都会生成built-in.o,以drivers/gpio/built-in.o为例,对应的编译命令:

cmd_drivers/gpio/built-in.o := arm-linux-gnueabihf-ld.bfd -r -o drivers/gpio/built-in.o drivers/gpio/mxc_gpio.o

通过交叉链接器ld的-r参数(部分链接),将目录下所有单个.o文件合并为可重定向的built-in.o。顶层Makefile通过libs-y变量统一收集:

# 定义需编译的核心子目录 libs-y += lib/ cmd/ common/ drivers/ fs/ net/ ... # 转换为各目录的built-in.o libs-y := $(patsubst %/, %/built-in.o, $(libs-y))

最终形成u-boot-main依赖集,大幅简化顶层链接的依赖管理。

三、最终链接过程详解

链接是将分散的目标文件、启动文件和链接脚本组合为可执行文件的过程,也是决定程序在内存中运行布局的关键步骤,兔哥带大家看具体细节。

3.1 链接的输入与核心参数

链接的输入文件包括:start.o启动目标码、所有子目录built-in.o集合、u-boot.lds链接脚本;交叉链接器(如arm-linux-gnueabihf-ld.bfd)的完整链接命令如下:

arm-linux-gnueabihf-ld.bfd -pie --gc-sections -Bstatic -Ttext 0x87800000\-o u-boot -T u-boot.lds\arch/arm/cpu/armv7/start.o\--start-group arch/arm/cpu/built-in.o arch/arm/imx-common/built-in.o...(所有built-in.o)--end-group\-L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4\-lgcc -Map u-boot.map

核心参数解析如下:

  • -T u-boot.lds:指定链接脚本,控制段布局;

  • -Ttext 0x87800000:指定代码段起始地址,与CONFIG_SYS_TEXT_BASE保持一致;

  • –gc-sections:垃圾回收未使用的代码/数据段,减小文件体积;

  • –start-group/–end-group:解决组内文件交叉依赖,循环解析符号;

  • -lgcc:链接GCC内置库,提供底层运算和异常处理函数;

  • -Map u-boot.map:生成链接映射文件,记录符号地址,用于调试。

3.2 链接输出与后续转换

链接直接输出ELF格式的u-boot文件,该文件含符号表和调试信息,可用于调试但无法直接烧录。后续通过objcopy转换为纯二进制的u-boot-nodtb.bin,再经copy操作生成最终的u-boot.bin,完成整个构建流程。

四、核心文件及作用对比表

文件名称生成来源核心作用文件格式/类型
顶层Makefile项目自带,板级适配修改定义编译目标、依赖关系、工具链参数,控制整体构建流程Makefile脚本文件
.c/.S文件开发者编写的源代码(驱动、命令、启动代码等)嵌入式程序核心逻辑载体,编译的原始输入源代码文件
.o文件.c/.S文件经交叉编译器(gcc)编译生成单个模块的目标文件,含二进制指令,为后续链接提供输入目标文件(可重定向)
built-in.o文件同一子目录下多个.o文件经ld -r部分链接生成合并子目录模块,简化顶层链接的依赖管理合并目标文件(可重定向)
u-boot.lds板级链接脚本模板经cpp_lds预处理生成定义代码段、数据段、栈地址等内存布局,指导链接过程链接脚本文件
u-boot(ELF文件)start.o、built-in.o、u-boot.lds经链接器链接生成含符号表和调试信息,为后续格式转换提供基础ELF可执行文件(带调试信息)
u-boot-nodtb.binELF格式u-boot经objcopy转换生成纯二进制文件,已完成静态重定位,适配硬件内存地址纯二进制文件
u-boot.binu-boot-nodtb.bin经copy操作生成最终可烧录文件,用于嵌入式设备启动引导纯二进制文件(可烧录)
u-boot.map链接过程中生成(-Map参数控制)记录符号地址、段布局信息,用于程序调试和问题定位文本格式映射文件

总结

兔哥再帮大家梳理核心逻辑:U-Boot的make构建流程本质是“依赖链驱动的增量构建”,从默认目标逐层拆解至源代码编译,经“.c/.S→.o→built-in.o→ELF文件→二进制文件”的转换链路,最终生成可烧录的u-boot.bin。其中.o文件是编译与链接的核心中间载体,u-boot.lds决定内存布局,链接过程则是整合所有模块的关键步骤。掌握这些逻辑,能帮大家快速定位编译和启动过程中的各类问题,深入理解嵌入式程序的构建本质。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 3:22:52

扔掉了本地开发环境,然后开发效率翻了一倍

我曾一度坚信&#xff0c;一个精心配置、插件齐全的本地开发环境&#xff0c;是程序员最后的尊严。直到上周&#xff0c;团队新来一个同事&#xff0c;光是配一个项目的开发环境就折腾了整整一天&#xff0c;最后还是因为一个依赖版本问题无法启动。那一刻我突然意识到&#xf…

作者头像 李华
网站建设 2026/4/17 2:06:22

如何复现论文中的大模型方法并解决实际问题

关键词&#xff1a;人工智能大模型 人工智能培训 大模型培训 具身智能培训 智能体 VLA 将论文中的大模型方法应用于实际问题&#xff0c;是一个从“理论”到“实践”的转化过程。以下是系统化的步骤和建议&#xff0c;帮助你高效地实现这一目标&#xff1a; 一、理解论文方法的…

作者头像 李华
网站建设 2026/4/18 2:00:38

基于SpringBoot+Vue的学生捐赠物品管理系统设计与实现毕设

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。一、研究目的本研究旨在设计并实现一个基于SpringBoot和Vue的学生捐赠物品管理系统。该系统旨在解决当前学生捐赠物品管理过程中存在的诸多问题&#xff0c;如信息不透明、捐…

作者头像 李华
网站建设 2026/4/18 1:57:18

java计算机毕业设计校园办公管理系统 高校无纸化协同办公平台的设计与实现 基于Java的智慧校园行政事务管理系统

计算机毕业设计校园办公管理系统n97i39&#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。当“让数据多跑路、让师生少跑腿”成为高校治理的新常态&#xff0c;传统纸质签批、Excel …

作者头像 李华
网站建设 2026/4/18 2:02:28

基于SpringBoot+Vue的药物评价交流平台毕设

博主介绍&#xff1a;✌ 专注于Java,python,✌关注✌私信我✌具体的问题&#xff0c;我会尽力帮助你。一、研究目的本研究旨在构建一个基于SpringBootVue的药物评价交流平台&#xff0c;以实现药物信息的共享、评价与交流。具体研究目的如下&#xff1a; 首先&#xff0c;本研究…

作者头像 李华
网站建设 2026/4/17 7:29:21

当工具变量遇上深度学习:DeepIV如何看透因果?

引子&#xff1a;从“涨价”不一定“减量”说起 生活中有许多看似反常的经济现象。比如&#xff0c;每逢节假日&#xff0c;机票价格飙升&#xff0c;但出游的人数却不减反增&#xff0c;各大航司的机票销售依旧火爆。如果我们天真地把“价格”和“销量”这两个数据点直接拿给…

作者头像 李华