Overview
This article is based on the U-boot Raspberry Pi 3 Generation configuration Process Analysis, the environment is as follows:
Compilation environment: Ubuntu 14.04 LTS
Compilation tool: ARM-LINUX-GNUEABI-GCC
Code version: U-boot v2016.09
Configuration file: Rpi_3_32b_defconfig
U-boot the introduction of Kbuild systems since the v2014.10 version, Makefile's management and organization is much different from previous versions of the Code, and its makefile is more complex. The whole makefile, nested a lot of other different uses of makefile, a variety of goals and dependencies are also many, make analysis is easy to get stuck in, let a person can not touch the mind.
The configuration commands that are covered in this article:
Make Rpi_3_32b_defconfig
instance Execution configuration command
The compilation of U-boot is performed in two steps, as with the kernel compilation:
-First step: Configure, perform make xxx_defconfig configuration, generate. config file
-Part II: Compile, perform make to compile, generate executable binaries U-boot.bin or u-boot.elf
Let's start with the simple make defconfig configuration process.
Command Line Input:
Make Rpi_3_32b_defconfig V=1
The compiled output is as follows:
Configuration Command parameter Description:
-Rpi_3_32b_defconfig is a Raspberry Pi 3 generation 32-bit compiled configuration file
-V=1 indicates that the compilation displays verbose output. Default v=0, compilation displays only the necessary brief information
From the output log, make Rpi_3_32b_defconfig's execution is divided into 3 parts, as shown on the chart:
-1. Execute make-f./scripts/makefile.build obj=scripts/basic, compile build SCRIPTS/BASIC/FIXDEP tool
-2. Execute make-f./scripts/makefile.build obj=scripts/kconfig Rpi_3_32b_defconfig Compile build scripts/kconfig/conf tool
-3. Perform scripts/kconfig/conf--defconfig=arch/. /configs/rpi_3_32b_defconfig Kconfig generate the final. config profile
The contents of the folder are changed as follows when you execute make rpi_3_32b_defconfig compared to the original code:
The file to be used for subsequent compilation is. config. detailed configuration Process Analysis
To get to the point, the entire configuration process is designed to generate a. config file, which is detailed below to analyze how the. config file is generated step-by-step.
The core of makefile is dependence and command. For each target, the dependency is checked first, and if the dependency exists, the command update target is executed, and if the dependency does not exist, the dependency is the target, and the dependency is made, and the command generation target is then executed after the build is dependent. 1. Top-level make defconfig rules
When you execute the make Xxx_defconfig command, there is a unique rule matching target in Makefile in the U-boot root directory:
%config:scripts_basic outputmakefile Force
$ (Q) $ (make) $ (build) =scripts/kconfig $@
For the target, Rpi_3_32b_defconfig, the expansion is:
Rpi_3_32b_defconfig:scripts_basic outputmakefile Force
$ (Q) $ (make) $ (build) =scripts/kconfig rpi_3_32b_ Defconfig
where $ (build) is defined in Kbuild.include:
Build: =-F $ (srctree)/scripts/makefile.build obj
i. Reliance on Scripts_basic
Dependent Scripts_basic:
# Basic helpers built in scripts/
phony + scripts_basic
scripts_basic:
$ (Q) $ (make) $ (build) =scripts/basic
$ (Q) rm-f. Tmp_quiet_recordmcount
There is no further dependency on the Scripts_basic, the following rules are expanded:
Scripts_basic:
$ (q) make-f./scripts/makefile.build obj=scripts/basic
$ (q) rm-f. Tmp_quiet_recordmcount
II. RELIANCE on Outputmakefile
Dependent Outputmakefile:
Phony + = Outputmakefile
# outputmakefile generates a Makefile in the output directory, if using a
# separate OUTPU T directory. This allows convenient with the 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
Outputmakefile also has no further reliance.
If you execute the following command:
Make Rpi_3_32b_defconfig O=out
Then all the generated targets will be placed in the out directory, and a makefile to the out directory will be compiled by Outputmakefile.
Because it is compiled under the current directory, $ (KBUILD_SRC) is empty and you do not need to export the makefile file, Outputmakefile is an empty destination. Iii. reliance on force
Reliance Force:
Phony + = force Force
:
Force is defined as an empty target.
If a target adds force dependency, each compilation will go to force (actually doing nothing) and then run the command to update the target, which will ensure that the target is updated every time. Here is also the command to ensure that the target rpi_3_32b_defconfig:
$ (Q) $ (make) $ (build) =scripts/kconfig Rpi_3_32b_defconfig
Always be able to be executed.
The above is the rpi_3_32b_defconfig of all dependencies, analysis of the dependency after the analysis of the command. 2. Commands for top-level make defconfig i. Commands that depend on Scripts_basic
Of the three dependent scripts_basic,outputmakefile and force of the target rpi_3_32b_defconfig, only scripts_basic need to execute the command, as follows
Scripts_basic:
$ (q) make-f./scripts/makefile.build obj=scripts/basic
$ (q) rm-f. Tmp_quiet_recordmcount
The make command then goes to the file Scripts/makefile.build to execute.
First call Scripts/makefile.build to compile
The beginning of the file Script/makefile.build is set Src=scripts/basic according to the incoming obj=scripts/basic parameter:
Prefix: = TPL
src: = $ (patsubst $ (prefix)/%,%,$ (obj))
ifeq ($ (obj), $ (src))
prefix: = SPL
src: = $ ( Patsubst $ (prefix)/%,%,$ (obj))
ifeq ($ (obj), $ (src))
prefix: =.
endif
endif
Then search for the makefile under the/$ (SRC) subdirectory of the $ (srctree), and include it in:
# The filename kbuild have 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)
This expands the replacement after the equivalent:
Include./scripts/basic/makefile
The tools FIXDEP compiled on the host are defined in file Scripts/basic/makefile:
Hostprogs-y: = Fixdep
always : = $ (hostprogs-y)
# FIXDEP are needed to compile other host programs
$ (addpre Fix $ (obj)/,$ (filter-out fixdep,$ (always)): $ (obj)/FIXDEP
Tool FIXDEP is used to update the dependent file *.cmd for each build target.
The $ (always) defined above will be added to the targets in Scripts/makefile.build:
Targets + = $ (extra-y) $ (makecmdgoals) $ (always)
on how to compile the executable program on the host, it will be analyzed in another article.
In short, the Scripts_basic rules
Scripts_basic:
$ (Q) make-f./scripts/makefile.build Obj=scripts/basic
The end result is to compile the executable file FIXDEP on the SCRIPTS/BASIC/FIXDEP.C build host. As for why compiling FIXDEP and how to use FIXDEP, it will be analyzed in another article. ii. commands for top-level rpi_3_32b_defconfig
After the update to the dependent Scripts_basic is complete, the next step is to perform the command for the top-level target to complete the update to the Rpi_3_32b_defconfig, with the following rules:
Rpi_3_32b_defconfig:scripts_basic outputmakefile Force
make-f./scripts/makefile.build obj= scripts/kconfig Rpi_ 3_32b_defconfig
where $ (build) is defined in Kbuild.include:
# #
# # shorthand for $ (q) $ (make)-F scripts/makefile.build obj=
# Usage:
# $ (q) $ (make) $ (build) =dir
Build: =-F $ (srctree)/scripts/makefile.build obj
This make command will be transferred to scripts/makefile.build the second time to execute.
second call to Scripts/makefile.build for compilation
The beginning of the file Script/makefile.build is set src=scripts/kconfig based on the incoming obj=scripts/kconfig parameter. Then search for makefile under the/$ (SRC) subdirectory of the $ (srctree), because the Src=scripts/kconfig parameter differs from the first called parameter (src=scripts/basic). The makefile included here are also different from the first makefile:
# The filename kbuild have 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)
Here the substitution expands to the equivalent of:
Include./scripts/kconfig/makefile
The target of all matching%config is defined in file Scripts/kconfig/makefile:
Phony + = xconfig gconfig menuconfig config silentoldconfig update-po-config \
localmodconfig localyesconfig
Phony + = Oldnoconfig savedefconfig defconfig
phony + kvmconfig
phony + = Tinyconfig
For the incoming rpi_3_32b_defconfig here, the target of the match is:
%_defconfig: $ (obj)/conf
$ (Q) $< $ (silent)--defconfig=arch/$ (Srcarch)/configs/$@ $ (Kconfig)
Expand to:
Rpi_3_32b_defconfig:scripts/kconfig/conf
$ (Q) scripts/kconfig/conf --defconfig=arch/. /configs/rpi_3_32b_defconfig Kconfig
The target rpi_3_32b_defconfig here depends on scripts/kconfig/conf, and then the dependencies are checked and generated.
Hostprogs-y: = conf nconf mconf kxgettext qconf gconf
Hostprogs-y points out that Conf is defined as a program executed on a host that relies on another two files:
Conf-objs : = CONF.O ZCONF.TAB.O
Generate CONF-OBJS by compiling CONF.C and ZCONF.TAB.C, and link to scripts/kconfig/conf.
The build dependency is the command that executes the target:
$ (Q) scripts/kconfig/conf --defconfig=arch/. /configs/rpi_3_32b_defconfig Kconfig
The operation of the tool scripts/kconfig/conf is analyzed in a separate article, where only a brief description is made:
The Conf tool reads the default Kconfig file from the root directory, parses its configuration, and stores it in memory. After parsing the default kconfig, read the specified file (that is, arch/). /configs/rpi_3_32b_defconfig) updated to get the final symbol table and output to the. config file.
This completes the analysis of all dependencies and commands involved in make Rpi_3_32b_defconfig execution configuration. Make defconfig configuration flow Diagram
The entire configuration process is more verbose and can be represented by a simple dependency graph, as follows:
(You can drag a picture to another window in your browser to see a larger view)