文章目录
make xxx_defconfig
生成.config文件
make xxx_defconfig的目标就是生成.config文件。
通过命令:scripts/kconfig/conf --defconfig=configs/xxx_defconfig Kconfig,生成.config文件。
conf为主机上的可执行文件,由scripts/kconfig目录下的conf.c和zconf.tab.c生成,功能为解析defconfig和Kconfig文件,将其中的符号生成到.config文件中。
make xxx_defconfig在makefile中的执行过程如下:
- make xxx_defconfig实际执行 make-f scripts/Makefile.buid obj=scripts/kconfig xxx_defconfig,如下所示:
build=-f scripts/Makefile.buid obj=
%config: scripts_basic FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
- 执行make-f scripts/Makefile.buid obj=scripts/kconfig xxx_defconfig时,Makefile.build会包含scripts/kconfig/Makefile,如下所示:
# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)
- 而xxx_defconfig目标正是定义在scripts/kconfig/Makefile中,如下所示:
# Added for U-Boot
# Linux has defconfig files in arch/$(SRCARCH)/configs/,
# on the other hand, U-Boot does in configs/.
# Set SRCARCH to .. fake this Makefile.
SRCARCH := ..
%_defconfig: $(obj)/conf
$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
- 上诉语句会执行命令:scripts/kconfig/conf --defconfig=configs/xxx_defconfig Kconfig
conf的代码没有深究,理解Kconfig文件的规则也能大概理解.config文件的生成逻辑。
make
生成配置文件
概述
生成的主要配置文件如下:
include/config/auto.conf
include/autoconf.mk
include/generated/autoconf.h
其中,include/config/auto.conf来自于.config文件,是.config文件去掉注释后的配置,为编译过程所用。
include/autoconf.mk来自于incluce/common.h,包含了uboot中c头文件的配置,为编译过程所用。
include/generated/autoconf.h来自于include/config/auto.conf,是将auto.conf的配置转化为c语言的宏定义,为uboot源代码所用。
生成配置文件的主要代码如下:
# Read in config
-include include/config/auto.conf
include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf
all:
make all时,如果include/config/auto.conf文件不存在,那么include/config/%.conf目标下的规则会被执行,即使include/config/%.conf没有被all依赖。之后再执行all目标,此时会重新包含include/config/auto.conf文件里面的内容。
include/config/%.conf目标规则的功能如下:
1、执行 make silentoldconfig,生成include/config/auto.conf和include/generated/autoconf.h。
2、执行 make -f scripts/Makefile.autoconf,生成 include/autoconf.mk。
make silentoldconfig
执行 make silentoldconfig与执行make xxx_defconfig类似,silentoldconfig目标也是定义在scripts/kconfig/Makefile中,如下所示:
silentoldconfig: $(obj)/conf
$(Q)mkdir -p include/config include/generated
$< $(silent) --$@ $(Kconfig)
上诉语句会执行命令:scripts/kconfig/conf --silentoldconfig Kconfig
make -f scripts/Makefile.autoconf
Makefile.autoconf的目标主要是生成include/config.h和include/autoconf.mk,代码如下:
__all: include/autoconf.mk include/autoconf.mk.dep
include/autoconf.mk include/autoconf.mk.dep \
spl/include/autoconf.mk tpl/include/autoconf.mk: include/config.h
include/config.h一个重要的功能就是指明了需要包含的板级预配置头文件:include/configs/$(CONFIG_SYS_CONFIG_NAME).h.
其中,CONFIG_SYS_CONFIG_NAME在第一步make xxx_defconfig中已经生成到.config文件中。
- 生成 include/config.h的代码如下所示:
# include/config.h
# Prior to Kconfig, it was generated by mkconfig. Now it is created here.
define filechk_config_h
(echo "/* Automatically generated - do not edit */"; \
for i in $$(echo $(CONFIG_SYS_EXTRA_OPTIONS) | sed 's/,/ /g'); do \
echo \#define CONFIG_$$i \
| sed '/=/ {s/=/ /;q; } ; { s/$$/ 1/; }'; \
done; \
echo \#define CONFIG_BOARDDIR board/$(if $(VENDOR),$(VENDOR)/)$(BOARD);\
echo \#include \<config_defaults.h\>; \
echo \#include \<config_uncmd_spl.h\>; \
echo \#include \<configs/$(CONFIG_SYS_CONFIG_NAME).h\>; \
echo \#include \<asm/config.h\>; \
echo \#include \<config_fallbacks.h\>;)
endef
include/config.h: scripts/Makefile.autoconf create_symlink FORCE
$(call filechk,config_h)
autoconf.mk来源于include/common.h,而通过如下文件包含关系,获取了板级预配置头文件的所有宏定义
include/common.h -> include/config.h -> include/configs/$(CONFIG_SYS_CONFIG_NAME).h
- 生成autoconf.mk的代码如下所示:
# We are migrating from board headers to Kconfig little by little.
# In the interim, we use both of
# - include/config/auto.conf (generated by Kconfig)
# - include/autoconf.mk (used in the U-Boot conventional configuration)
# The following rule creates autoconf.mk
# include/config/auto.conf is grepped in order to avoid duplication of the
# same CONFIG macros
quiet_cmd_autoconf = GEN $@
cmd_autoconf = \
$(CPP) $(c_flags) $2 -DDO_DEPS_ONLY -dM $(srctree)/include/common.h > $@.tmp && { \
sed -n -f $(srctree)/tools/scripts/define2mk.sed $@.tmp | \
while read line; do \
if [ -n "${KCONFIG_IGNORE_DUPLICATES}" ] || \
! grep -q "$${line%=*}=" include/config/auto.conf; then \
echo "$$line"; \
fi \
done > $@; \
rm $@.tmp; \
} || { \
rm $@.tmp; false; \
}
include/autoconf.mk: FORCE
$(call cmd,autoconf)
生成u-boot.bin
生成elf文件和bin文件
u-boot为生成的elf文件;u-boot.bin为u-boot去除符号表后的二进制文件。它们的依赖关系如下所示:
u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE
$(call if_changed,u-boot__)
u-boot-nodtb.bin: u-boot FORCE
$(call if_changed,objcopy)
$(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))
u-boot.bin: u-boot-nodtb.bin FORCE
$(call if_changed,copy)
u-boot主要依赖u-boot-init和u-boot-main,两者在主makefile中定义。
arch/arm/Makefile(被主makefile包含):
head-y := arch/arm/cpu/$(CPU)/start.o
libs-y += arch/arm/cpu/$(CPU)/
libs-y += arch/arm/cpu/
libs-y += arch/arm/lib/
......
主makefile:
include arch/$(ARCH)/Makefile
libs-y += lib/
libs-y += fs/
libs-y += net/
libs-y += disk/
libs-y += drivers/
libs-$(CONFIG_UT_ENV) += test/env/
libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
......
u-boot-init := $(head-y)
u-boot-main := $(libs-y)
$(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ;
u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples
u-boot-dirs代表了libs-y中包含的所有目录,为u-boot-init和u-boot-main所依赖。
而u-boot-dirs中每个目录的标规是:
make -f scripts/Makefile.buid obj=$(dir)
该规则功能是将该目录下的待编译c文件编译打包成一个built-in.o文件。
$(u-boot-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@
Makefile.build
make -f scripts/Makefile.buid obj=$(dir),来编译某个目录,生成该目录的built-in.o文件。
分析生成built-in.o的过程,Makefile.buid可简化为
src := $(obj)
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
@:
builtin-target := $(obj)/built-in.o
$(builtin-target): $(obj-y) FORCE
$(call if_changed,link_o_target)
$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
$(call if_changed_rule,cc_o_c)
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
subdir-ym := $(sort $(subdir-y) $(subdir-m))
$(subdir-ym):
$(Q)$(MAKE) $(build)=$@
Makefile.build首先包括当前目录($(obj)取值的目录)的Makefile,该Makfile中会定义obj-y,可能是文件,也可能是目录,代表需要编译的文件和子目录。如下所示:
src := $(obj)
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)
Makefile.build的目标为__build,它依赖于 ( o b j ) / b u i l t − i n . o ,而 (obj)/built-in.o,而 (obj)/built−in.o,而(obj)/built-in.o又依赖于$(obj-y)。
当obj-y为xxx.o时,通过c文件编译,如下所示:
$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
$(call if_changed_rule,cc_o_c)
当obj-y为xxx/时,代表一个子目录,则递归调用Makefile.build,进一步编译该子目录。如下所示:
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
subdir-ym := $(sort $(subdir-y) $(subdir-m))
$(subdir-ym):
$(Q)$(MAKE) $(build)=$@



1万+

被折叠的 条评论
为什么被折叠?



