uboot 编译过程
文章目录
- 一、Kconfig和make menuconfig的关系
- **Kconfig 与 `make menuconfig` 的关系**
- **Kconfig 语法**
- **1. 定义配置项**
- **2. 依赖关系 (`depends on`)**
- **3. 条件 (`if ... endif`)**
- **4. 选项类型**
- **5. 选择某个选项 (`select`)**
- **总结**
- 二、uboot的编译过程
- **U-Boot `make` 过程解析**
- **1. 选择目标板**
- **2. 生成编译配置**
- **3. 递归调用 `Makefile` 编译**
- **4. 生成最终 U-Boot 镜像**
- **5. U-Boot 编译过程总结**
- **总结**
一、Kconfig和make menuconfig的关系
Kconfig 与 make menuconfig
的关系
Kconfig 是 Linux 内核、U-Boot 等项目使用的 配置系统,用于定义编译选项,类似 C 语言的 #ifdef
预处理指令,但更强大,提供了层次化、菜单式的配置方式。
make menuconfig
是 Kconfig 的交互式配置工具,它解析 Kconfig 文件并生成菜单供用户选择,最终输出 .config
配置文件,控制内核或其他项目的编译行为。
其核心流程:
- Kconfig 定义选项(类似菜单树结构)
make menuconfig
解析 Kconfig,提供 TUI 选择界面- 用户选择配置项,最终生成
.config
make
解析.config
,影响编译行为
Kconfig 语法
Kconfig 语法类似 C 语言宏定义,支持变量、条件、依赖项等。下面是几个常见的 Kconfig 语法:
1. 定义配置项
config FEATURE_X
bool "Enable Feature X"
default n
help
This option enables Feature X.
config FEATURE_X
:定义FEATURE_X
选项bool
:二进制选项(y/n
)"Enable Feature X"
:用户在menuconfig
看到的描述default n
:默认关闭help
:提供详细说明
2. 依赖关系 (depends on
)
config FEATURE_Y
bool "Enable Feature Y"
depends on FEATURE_X
depends on FEATURE_X
:FEATURE_X=y
时,FEATURE_Y
才可选
3. 条件 (if ... endif
)
config ADVANCED_FEATURE
bool "Advanced Feature"
depends on EXPERT
if ADVANCED_FEATURE
config SUB_FEATURE
bool "Sub Feature of Advanced"
endif
if ... endif
结构限制SUB_FEATURE
仅在ADVANCED_FEATURE=y
时可选
4. 选项类型
bool
:二进制开关(y/n
)tristate
:三态(y/n/m
,m 表示编译成模块)int
/hex
:整数/十六进制数输入string
:字符串输入
示例:
config MAX_THREADS
int "Max threads"
range 1 256
default 4
5. 选择某个选项 (select
)
config FEATURE_A
bool "Feature A"
config FEATURE_B
bool "Feature B"
select FEATURE_A
- 选择
FEATURE_B
时,FEATURE_A
也会自动启用(类似depends on
,但不会受FEATURE_A
的依赖项限制)
总结
- Kconfig 定义编译选项,支持菜单层次、依赖关系、默认值等
make menuconfig
提供图形化选择界面.config
是最终生成的配置文件,控制编译行为- 常见语法:
config NAME
:定义选项bool
/tristate
/int
/string
:选项类型depends on
/select
:控制依赖default
:默认值if ... endif
:条件
二、uboot的编译过程
U-Boot make
过程解析
U-Boot(Das U-Boot)是一个常见的嵌入式引导加载程序,采用类似 Linux 内核的 Kconfig
+ Makefile
机制进行编译。
整个 make
过程可以概括为:
- 选择目标板(通过
make <board>_defconfig
) - 配置构建参数(
make menuconfig
,生成.config
) - 生成头文件(
autoconf.mk
和autoconf.h
) - 递归调用
Makefile
进行编译 - 链接生成最终的 U-Boot 镜像(如
u-boot.bin
)
1. 选择目标板
U-Boot 支持多个硬件平台,每个平台有一个 defconfig
预设配置文件,存放在 configs/
目录下。例如:
make imx6ull_defconfig
这个命令会:
- 复制
configs/imx6ull_defconfig
到.config
make
解析.config
并生成include/config/auto.conf
(由Kconfig
系统完成)
如果要手动修改配置:
make menuconfig
- 进入
menuconfig
界面,修改编译选项 - 最终
.config
影响 U-Boot 的编译行为
2. 生成编译配置
执行 make
之后:
make
关键步骤:
- 解析
.config
- 通过
scripts/kconfig/conf
解析.config
- 生成
include/generated/autoconf.h
,包含所有#define CONFIG_xxx
- 生成
include/config/auto.conf
,包含所有CONFIG_xxx=y
的宏定义
- 通过
- Makefile 解析
Kconfig
Makefile
通过scripts/Makefile.autoconf
读取auto.conf
- 提供给后续编译使用
3. 递归调用 Makefile
编译
U-Boot 采用 递归 Make 机制,根 Makefile
调用子目录:
subdirs := arch board common drivers lib net
subdir-y := $(subdirs)
include $(srctree)/scripts/Kbuild.include
.PHONY: $(subdir-y)
$(subdir-y):
$(Q)$(MAKE) $(build)=$@
subdir-y
包含各个子目录(如arch/
、board/
)$(MAKE) $(build)=arch/
递归进入arch/
目录- 每个子目录都有
Makefile
负责自身编译
编译关键目标
arch/
处理架构相关代码(ARM/MIPS/RISC-V)board/
处理开发板代码(board/<厂商>/<开发板>/
)common/
包含公共代码,如cmd/
(U-Boot 命令)drivers/
设备驱动,如drivers/serial
(串口)、drivers/net
(网络)lib/
提供基础库函数,如lib/string.c
net/
处理网络协议栈,如tftp
、dhcp
4. 生成最终 U-Boot 镜像
当所有 .o
文件编译完成后,Makefile
执行链接步骤:
$(LD) $(LDFLAGS) -T u-boot.lds -o u-boot $(OBJS) $(LIBS)
$(LD)
:调用ld
链接器u-boot.lds
:链接脚本,定义TEXT_BASE
(U-Boot 加载地址)$(OBJS)
:所有.o
目标文件$(LIBS)
:所有库文件(lib.a
)
最终生成:
u-boot
(ELF 格式,可调试)u-boot.bin
(裸机可执行文件)u-boot.map
(符号地址映射)
不同 SoC 可能需要转换格式,如:
mkimage -A arm -O u-boot -T firmware -C none -a 0x87800000 -e 0x87800000 -n "U-Boot" -d u-boot.bin u-boot.img
5. U-Boot 编译过程总结
make imx6ull_defconfig # 选择开发板配置
make menuconfig # 可选,修改配置
make # 编译
最终得到:
u-boot
(ELF 格式)u-boot.bin
(可烧录)u-boot.img
(若使用mkimage
生成)
总结
- U-Boot 采用 Kconfig + Makefile 机制
make <board>_defconfig
选择开发板make menuconfig
修改配置- 递归
Makefile
编译不同模块 - 最终生成
u-boot.bin
,用于烧录