使用如何阅读U-Boot的Makefile中的方法我们同样可以获取make_boot_compile.log.1
,下面是其中内容的详细解释。
目标autoconf.mk和autoconf.mk.dep
make[1]: Entering directory `/disk2/boot'
Generating include/autoconf.mk
Generating include/autoconf.mk.dep
make[1]: Leaving directory `/disk2/boot'
在boot/Makefile
中有
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk
虽然boot/Makefile
中有两个all
目标,但是在执行make时首先会执行第一个all
,第一个all
目标只是说明了sinclude
两个文件,这两个文件在下面有创建的规则,所以会直接执行这两个目标。
autoconf.mk
$(obj)include/autoconf.mk: $(obj)include/config.h
@$(XECHO) Generating $@ ; \
set -e ; \
: Extract the config macros ; \
$(CPP) $(CFLAGS) -DDO_DEPS_ONLY -dM include/common.h | \
sed -n -f tools/scripts/define2mk.sed > $@.tmp && \
mv $@.tmp $@
依赖include/config.h
,XECHO
根据环境变量中是否有s
静默模式赋值为echo
或者:
,:
表示注释,CPP
为gcc -E
,表示展开宏,定义在config.mk
。-dM include/common.h
表示展开文件中的宏,利用脚本define2mk.sed
将宏定义转换成CONFIG_SYS_SPI_U_BOOT_OFFS=0x20000
。
include/config.h在U-boot配置时创建。
autoconf.mk.dep
$(obj)include/autoconf.mk.dep: $(obj)include/config.h include/common.h
@$(XECHO) Generating $@ ; \
set -e ; \
: Generate the dependancies ; \
$(CC) -x c -DDO_DEPS_ONLY -M $(CFLAGS) $(CPPFLAGS) \
-MQ $(obj)include/autoconf.mk include/common.h > $@
依赖include/config.h
和include/common.h
,提取所有依赖的头文件。
目标all
这里的目标all
指的是第二个
all: $(ALL-y) $(SUBDIR_EXAMPLES)
只有依赖文件,没有命令,所以只需要关注变量$(ALL-y)
和$(SUBDIR_EXAMPLES)
ALL-y
ALL-y += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)u-boot.dis $(obj)System.map
ALL-$(CONFIG_SPL) += $(obj)spl/u-boot-spl.bin
有两种赋值形式,需要了解的是第二种,根据宏是否定义为y
来决定ALL-y
是否包含。
u-boot.srec
继续看make_boot_compile.log.1
文件“all”不存在。
文件“u-boot.srec”不存在。
文件“u-boot”不存在。
...
必须重新创建目标“u-boot.srec”。
/disk2/cross_compiler/bin/arm-buildroot-linux-uclibcgnueabi-objcopy -O srec u-boot u-boot.srec
重新创建目标文件“u-boot.srec”成功。
对应的makefile内容是
$(obj)u-boot.srec: $(obj)u-boot
$(OBJCOPY) -O srec $< $@
u-boot[重要]
文件“u-boot”不存在。
文件“depend”不存在。
...
重新创建目标文件“depend”成功。
...
cd /disk2/boot && /disk2/cross_compiler/bin/arm-buildroot-linux-uclibcgnueabi-ld -pie -T u-boot.lds -Bstatic -Ttext 0x4ff00000 arch/arm/cpu/arm920t/start.o --start-group arch/arm/cpu/arm920t/libarm920t.o arch/arm/lib/libarm.o common/libcommon.o drivers/crypto/libcrypto.o drivers/i2c/libi2c.o drivers/mtd/libmtd.o drivers/mtd/nand/libnand.o drivers/mtd/spi/libspi_flash.o drivers/net/libnet.o drivers/net/phy/libphy.o drivers/rtc/librtc.o drivers/serial/libserial.o drivers/spi/libspi.o drivers/usb/ulpi/libusb_ulpi.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o lib/zlib/libz.o net/libnet.o board/samsung/smdk2440/libsmdk2440.o --end-group /disk2/boot/arch/arm/lib/eabi_compat.o -L /disk2/cross_compiler/cross_compiler/bin/../lib/gcc/arm-linux-gcc/4.7.2 -lgcc -Map u-boot.map -o u-boot
重新创建目标文件“u-boot”成功。
对应Makefile的代码
GEN_UBOOT = \
cd $(LNDIR) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
$(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
$(obj)u-boot: depend \
$(SUBDIR_TOOLS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
$(GEN_UBOOT)
依赖文件是depend
、$(SUBDIR_TOOLS)
、$(OBJS)
、$(LIBBOARD)
、$(LIBS)
、$(LDSCRIPT)
和$(obj)u-boot.lds
,待这些依赖文件全部更新后执行$(GEN_UBOOT)
。
下面我们对每一个进行分析
depend
Makefile内容
depend dep: $(TIMESTAMP_FILE) $(VERSION_FILE) \
$(obj)include/autoconf.mk \
$(obj)include/generated/generic-asm-offsets.h \
$(obj)include/generated/asm-offsets.h
for dir in $(SUBDIRS) $(CPUDIR) $(LDSCRIPT_MAKEFILE_DIR) ; do \
$(MAKE) -C $$dir _depend ; done
-
TIMESTAMP_FILE
是时间戳文件include/generated/timestamp_autogenerated.h
; -
VERSION_FILE
是版本信息,包括boot
的版本信息、arm-linux-gcc
和arm-linux-ld
的版本信息; -
include/autoconf.mk
之前已经分析过了; -
lib/asm-offsets.c
中定义了global_data
结构体的一些信息,利用该文件生成lib/asm-offsets.s
,再利用tools/scripts/make-asm-offsets
和lib/asm-offsets.s
生成include/generated/generic-asm-offsets.h
; - 利用
$(src)$(CPUDIR)/$(SOC)/asm-offsets.c
生成$(CPUDIR)/$(SOC)/asm-offsets.s
,不存在则该文件为空,再利用tools/scripts/make-asm-offsets
和$(CPUDIR)/$(SOC)/asm-offsets.s
生成include/generated/asm-offsets.h
; - 对
tools
、arch/arm/cpu/arm920t
和/disk2/boot/board/samsung/smdk2440/
分别执行make -C $dir _depend
,将在这些目录下生成.depend
文件,内容是.c
文件编译时所依赖的头文件。
$(SUBDIR_TOOLS)
在boot下面的Makefile中SUBDIR_TOOLS = tools
。
TOOLSUBDIRS =
BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
BINS := $(addprefix $(obj),$(sort $(BIN_FILES-y)))
all: $(obj).depend $(BINS) $(LOGO-y) subdirs
$(obj)envcrc$(SFX): $(obj)crc32.o $(obj)env_embedded.o $(obj)envcrc.o $(obj)sha1.o
$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
subdirs:
ifeq ($(TOOLSUBDIRS),)
@:
else
@for dir in $(TOOLSUBDIRS) ; do \
$(MAKE) \
HOSTOS=$(HOSTOS) \
HOSTARCH=$(HOSTARCH) \
-C $$dir || exit 1 ; \
done
endif
.depend
之前已经更新了;BIN表示诸如envcrc
的可执行文件,在boot/rules.mk
中关于.c编译成.o;LOGO-y
表示头文件;subdirs
表示其他需要编译的目录,这里定义是空。
$(HOSTOBJS): $(obj)%.o: %.c
$(HOSTCC) $(HOSTCFLAGS) $(HOSTCFLAGS_$(@F)) $(HOSTCFLAGS_$(BCURDIR)) -o $@ $< -c
tool
中的可执行文件使gcc
编译的,也就是说这些工具是在
$(OBJS)
在boot/Makefile
中OBJS
的定义是arch/arm/cpu/arm920t/start.o
OBJS = $(CPUDIR)/start.o
OBJS := $(addprefix $(obj),$(OBJS))
$(OBJS): depend
$(MAKE) -C $(CPUDIR) $(if $(REMOTE_BUILD),$@,$(notdir $@))
执行的命令等同于
make -C arch/arm/cpu/arm920t start.o
对应make_boot_compile.log.1
中的内容
文件“arch/arm/cpu/arm920t/start.o”不存在。
必须重新创建目标“arch/arm/cpu/arm920t/start.o”。
make -C arch/arm/cpu/arm920t start.o
文件“start.o”不存在。
必须重新创建目标“start.o”。
make[2]: Entering directory `/disk2/boot/arch/arm/cpu/arm920t'
/disk2/cross_compiler/bin/arm-linux-gcc -D__ASSEMBLY__ -g -Os -fno-common -ffixed-r8 -msoft-float -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x4ff00000 -DCONFIG_SPL_TEXT_BASE=0x200000 -DCONFIG_SPL_PAD_TO=0 -I/disk2/boot/include -fno-builtin -ffreestanding -nostdinc -isystem /disk2/cross_compiler/cross_compiler/bin/../lib/gcc/arm-linux-gcc/4.7.2/include -pipe -DCONFIG_ARM -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -march=armv5 -o start.o start.S -c
重新创建目标文件“start.o”成功。
$(LIBBOARD)
LIBS-y += lib/libgeneric.o
LIBS-y += lib/lzma/liblzma.o
...
LIBS-y += $(CPUDIR)/$(SOC)/lib$(SOC).o
LIBS := $(addprefix $(obj),$(sort $(LIBS-y)))
SUBDIR_TOOLS = tools
LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).o
LIBBOARD := $(addprefix $(obj),$(LIBBOARD))
$(LIBS): depend $(SUBDIR_TOOLS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
$(LIBBOARD): depend $(LIBS)
$(MAKE) -C $(dir $(subst $(obj),,$@))
依赖文件是depend
和$(LIBS)
,depend
之前已经更新过了,所以这里只需要考虑$(LIBS)
的更新。根据(LIBS)
的定义可以看出是.o文件,编译的方法类似于
make -C arch/arm/cpu/arm920t/
LIBBOARD
的定义是board/samsung/smdk2440/libsmdk2440.o
,因此编译的命令相当于
make -C board/samsung/smdk2440/
$(LIBS)
之前更新$(LIBBOARD)
时已经更新过了。
$(LDSCRIPT)
ifeq ($(wildcard $(LDSCRIPT)),)
LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
endif
对应make_boot_compile.log.1
中
目标“/disk2/boot/board/samsung/smdk2440/u-boot.lds”的前提“depend”不存在。
必须重新创建目标“/disk2/boot/board/samsung/smdk2440/u-boot.lds”。
make -C /disk2/boot/board/samsung/smdk2440/ u-boot.lds
u-boot.lds
文件存在,不需要更新。
$(obj)u-boot.lds
在boot/Makefile
中
$(obj)u-boot.lds: $(LDSCRIPT)
$(CPP) $(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$< >$@
对应make_boot_compile.log.1
中
文件“u-boot.lds”不存在。
必须重新创建目标“u-boot.lds”。
/disk2/cross_compiler/bin/arm-linux-gcc -E -g -Os -fno-common -ffixed-r8 -msoft-float -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x4ff00000 -DCONFIG_SPL_TEXT_BASE=0x200000 -DCONFIG_SPL_PAD_TO=0 -I/disk2/boot/include -fno-builtin -ffreestanding -nostdinc -isystem /disk2/cross_compiler/cross_compiler/bin/../lib/gcc/arm-linux-gcc/4.7.2/include -pipe -DCONFIG_ARM -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -march=armv5 -include /disk2/boot/include/u-boot/u-boot.lds.h -DCPUDIR=arch/arm/cpu/arm920t -ansi -D__ASSEMBLY__ -P - </disk2/boot/board/samsung/smdk2440/u-boot.lds >u-boot.lds
重新创建目标文件“u-boot.lds”成功。
u-boot.bin
文件“u-boot.bin”不存在。
必须重新创建目标“u-boot.bin”。
/disk2/cross_compiler/bin/arm-buildroot-linux-uclibcgnueabi-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
重新创建目标文件“u-boot.bin”成功。
对应的makefile内容是
$(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(BOARD_SIZE_CHECK)
u-boot.bin
用于烧写。
u-boot.dis
文件“u-boot.dis”不存在。
必须重新创建目标“u-boot.dis”。
/disk2/cross_compiler/bin/arm-buildroot-linux-uclibcgnueabi-objdump -d u-boot > u-boot.dis
重新创建目标文件“u-boot.dis”成功。
对应的makefile内容是
$(obj)u-boot.dis: $(obj)u-boot
$(OBJDUMP) -d $< > $@
反汇编u-boot,u-boot.dis
一般用于定位问题。
System.map
文件“System.map”不存在。
必须重新创建目标“System.map”。
重新创建目标文件“System.map”成功。
对应的makefile内容是
SYSTEM_MAP = \
$(NM) $1 | \
grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
LC_ALL=C sort
$(obj)System.map: $(obj)u-boot
@$(call SYSTEM_MAP,$<) > $(obj)System.map
依赖文件u-boot
,命令是$(call SYSTEM_MAP,$<) > $(obj)System.map
,等同于
$(CROSS_COMPILE)nm u-boot | \
grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \
LC_ALL=C sort > System.map
生成符号表System.map
。
spl/u-boot-spl.bin
$(obj)spl/u-boot-spl.bin: $(SUBDIR_TOOLS) depend
$(MAKE) -C spl all
SUBDIR_EXAMPLES
例子所在的文件夹,可以直接注释掉
SUBDIR_EXAMPLES = examples/standalone examples/api