一,u-boot的默认配置 xxx_defconfig
在顶层的Makefile中找到如下规则
%config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
target -> %config -> mx6ull_14x14_evk_defconfig
command -> $(Q)$(MAKE) $(build)=scripts/kconfig $@ -> @make -f ./scripts/Makefile.build obj=scripts/kconfig mx6ull_14x14_evk_defconfig
1,依赖条件1:scripts_basic
# Basic helpers built in scripts/
PHONY += scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
->
scripts_basic:
@make -f scripts/Makefile.build obj=scripts/basic
@rm -f.tmp_quiet_recordmcount
所以依赖条件1变为:
scripts_basic:
@make -f scripts/Makefile.build obj=scripts/basic
@rm -f.tmp_quiet_recordmcount
然后将src下的makefile包含进来,最终src= scripts/basic下的makefile内容被编译。
查看scripts\basic目录下的makefile 编译了fixdep.c,用于解决依赖的问题。
2,依赖条件2:outputmakefile
PHONY += outputmakefile
# outputmakefile generates a Makefile in the output directory, if using a
# separate output directory. This allows convenient use of make in the
# output directory.
outputmakefile:
ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif
KBUILD_SRC为空,此依赖条件并不执行。
3,依赖条件3:FORCE(不执行什么)
PHONY += FORCE
FORCE:
Makefile 伪目标 FORCE
force则通常是用户自定义的一个目标,它没有命令,也没有依赖,所以它总是被认为是需要更新的。
因此,如果一个目标依赖于force,那么这个目标的命令总是会被执行。
这在你想要强制执行某些命令时非常有用,例如清理操作或者强制重新编译。
4,此时目标变成
mx6ull_14x14_evk_defconfig:scripts_basic
@make –f ./scripts/Makefile.build obj=scripts/kconfig mx6ull_14x14_evk_defconfig
结果是将scripts/kconfig目录下makefile文件的中目标被编译。即:scripts/kconfig/Makefile中的%_defconfig被匹配:
%_defconfig: scripts/kconfig/conf
$(Q)$<$(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
展开后:
mx6ull_14x14_evk_defconfig:scripts/kconfig/conf
$(Q)scripts/kconfig/conf --defconfig=arch/../configs/mx6ull_14x14_evk_defconfig Kconfig
5,conf工具的生成和作用
scripts/kconfig/conf: FORCE scripts/kconfig/conf.o scripts/kconfig/zconf.tab.o
依赖1
scripts/kconfig/conf.o: scripts/kconfig/conf.c FORCE
依赖2:
scripts/kconfig/zconf.tab.o: scripts/kconfig/zconf.tab.c FORCE scripts/kconfig/zconf.lex.c scripts/kconfig/zconf.hash.c
scripts/kconfig/conf --defconfig=arch/../configs/mx6ull_14x14_evk_defconfig Kconfig ->
scripts/kconfig/conf: 读取 Kconfig 及mx6ull_14x14_evk_defconfig输出到.config。
conf命令概述
总体分析:scripts/kconfig/conf.c
defconfig_file = "arch/../configs/mx6ull_14x14_evk_defconfig";
name = "Kconfig"
conf_parse(name); // 解析uboot根目录下的Kconfig文件
conf_read(defconfig_file); // 读配置文件
conf_set_all_new_symbols(def_default); // 设置new_symbols为默认值
conf_write(NULL); // 写到.config
-
Kconfig:这是一个通用文件,里面规定了一些依赖,比如:
如果是ARM架构,就默认选中A、B、C配置
如果是RISC-V架构,就默认选中a、b、c配置
-
defconfig_file:这是厂家提供的,里面定义了
ARM架构
自己的一些配置项
-
怎么处理呢?
使用defconfig_file的内容去解析Kconfig,确定各个依赖的配置项
其他未涉及的配置项,给它们指定默认值
写入.config
二,Kconfig介绍
1,menuconfig结果的保存
对于各类内核,只要支持menuconfig配置界面,都是使用Kconfig。
在配置界面中,可以选择、设置选项,这些设置会保存在.config文件里。
编译脚本会包含.config,根据里面的值决定编译哪些文件、怎么编译文件。
.config文件也会被转换为头文件,C程序可以从头文件中获得配置信息。
2,使用menuconfig更新.config
make mx6ull_14x14_evk_defconfig生成的.config文件部分内容如下:
#
# Boot media
#
# CONFIG_NAND_BOOT is not set
# CONFIG_ONENAND_BOOT is not set
# CONFIG_QSPI_BOOT is not set
# CONFIG_SATA_BOOT is not set
# CONFIG_SD_BOOT is not set
# CONFIG_SPI_BOOT is not set
CONFIG_BOOTDELAY=3
使用make menuconfig打开配置 bootmedia > Support for booting from SPI flash,更新后的.config文件的部分内容如下:
#
# Boot media
#
# CONFIG_NAND_BOOT is not set
# CONFIG_ONENAND_BOOT is not set
# CONFIG_QSPI_BOOT is not set
# CONFIG_SATA_BOOT is not set
# CONFIG_SD_BOOT is not set
CONFIG_SPI_BOOT=y
CONFIG_BOOTDELAY=3
CONFIG_SPI_BOOT=y配置项被打开。
三,配置文件进一步处理
1,u-boot的各类配置文件
2,配置文件进一步处理
前面生成了.config,但是它不是最终版本的配置文件。在make时会进一步配置,然后再执行编译。
顶层Makefile会包含2个配置文件:include/config/auto.conf、include/autoconf.mk。
u-boot中有非常多的配置文件:
-
.config:来自单板的默认配置、Kconfig
-
include/config/auto.conf:来自.config,去掉了很多注释
- u-boot.cfg:它的内容跟头文件类似,来自
* .config
* 头文件include/common.h,又包含了"#include <config.h>",config.h内容如下:
/* Automatically generated - do not edit */
#define CONFIG_IMX_CONFIG board/freescale/mx6ullevk/imximage.cfg
#define CONFIG_BOARDDIR board/freescale/mx6ullevk
#include <config_defaults.h>
#include <config_uncmd_spl.h>
#include <configs/mx6ullevk.h>
#include <asm/config.h>
#include <linux/kconfig.h>
#include <config_fallbacks.h>
- include/autoconf.mk:来自u-boot.cfg,但是移除include/config/auto.conf的内容以免重复
需要进一步处理,根据Makefile的remake功能,在执行all target之前会首先根据如下规则生成include/config/auto.conf、include/autoconf.mk:
include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \
{ rm -f include/config/auto.conf; false; }
$(Q)touch include/config/auto.conf
上述规则的命令里,有2个操作:
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf
第1个操作相当于:make silentoldconfig,生成了文件
-
include/config/auto.conf:来自.config,去掉了很多注释
-
include/config/auto.conf.cmd:auto.conf的依赖规则
-
include/generated/autoconf.h:内容跟auto.conf类似,是C语言的头文件
-
include/config/tristate.conf:空文件
-
include/generated/autoksyms.h:空文件
make silentoldconfig%config: scripts_basic outputmakefile FORCE$(Q)$(MAKE) $(build)=scripts/kconfig $@进入scripts/kconfig是它的Makefile:
silentoldconfig: $(obj)/conf$(Q)mkdir -p include/config include/generated$(Q)test -e include/generated/autoksyms.h || \touch include/generated/autoksyms.h$< $(silent) --$@ $(Kconfig)scripts/kconfig/conf分析:
scripts/kconfig/conf --silentoldconfig Kconfig
1. sync_kconfig = 1
2. name = "Kconfig", conf_parse(name);
3. name = conf_get_configname(); = ".config"
4. conf_read(NULL); #
第2个操作相当于make -f scripts/Makefile.autoconf ,会生成一系列头文件:
ln -fsn arch-mx6 arch/arm/include/asm/arch
include/autoconf.mk, {spl,tpl}/include/autoconf.mk
include/config.h
scripts/Makefile.autoconf 分析:
__all: include/autoconf.mk include/autoconf.mk.depinclude include/config/auto.conf
include scripts/Kbuild.includeCC = $(CROSS_COMPILE)gcc
CPP = $(CC) -Einclude config.mk
include/autoconf.mk.dep: include/config.h FORCE$(call cmd,autoconf_dep)u-boot.cfg: include/config.h FORCE$(call cmd,u_boot_cfg)include/autoconf.mk: u-boot.cfg$(call cmd,autoconf)include/config.h: scripts/Makefile.autoconf create_symlink FORCE$(call filechk,config_h)create_symlink:
ifdef CONFIG_CREATE_ARCH_SYMLINK
ifneq ($(KBUILD_SRC),)$(Q)mkdir -p include/asm$(Q)if [ -d $(KBUILD_SRC)/arch/$(ARCH)/mach-$(SOC)/include/mach ]; then
\dest=arch/$(ARCH)/mach-$(SOC)/include/mach;
\else
\dest=arch/$(ARCH)/include/asm/arch-$(if $(SOC),$(SOC),$(CPU));
\fi;
\ln -fsn $(KBUILD_SRC)/$$dest include/asm/arch
else$(Q)if [ -d arch/$(ARCH)/mach-$(SOC)/include/mach ]; then \dest=../../mach-$(SOC)/include/mach; \else \dest=arch-$(if $(SOC),$(SOC),$(CPU)); \fi; \ln -fsn $$dest arch/$(ARCH)/include/asm/arch
endif
endif
编译配置时的log:
if [ -d arch/arm/mach-mx6/include/mach ]; then \dest=../../mach-mx6/include/mach; \
else \dest=arch-mx6; \
fi; \
//链接
ln -fsn $dest arch/arm/include/asm/arch//生成 include/config.h
set -e; : ' CHK include/config.h';
mkdir -p include/; (echo "/* Automatically generated - do not edit */"; for i in $(echo "IMX_CONFIG=board/freescale/mx6ullevk/imximage.cfg" | sed 's/,/ /g'); do echo \#define CONFIG_$i | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }';
done; echo \#define CONFIG_BOARDDIR board/freescale/mx6ullevk; echo \#include \<config_defaults.h\>; echo \#include \<config_uncmd_spl.h\>; echo \#include \<configs/"mx6ullevk".h\>;
echo \#include \<asm/config.h\>; echo \#include \<linux/kconfig.h\>; echo \#include \<config_fallbacks.h\>;) < scripts/Makefile.autoconf > include/config.h.tmp; if [ -r include/config.h ] && cmp -s include/config.h include/config.h.tmp;
then rm -f include/config.h.tmp; else : ' UPD include/config.h'; mv -f include/config.h.tmp include/config.h; fi//生成u-boot.cfg
arm-buildroot-linux-gnueabihf-gcc -E -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -O2 -fno-stack-protector -fno-delete-null-pointer-checks -g -fstack-usage -Wno-format-nonliteral -Werror=date-time -D__KERNEL__ -D__UBOOT__
-D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -msoft-float -pipe -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h
-nostdinc -isystem /home/zhuwg1/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin/../lib/gcc/arm-buildroot-linux-gnueabihf/7.5.0/include -DDO_DEPS_ONLY -dM ./include/common.h > u-boot.cfg.tmp &&
{ grep 'define CONFIG_' u-boot.cfg.tmp > u-boot.cfg; rm u-boot.cfg.tmp; } || { rm u-boot.cfg.tmp; false; }//生成include/autoconf.mk
sed -n -f ./tools/scripts/define2mk.sed u-boot.cfg | while read line; do if [ -n "" ] || ! grep -q "${line%=*}=" include/config/auto.conf; then echo "$line"; fi done > include/autoconf.mk//生成include/autoconf.mk.dep
arm-buildroot-linux-gnueabihf-gcc -x c -DDO_DEPS_ONLY -M -MP -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -O2 -fno-stack-protector -fno-delete-null-pointer-checks -g -fstack-usage -Wno-format-nonliteral -Werror=date-time
-D__KERNEL__ -D__UBOOT__ -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -msoft-float -pipe -Iinclude -I./arch/arm/include -include
./include/linux/kconfig.h -nostdinc -isystem /home/zhuwg1/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin/../lib/gcc/arm-buildroot-linux-gnueabihf/7.5.0/include -MQ include/config/auto.conf
./include/common.h > include/autoconf.mk.dep || { rm include/autoconf.mk.dep; false; }
touch include/config/auto.conf
两条指令流程及生成的文件: