一、编译处理过程
1、make distclean清理工程(可以在顶层makefile中搜索)
(1)make中命令行前面加上at符号@
就是,在make执行时候,输出的信息中,不要显示此行命令。
而正常情况下,make执行过程中,都是会显示其所执行的任何的命令的。如果你不想要显示某行的命令,那么就在其前面加上@符号即可。
(2)Find,rm
Linux 下shell的find 命令用来在指定目录下查找文件. Linux rm命令用于删除一个文件或者目录
2、make mx6ull_14x14_ddr512_emmc_defconfig这条指令的执行过程
make xxx_defconfig的规则
%config: scripts_basic outputmakefile FORCE
(
Q
)
(Q)
(Q)(MAKE) $(build)=scripts/kconfig $@
知识点1
目标…… : 依赖文件集合……
命令 1
命令 2
……
知识点2
FORCE 是没有规则和依赖的,所以每次都会重新生成 FORCE。当 FORCE 作为
其他目标的依赖时,由于 FORCE 总是被更新过的,因此依赖所在的规则总是会执行的
知识点3
规则即存在文件scripts_basic 和outputmakefile时,执行命令,便可生成%config
知识点4
shell命令make -f ./scripts/Makefile.build obj=scripts/basic中-f是make的参数,=是makefile中给变量赋值的。用=第一次定义后的变量,后面的再次定义在这些再次定义和第一次定义之间只用第一次定义的内容,即在这个区间内第一次定义的什么就是什么
3、目标%config的makefile规则的依赖
(1)%config依赖文件1,问题是文件scripts_basic如何来
(a)scripts_basic的规则
scripts_basic:
(
Q
)
(Q)
(Q)(MAKE) $(build)=scripts/basic
因为目标scripts_basic的生成规则是一条命令,所以执行命令
(
Q
)
(Q)
(Q)(MAKE)
(
b
u
i
l
d
)
=
s
c
r
i
p
t
s
/
b
a
s
i
c
即可生成
s
c
r
i
p
t
s
b
a
s
i
c
不管是否在终端输出完整的命令后为:
(build)=scripts/basic即可生成scripts_basic 不管是否在终端输出完整的命令后为:
(build)=scripts/basic即可生成scriptsbasic不管是否在终端输出完整的命令后为:(MAKE) $(build)=scripts/basic
eaidk@ubuntu:~$ make -help
Usage: make [options] [target] ...
Options:
-b, -m 忽略兼容性。
......略...... ....
-f FILE, --file=FILE, --makefile=FILE 将FILE读取为makefile。
......略......
(b)scripts_basic的规则中的变量build
build定义在scripts\Kbuild.include
build := -f
(
s
r
c
t
r
e
e
)
/
s
c
r
i
p
t
s
/
M
a
k
e
f
i
l
e
.
b
u
i
l
d
o
b
j
因为
(srctree)/scripts/Makefile.build obj因为
(srctree)/scripts/Makefile.buildobj因为(srctree)为“.”,所以在$(MAKE) $(build)=scripts/basic中,
build为-f ./scripts/Makefile.build obj
( c)总结
生成目标scripts_basic要执行:make -f ./scripts/Makefile.build obj=scripts/basic
(2)%config依赖文件2,问题是文件outputmakefile如何来
在KBUILD_SRC为空时,outputmakefile无效。
即在KBUILD_SRC为空时,当outputmakefile不存在。
4、目标%config的makefile规则的命令
生成目标%config最终要执行的命令
Make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
上面分析出生成目标%config要执行两条命令。
两条命令最终都与文件./scripts/Makefile.build打交道,即与Makefile.build打交道分析Makefile.build
(1)第一条命令:(命令的结果最终是编译scripts/basic/fixdep.c)
(a)
)makefile是文件依赖规则
给make 命令指定一个特殊名字的Makefile。make –f 特殊名字的Makefile
make -f ./scripts/Makefile.build obj=scripts/basic
( b)
① Makefile.build定义了一些变量(用echo)得到一些变量值:
src = scripts/basic
kbuild-dir = ./scripts/basic
kbuild-file = ./scripts/basic/Makefile
② Makefile.build包含子Makefile:include ./scripts/basic/Makefile
③ Makefile.build指出默认目标为__build
( c)
因为命令“@make -f ./scripts/Makefile.build obj=scripts/basic”没有指定目标,所以会使用到默认目标: __build。
__build: $(if
(
K
B
U
I
L
D
B
U
I
L
T
I
N
)
,
(KBUILD_BUILTIN) ,
(KBUILDBUILTIN),(builtin-target) $(lib-target) $(extra-y))
$(if
(
K
B
U
I
L
D
M
O
D
U
L
E
S
)
,
(KBUILD_MODULES) ,
(KBUILDMODULES),(obj-m) $(modorder-target))
$(subdir-ym) $(always)
@:
(d)
(用echo)因为此时KBUILD_BUILTIN为1。
KBUILD_MODULES为空
所以__build: $(builtin-target) $(lib-target) $(extra-y) $(subdir-ym) $(always)
@:
(e)
(用echo)又因为builtin-target ,lib-target ,extra-y为空。Always为scripts/basic/fixdep
(f)总结
所以__build:scripts/basic/fixdep
因此需要编译出scripts/basic/fixdep,对应的.c是scripts/basic/fixdep.c,
编译scripts/basic/fixdep.c
(2)第二条命令:(命令的结果最终是生成.config 文件)
Make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
(a)
分析Makefile.build(用echo)得到一些变量值:
src= scripts/kconfig
kbuild-dir = ./scripts/kconfig
kbuild-file = ./scripts/kconfig/Makefile
include ./scripts/kconfig/Makefile
(b)
%_defconfig: $(obj)/conf
(
Q
)
(Q)
(Q)<
(
s
i
l
e
n
t
)
−
−
d
e
f
c
o
n
f
i
g
=
a
r
c
h
/
(silent) --defconfig=arch/
(silent)−−defconfig=arch/(SRCARCH)/configs/$@
(
K
c
o
n
f
i
g
)
展开
(Kconfig) 展开
(Kconfig)展开(obj)/conf后检查并生成依赖 scripts/kconfig/conf,不要纠结conf 是怎么编译出来的,很难,一般没有必有
不要纠结 conf 是怎么编译出来的,否则就越陷越深,太绕了,像 conf 这种主机所使用的工具类软件我们一般不关心它是如何编译产生的。如果一定要看是 conf 是怎么生成的,可以输入如下命令重新配置 uboot,在重新配置 uboot 的过程中就会输出 conf 编译信息。
©
将其代值展开就是:
xxx_defconfig: scripts/kconfig/conf
scripts/kconfig/conf --defconfig=arch/…/configs/ xxx_defconfig Kconfig
将mx6ull_alientek_emmc_defconfig 中的配置输出到.config 文件中,最终生成 uboot 根目录下的.config 文件
二、 make V=1 -j12 (据规则统计哪些要编译后再编译)
(1)make V=1 -j12没有指定目标,_ _all就是默认目标
如 果 KBUILD_EXTMOD 为 空 的 话 _all 依 赖 于 all 。 这 里 不 编 译 模 块 , 所 以KBUILD_EXTMOD 肯定为空, _all 的依赖就是 all。
PHONY := _all
_all:
_all: all
all: $(ALL-y)
(2) u-boot.bin
ALL-y += u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg binary_size_check
ALL-y 里面有个 u-boot.bin,这个就是我们最终需要的 uboot 二进制可执行文件,所作的所有工作就是为了它。
(3) u-boot.bin的生成规则
u-boot.bin: u-boot-nodtb.bin FORCE
$(call if_changed,copy)
u-boot-nodtb.bin: u-boot FORCE
$(call if_changed,objcopy)
$(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))
$(BOARD_SIZE_CHECK)
u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE
$(call if_changed,u-boot__)
u-boot-init := $(head-y)
u-boot-main := $(libs-y)
head-y= arch/arm/cpu/armv7/start.o
(4)libs-y=保存源码的目录
libs-y += lib/ 即lib/built-in.o
libs-y保存大量的built-in.o
u-boot就是将start.o 和大量的built-in.o链接在一起。
假如
CONFIG_ONENAND_U_BOOT =y
ALL-$(CONFIG_ONENAND_U_BOOT)
ALL-y += u-boot-onenand.bin
三、链接
链接脚本为u-boot.lds,uboot链接首地址为0X87800000,
在mx6_common.h文件中设置CONFIG_SYS_TEXT_BASE=0X87800000