目录
- 1.前言
- 2.目标依赖
- 3. 编译过程
- 3.1 include/config/%.conf目标(主Makefile)
- 3.2 include/config/uboot.release目标(主Makefile)
- 3.3 $(timestamp_h)目标(主Makefile)
- 3.4 $(version_h)目标(主Makefile)
- 3.5 prepare0目标(主Makefile)
- 3.6 u-boot.lds目标(主Makefile)
- 3.7 libs-y目标
- 3.8 u-boot目标(主Makefile)
- 3.9 u-boot.srec目标(主Makefile)
- 3.10 u-boot-nodtb.bin目标(主Makefile)
- 3.11 u-boot.sym目标(主Makefile)
- 3.12 u-boot.bin目标(主Makefile)
- 3.13 all目标(主Makefile)
- 4.readelf查看uboot.bin
1.前言
本文主要就Hi3556v200的U-boot+Liteos方案的编译流程做简要介绍,主要通过make过程的打印来逐步理清编译的过程,本文主要结合编译的打印信息介绍u-boot.bin的编译过程
U-boot版本:u-boot-2016.11
2.目标依赖
红色为主Makefile
蓝色为arch/arm/Makefile
3. 编译过程
自下而上分析编译流程,分析过程与实际编译流程略有出入,但基本按照实际的编译流程进行分析
3.1 include/config/%.conf目标(主Makefile)
通过make -p打印出head-y为 arch/arm/cpu/armv7/start.o
通过搜索可以在arch/arm/Makefile中搜索到head-y变量的定义
head-y := arch/arm/cpu/$(CPU)/start.o
通过主Makefile可以看到有如下的include:
ifeq ($(autoconf_is_old),)
include config.mk
include arch/$(ARCH)/Makefile
endif
在主Makefile中,有如下的定义:
u-boot-init := $(head-y)
这样就会编译arch/arm/cpu/armv7/start.o,调用规则为:
%.o: %.S prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
最终通过prepare依赖一步步会编译到include/config/%.conf目标:
include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
@# If the following part fails, include/config/auto.conf should be
@# deleted so "make silentoldconfig" will be re-run on the next build.
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \
{ rm -f include/config/auto.conf; false; }
@# include/config.h has been updated after "make silentoldconfig".
@# We need to touch include/config/auto.conf so it gets newer
@# than include/config.h.
@# Otherwise, 'make silentoldconfig' would be invoked twice.
$(Q)touch include/config/auto.conf
include/config/%.conf编译规则1
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
即make -f ./Makefile silentoldconfig, 编译主Makefile下的silentoldconfig目标
主Makefile中关于silentoldconfig目标的编译规则如下:
%config: scripts_basic outputmakefile FORCE
$(Q)$(MAKE) $(build)=scripts/kconfig $@
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
根据前面config编译分析,此处scripts_basic目标主要是编译fixdep工具,由于fixdep工具已经编译,因此不会执行动作
回到%config目标,将会执行它的编译规则:
$(Q)$(MAKE) $(build)=scripts/kconfig $@
即make -f ./scripts/Makefile.build obj=scripts/kconfig silentoldconfig
根据前面对config编译的说明,此处会进入到./scripts/Makefile.build文件,并在./scripts/Makefile.build文件中包含scripts/kconfig/Makefile, 然后编译它的silentoldconfig目标,silentoldconfig目标在scripts/kconfig/Makefile定义如下:
#scripts/kconfig/Makefile
silentoldconfig: $(obj)/conf
$(Q)mkdir -p include/config include/generated
$< $(silent) --$@ $(Kconfig)
编译规则为:
mkdir -p include/config include/generated
scripts/kconfig/conf --silentoldconfig Kconfig
先创建了include/config 和include/generated文件夹,通过conf工具:
在include/config下生成auto.conf和auto.conf.cmd,以及tristate.conf;
在include/generated下生成autoconf.h文件;
include/generated/autoconf.h 头文件由内核本身使用,主要用来预处理 C 代码。比如在 .config 或 auto.conf 中定义要编译为模块的项,如:
CONFIG_DEBUG_NX_TEST=m
在 autoconf.h 中会被定义为:
#define CONFIG_DEBUG_NX_TEST_ MODULE 1
注:整个编译过程有两处调用了conf工具: 第一次调用生成.config scripts/kconfig/conf
–defconfig=arch/…/configs/rpi_3_32b_defconfig Kconfig 第二次调用生成auto.conf和autoconf.h scripts/kconfig/conf --silentoldconfig
Kconfig
参考:https://blog.csdn.net/guyongqiangx/article/details/52679635?utm_source=blogxgwz6
include/config/%.conf编译规则2
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf
即
make -f ./scripts/Makefile.autoconf ||
{ rm -f include/config/auto.conf; false; }
会执行./scripts/Makefile.autoconf下的默认目标
#scripts/Makefile.autoconf
__all: include/autoconf.mk include/autoconf.mk.dep
# 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 = \
sed -n -f $(srctree)/tools/scripts/define2mk.sed $< | \
while read line; do \
if [ -n "${KCONFIG_IGNORE_DUPLICATES}" ] || \
! grep -q "$${line%=*}=" include/config/auto.conf; then \
echo "$$line"; \
fi \
done > $@
quiet_cmd_u_boot_cfg = CFG $@
cmd_u_boot_cfg = \
$(CPP) $(c_flags) $2 -DDO_DEPS_ONLY -dM $(srctree)/include/common.h > $@.tmp && { \
grep 'define CONFIG_' $@.tmp > $@; \
rm $@.tmp; \
} || { \
rm $@.tmp; false; \
}
include/autoconf.mk: u-boot.cfg
$(call cmd,autoconf)
u-boot.cfg: include/config.h FORCE
$(call cmd,u_boot_cfg)
include/autoconf.mk.dep: include/config.h FORCE
$(call cmd,autoconf_dep)
- 编译include/u-boot.cfg
- 编译include/autoconf.mk.dep
- 编译include/autoconf.mk
include/config/%.conf编译规则3
$(Q)touch include/config/auto.conf
更新include/config/auto.conf时间戳
3.2 include/config/uboot.release目标(主Makefile)
编译规则如下:
# Store (new) UBOOTRELEASE string in include/config/uboot.release
include/config/uboot.release: include/config/auto.conf FORCE
$(call filechk,uboot.release)
对uboot.release的版本进行检查
3.3 $(timestamp_h)目标(主Makefile)
timestamp_h := include/generated/timestamp_autogenerated.h
$(timestamp_h): $(srctree)/Makefile FORCE
$(call filechk,timestamp.h)
3.4 $(version_h)目标(主Makefile)
version_h := include/generated/version_autogenerated.h
$(version_h): include/config/uboot.release FORCE
$(call filechk,version.h)
3.5 prepare0目标(主Makefile)
prepare0: archprepare FORCE
$(Q)$(MAKE) $(build)=.
此编译规则展开为:
make -f ./scripts/Makefile.build obj=.
在/scripts/Makefile.build中有如下的定义:
# 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)
由于主目录下有kbuild文件,因此最终include $(kbuild-file)会包含主目录下的kbuild文件
之后将编译scripts/Makefile.build的默认目标_builld
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
@:
kbuild中有如下的定义
generic-offsets-file := include/generated/generic-asm-offsets.h
always := $(generic-offsets-file)
ifneq ($(wildcard $(srctree)/arch/$(ARCH)/lib/asm-offsets.c),)
offsets-file := include/generated/asm-offsets.h
endif
always += $(offsets-file)
$(obj)/$(generic-offsets-file): lib/asm-offsets.s FORCE
$(call filechk,offsets,__GENERIC_ASM_OFFSETS_H__)
$(obj)/$(offsets-file): arch/$(ARCH)/lib/asm-offsets.s FORCE
$(call filechk,offsets,__ASM_OFFSETS_H__)
编译生成arch/arm/lib/asm-offsets.s, lib/asm-offsets.s,这两个文件的作用(TODO)
检查include/generated/generic-asm-offsets.h是否是最新,如果不是最新则更新
检查include/generated/asm-offsets.h是否是最新,如果不是最新则更新
3.6 u-boot.lds目标(主Makefile)
u-boot.lds: $(LDSCRIPT) prepare FORCE
$(call if_changed_dep,cpp_lds)
# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
# that (or fail if absent). Otherwise, search for a linker script in a
# standard location.
ifndef LDSCRIPT
#LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds.debug
ifdef CONFIG_SYS_LDSCRIPT
# need to strip off double quotes
LDSCRIPT := $(srctree)/$(CONFIG_SYS_LDSCRIPT:"%"=%)
endif
endif
# If there is no specified link script, we look in a number of places for it
ifndef LDSCRIPT
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(srctree)/board/$(BOARDDIR)/u-boot.lds
endif
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(srctree)/$(CPUDIR)/u-boot.lds
endif
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(srctree)/arch/$(ARCH)/cpu/u-boot.lds
endif
endif
从实际打印来看使用了 arch/arm/cpu/u-boot.lds的链接脚本
3.7 libs-y目标
在主Makefile中关于libs-y变量的赋值如下,此处只列出了部分:
libs-y += lib/
libs-y += fs/
libs-y += net/
libs-y += disk/
libs-y += drivers/
libs-y += drivers/dma/
libs-y += drivers/gpio/
libs-y += drivers/i2c/
libs-y += drivers/mmc/
libs-y += drivers/mtd/
libs-$(CONFIG_CMD_NAND) += drivers/mtd/nand/
libs-y += drivers/mtd/onenand/
libs-$(CONFIG_CMD_UBI) += drivers/mtd/ubi/
libs-y += drivers/mtd/spi/
libs-y += drivers/net/
libs-y += drivers/net/phy/
libs-y += drivers/pci/
libs-y += drivers/power/ \
drivers/power/domain/ \
drivers/power/fuel_gauge/ \
drivers/power/mfd/ \
drivers/power/pmic/ \
drivers/power/battery/ \
drivers/power/regulator/
libs-y += drivers/spi/
libs-y += drivers/ddr/hisilicon/$(SOC)/
libs-y += drivers/serial/
libs-y += drivers/usb/dwc3/
libs-y += drivers/usb/common/
libs-y += drivers/usb/emul/
libs-y += drivers/usb/eth/
libs-y += drivers/usb/gadget/
libs-y += drivers/usb/gadget/hiudc3/
libs-y += drivers/usb/gadget/udc/
libs-y += drivers/usb/host/
libs-y += drivers/usb/musb/
libs-y += drivers/usb/musb-new/
libs-y += drivers/usb/phy/
libs-y += drivers/usb/ulpi/
libs-y += cmd/
libs-y += common/
libs-$(CONFIG_API) += api/
libs-$(CONFIG_HAS_POST) += post/
ifndef CONFIG_MINI_BOOT
libs-y += test/
libs-y += test/dm/
libs-$(CONFIG_UT_ENV) += test/env/
libs-$(CONFIG_UT_OVERLAY) += test/overlay/
由于主Makefile包含了arch/arm/Makefile,在后者中有如下的赋值:
libs-y += $(machdirs)
libs-y += arch/arm/cpu/$(CPU)/
libs-y += arch/arm/cpu/
libs-y += arch/arm/lib/
主Makefile对libs-y进行排序:
libs-y := $(sort $(libs-y))
主Makefile将最后一个"/"去掉,如arch/arm/lib/变为arch/arm/lib,保存到u-boot-dirs
u-boot-dirs := $(patsubst %/,%,$(filter %/, $(libs-y))) tools examples
u-boot-alldirs := $(sort $(u-boot-dirs) $(patsubst %/,%,$(filter %/, $(libs-))))
将xxx/替换为xxx/built-in.o,如如arch/arm/lib/变为arch/arm/lib/built-in.o
libs-y := $(patsubst %/, %/built-in.o, $(libs-y))
由于由如下的依赖关系,因此会触发$(u-boot-dirs)目标的编译
# The actual objects are generated when descending,
# make sure no implicit rule kicks in
$(sort $(u-boot-init) $(u-boot-main)): $(u-boot-dirs) ;
PHONY += $(u-boot-dirs)
$(u-boot-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@
这样就会进入$(u-boot-dirs)目录进行编译:
make -f ./scripts/Makefile.build obj=arch/arm/cpu
make -f ./scripts/Makefile.build obj=arch/arm/cpu/armv7
make -f ./scripts/Makefile.build obj=arch/arm/lib
make -f ./scripts/Makefile.build obj=board/hisilicon/hi3556v200
make -f ./scripts/Makefile.build obj=cmd
make -f ./scripts/Makefile.build obj=common
make -f ./scripts/Makefile.build obj=disk
make -f ./scripts/Makefile.build obj=drivers
make -f ./scripts/Makefile.build obj=fs
make -f ./scripts/Makefile.build obj=lib
make -f ./scripts/Makefile.build obj=net
make -f ./scripts/Makefile.build obj=product/himedia
make -f ./scripts/Makefile.build obj=test
make -f ./scripts/Makefile.build obj=lib/zlib
make -f ./scripts/Makefile.build obj=examples
3.8 u-boot目标(主Makefile)
主Makefile中有如下的u-boot目标编译规则:
# Rule to link u-boot
# May be overridden by arch/$(ARCH)/config.mk
quiet_cmd_u-boot__ ?= LD $@
cmd_u-boot__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_u-boot) -o $@ \
-T u-boot.lds $(u-boot-init) \
--start-group $(u-boot-main) --end-group \
$(PLATFORM_LIBS) -Map u-boot.map
u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE
$(call if_changed,u-boot__)
ifeq ($(CONFIG_KALLSYMS),y)
$(call cmd,smap)
$(call cmd,u-boot__) common/system_map.o
endif
if_changed的定义如下:
#scripts/kbuild.include
dot-target = $(dir $@).$(notdir $@)
# Execute command if command has changed or prerequisite(s) are updated.
#
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
其中$(any-prereq)定义如下:
#scripts/Kbuild.include
any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
?
表
示
所
有
比
目
标
还
要
新
的
依
赖
文
件
;
? 表示所有比目标还要新的依赖文件;
?表示所有比目标还要新的依赖文件;^ 表示所有的依赖文件,在 any-prereq 中,首先使用 $(filter-out
(
P
H
O
N
Y
)
,
(PHONY),
(PHONY),?) 将 $? 中的所有伪目标去掉,不然可能会将 FORCE 这种目标也带进来,如果此时返回非空,那么说明有比目标还要新的依赖文件。
$(wildcard $^) 匹配当前目录下的所有依赖文件(已经存在的),然后再使用 $(filter-out $(PHONY) $(wildcard
)
,
^),
),^) 将伪目标以及当前目录下匹配的文件列表从整个 $^ 列表中删除,如果返回不为空,那么说明某些依赖文件不存在,也就是说这些不存在的依赖文件还没生成 – 这是因为某些依赖文件需要在编译时才会生成
$(arg-check) 的定义如下:
#scripts/Kbuild.include
arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
$(filter-out $(cmd_$@), $(cmd_$(1))) )
在 arg-check 中,$(1) 表示第 1 个参数,比如上面的 KaTeX parse error: Expected group after '_' at position 24: …_changed,u-boot_̲_) 中,(1) 就是
u-boot__ ,所以 KaTeX parse error: Expected group after '_' at position 5: (cmd_̲(1) 就是表示 cmd_u-boot__ – 这个变量可以在上面主Makefile 中看到定义。它实际上表示的是这一次链接文件时所用到的链接参数。
$@ 表示目标文件,从上面叙述可知,它就是u-boot 。 KaTeX parse error: Expected group after '_' at position 5: (cmd_̲@) 就是表示 $(cmd_u-boot),而在主目录 .u-boot.cmd文件中我们看到了cmd_u-boot用来保存着上次编译的参数。在 arg-check 中,首先使用 $(filter-out KaTeX parse error: Expected group after '_' at position 5: (cmd_̲(1)), KaTeX parse error: Expected group after '_' at position 5: (cmd_̲@)) 将上一次的编译参数中过略掉本次要编译的参数,再用 $(filter-out KaTeX parse error: Expected group after '_' at position 5: (cmd_̲@), KaTeX parse error: Expected group after '_' at position 5: (cmd_̲(1))) 将本次的编译参数中过滤掉上一次的编译参数。正反过滤的原因是,filter-out 函数在过滤时,如果第 2 个参数是第 1 个参数的子集或者是相同,那么返回空;所以,在第 1 次过滤时如果返回为空,那么 cmd_KaTeX parse error: Expected group after '_' at position 12: @ 可能是等于 cmd_̲(1) 的,也可能是它的子集,所以只有当再次反过来做过滤时发现返回为空,那么才能判断两次编译的参数是相等的,否则是不等的。如果返回结果不为空,说明编译参数发生了变化,那么就会执行 $(cmd_u-boot__) 。
命令执行过程为:
arm-himix400-linux-ld.bfd -pie --gc-sections -Bstatic -Ttext 0x80800000 -o u-boot -T u-boot.lds arch/arm/cpu/armv7/start.o --start-group arch/arm/cpu/built-in.o arch/arm/cpu/armv7/built-in.o arch/arm/lib/built-in.o board/hisilicon/hi3556v200/built-in.o cmd/built-in.o common/built-in.o disk/built-in.o drivers/built-in.o drivers/ddr/hisilicon/hi3556v200/built-in.o drivers/dma/built-in.o drivers/gpio/built-in.o drivers/i2c/built-in.o drivers/mmc/built-in.o drivers/mtd/built-in.o drivers/mtd/onenand/built-in.o drivers/mtd/spi/built-in.o drivers/net/built-in.o drivers/net/phy/built-in.o drivers/pci/built-in.o drivers/power/built-in.o drivers/power/battery/built-in.o drivers/power/domain/built-in.o drivers/power/fuel_gauge/built-in.o drivers/power/mfd/built-in.o drivers/power/pmic/built-in.o drivers/power/regulator/built-in.o drivers/serial/built-in.o drivers/spi/built-in.o drivers/usb/common/built-in.o drivers/usb/dwc3/built-in.o drivers/usb/emul/built-in.o drivers/usb/eth/built-in.o drivers/usb/gadget/built-in.o drivers/usb/gadget/hiudc3/built-in.o drivers/usb/gadget/udc/built-in.o drivers/usb/host/built-in.o drivers/usb/musb-new/built-in.o drivers/usb/musb/built-in.o drivers/usb/phy/built-in.o drivers/usb/ulpi/built-in.o fs/built-in.o lib/built-in.o net/built-in.o product/himedia/built-in.o test/built-in.o test/dm/built-in.o --end-group arch/arm/lib/eabi_compat.o arch/arm/lib/lib.a -Map u-boot.map
如上的链接命令,显示链接地址为0x80800000,采用u-boot.lds链接脚本
可以看出如上命令的效果就是产生了u-boot文件
printf ‘%s\n’ ‘cmd_$@ := $(make-cmd)’ > ( d o t − t a r g e t ) . c m d ) 将 编 译 参 数 c m d _ u − b o o t : = (dot-target).cmd) 将编译参数cmd\_u-boot := (dot−target).cmd)将编译参数cmd_u−boot:=(make-cmd)保存到.u-boot.cmd 用于与下次编译时进行比较
总结 $(call if_changed,xxx_xxx)的用法: 如果依赖文件比目标新,或依赖文件不存在,或者命令参数发生变化, 会执行cmd_xxx_xxx ,同时将新的命令参数保存到$(dir> $@).$(notdir $@).cmd文件用于下次执行if_changed检查
3.9 u-boot.srec目标(主Makefile)
u-boot.srec有如下的编译规则:
u-boot.hex u-boot.srec: u-boot FORCE
$(call if_changed,objcopy)
根据前面对u-boot目标的分析,此处 $(call if_changed,objcopy)的含义为:
如果依赖文件u-boot比目标u-boot.srec新,或依赖文件u-boot不存在,或者命令参数发生变化,会执行cmd_objcopy,同时将新的命令参数保存到$(dir $@).$(notdir $@).cmd文件用于下次执行if_changed检查
# Normally we fill empty space with 0xff
quiet_cmd_objcopy = OBJCOPY $@
cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
$(OBJCOPYFLAGS_$(@F)) $< $@
arm-himix400-linux-objcopy --gap-fill=0xff -j .text -j .secure_text -j .image -j .secure_data -j .rodata -j .hash -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn -O srec u-boot u-boot.srec
将srec u-boot文件转换为u-boot.srec
3.10 u-boot-nodtb.bin目标(主Makefile)
u-boot-nodtb.bin: u-boot FORCE
$(call if_changed,objcopy)
$(call DO_STATIC_RELA,$<,$@,$(CONFIG_SYS_TEXT_BASE))
$(BOARD_SIZE_CHECK)
根据前面对u-boot目标的分析,此处 $(call if_changed,objcopy)的含义为:
如果依赖文件u-boot比目标u-boot-nodtb.bin新,或依赖文件u-boot不存在,或者命令参数发生变化,会执行cmd_objcopy,同时将新的命令参数保存到$(dir $@).$(notdir $@).cmd文件用于下次执行if_changed检查
arm-himix400-linux-objcopy --gap-fill=0xff -j .text -j .secure_text -j .image -j .secure_data -j .rodata -j .hash -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn -O binary u-boot u-boot-nodtb.bin
3.11 u-boot.sym目标(主Makefile)
quiet_cmd_sym ?= SYM $@
cmd_sym ?= $(OBJDUMP) -t $< > $@
u-boot.sym: u-boot FORCE
$(call if_changed,sym)
arm-himix400-linux-objdump -t u-boot > u-boot.sym
生成u-boot.sym符号表文件
3.12 u-boot.bin目标(主Makefile)
ifeq ($(CONFIG_OF_SEPARATE),y)
u-boot-dtb.bin: u-boot-nodtb.bin dts/dt.dtb FORCE
$(call if_changed,cat)
u-boot.bin: u-boot-dtb.bin FORCE
$(call if_changed,copy)
else
u-boot.bin: u-boot-nodtb.bin FORCE
$(call if_changed,copy)
endif
根据前面对u-boot目标的分析,此处 $(call if_changed,objcopy)的含义为:
如果依赖文件u-boot-nodtb.bin比目标u-boot.bin新,或依赖文件u-boot-nodtb.bin不存在,或者命令参数发生变化,会执行cmd_objcopy,同时将新的命令参数保存到$(dir $@).$(notdir $@).cmd文件用于下次执行if_changed检查
# Normally we fill empty space with 0xff
quiet_cmd_objcopy = OBJCOPY $@
cmd_objcopy = $(OBJCOPY) --gap-fill=0xff $(OBJCOPYFLAGS) \
$(OBJCOPYFLAGS_$(@F)) $< $@
cp u-boot-nodtb.bin u-boot.bin
3.13 all目标(主Makefile)
all: $(ALL-y)
ifeq ($(CONFIG_DM_I2C_COMPAT)$(CONFIG_SANDBOX),y)
@echo "===================== WARNING ======================"
@echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove"
@echo "(possibly in a subsequent patch in your series)"
@echo "before sending patches to the mailing list."
@echo "===================================================="
endif
@# Check that this build does not use CONFIG options that we do not
@# know about unless they are in Kconfig. All the existing CONFIG
@# options are whitelisted, so new ones should not be added.
$(srctree)/scripts/check-config.sh u-boot.cfg \
$(srctree)/scripts/config_whitelist.txt ${srctree} 1>&2
./scripts/check-config.sh u-boot.cfg
./scripts/config_whitelist.txt . 1>&2
4.readelf查看uboot.bin
ubuntu@ct-srv12:~/Hi3559V200_SmartCam_V5.0.0.1/osdrv/opensource/uboot/u-boot-2016.11$ arm-himix100-linux-readelf -S u-boot
There are 33 section headers, starting at offset 0x234eac:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 80800000 008000 02e2d4 00 AX 0 0 32
[ 2] .__secure_start PROGBITS 8082e2d4 0362d4 000000 00 WA 0 0 1
[ 3] .secure_text PROGBITS 8082e2e0 0362e0 000108 00 AX 0 0 32
[ 4] .__secure_end PROGBITS 8082e3e8 0363e8 000004 00 WA 0 0 1
[ 5] .rodata PROGBITS 8082e3ec 0363ec 00c947 00 A 0 0 4
[ 6] .hash HASH 8083ad34 042d34 000018 04 A 15 0 4
[ 7] .image PROGBITS 8083ad4c 042d4c 004268 00 A 0 0 1
[ 8] .data PROGBITS 8083efb4 046fb4 004390 00 WA 0 0 4
[ 9] .got.plt PROGBITS 80843344 04b344 00000c 04 WA 0 0 4
[10] .u_boot_list PROGBITS 80843350 04b350 00073c 00 WA 0 0 4
[11] .rel.dyn REL 80843a8c 04ba8c 0083a0 08 A 15 0 4
[12] .bss_start PROGBITS 80843a8c 053f1c 000000 00 W 0 0 1
[13] .bss NOBITS 80843a8c 000000 04e4d8 00 WA 0 0 64
[14] .bss_end PROGBITS 80891f64 053f1c 000000 00 W 0 0 1
[15] .dynsym DYNSYM 8084be2c 053e2c 000030 10 A 16 3 4
[16] .dynstr STRTAB 8084be5c 053e5c 000001 00 A 0 0 1
[17] .dynamic DYNAMIC 8084be60 053e60 000090 08 WA 16 0 4
[18] .interp PROGBITS 8084bef0 053ef0 000011 00 A 0 0 1
[19] .gnu.hash GNU_HASH 8084bf04 053f04 000018 04 A 15 0 4
[20] .ARM.attributes ARM_ATTRIBUTES 00000000 053f1c 00002d 00 0 0 1
[21] .comment PROGBITS 00000000 053f49 00002d 01 MS 0 0 1
[22] .debug_line PROGBITS 00000000 053f76 0227ad 00 0 0 1
[23] .debug_info PROGBITS 00000000 076723 103f86 00 0 0 1
[24] .debug_abbrev PROGBITS 00000000 17a6a9 0257f4 00 0 0 1
[25] .debug_aranges PROGBITS 00000000 19fea0 003ef0 00 0 0 8
[26] .debug_str PROGBITS 00000000 1a3d90 0167a0 01 MS 0 0 1
[27] .debug_frame PROGBITS 00000000 1ba530 00ada4 00 0 0 4
[28] .debug_loc PROGBITS 00000000 1c52d4 04d62e 00 0 0 1
[29] .debug_ranges PROGBITS 00000000 212908 008628 00 0 0 8
[30] .symtab SYMTAB 00000000 21af30 0126f0 10 31 3744 4
[31] .strtab STRTAB 00000000 22d620 007749 00 0 0 1
[32] .shstrtab STRTAB 00000000 234d69 000143 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
y (purecode), p (processor specific)