1.在MTK集成过的android平台下编译UBOOT,在工程根目录下使用命令
./makeMtk project_name(工程名) remake ub
找到makeMtk源码(perl语言),编译命令最终是通过调用
$makeCmd = "make -f mediatek/build/makemtk.mk $cmdArg @mOpts";
这个编译命令进行编译的。GNU make可以添加DEBUG参数来获取调试信息,比如--debug=v。
可以通过修改$makeCmd来增加调试信息,比如:
$makeCmd = "make --debug=v -f mediatek/build/makemtk.mk $cmdArg @mOpts";
2.$makeCmd命令指定makefile文件 mediatek/build/makemtk.mk。找到其对应UBOOT的源码部分。
$(hide) cd $(UBOOT_WD) &&
(MAKEJOBS=$(MAKEJOBS) ./build.sh $(ACTION) $(DEAL_STDOUT) &&
cd $(MKTOPDIR) &&
$(call chkImgSize,$(ACTION),$(PROJECT),$(SCATTER_FILE),$(UBOOT_IMAGES),$(DEAL_STDOUT) &&)
$(SHOWRSLT) $$? $(MODULE_LOG) ||
$(SHOWRSLT) $$? $(MODULE_LOG))
它是通过./build.sh来生成UBOOT映象文件的。源代码位于bootable/bootloader/uboot/build.sh目录下。通过make ${MTK_PROJECT}_config;来生成u-boot.bin。并mkimage工具生成最终的UBOOT文件。
3.主要分析make ${MTK_PROJECT}_config这个命令。它的工作目录是bootable/bootloader/uboot/。它最终使用这个目录下面的Makefile来生成编译规则。查看这个目录的源代码发现包含这么一行
include ../../../mediatek/build/uboot/config.mk
这个目标{MTK_PROJECT}_config的定义是在这个config.mk里面。它位于mediatek目录下。
源码如下:
.PHONY: $(MTK_PROJECT)_config
$(MTK_PROJECT)_config: $(UBOOT_CHIP_CONFIG)_config
$(UBOOT_CHIP_CONFIG)_config : unconfig
@chmod a+x $(MKCONFIG)
@$(MKCONFIG) $(UBOOT_BOARD_CONFIG) arm $(UBOOT_CPU_CONFIG) $(UBOOT_BOARD_CONFIG) NULL $(UBOOT_CHIP_CONFIG)
echo "#define ${UBOOT_STORAGE_CONFIG}" >> include/config.h
echo "#define CFG_BOARD "${UBOOT_BOARD_CONFIG}"" >> include/config.h
在这里进行了一些关于工程的配置,但是并没有生成最终的u-boot.bin。那么这个u-boot.bin是在哪里生成的呢?
4.我们回来看bootable/bootloader/uboot/Makefile文件。这个文件第一个target是$(SUBDIRS),
SUBDIRS = tools
examples/standalone
examples/api
.PHONY : $(SUBDIRS)
它里面也没有生成u-boot.bin的规则。这就麻烦了,u-boot.bin到底是哪个规则生成的呢?
伪目标.PHONY : $(SUBDIRS)的依赖关系会被推导成
tools examples/standalone examples/api。这个时候仍然没有生成u-boot.bin。
SUBDIRS = tools
examples/standalone
examples/api 这个定义是一个可扩展变量,不同于:=这种带冒号的定义。它在后面重新扩展了一次看代码:
$(SUBDIRS): depend
$(MAKE) -C $@ all
多了一个
$(MAKE) -C $@ all。就是这句话最终生成u-boot.bin的。开始以为-C是代表clean,其实是代表每次都认为后面的target是最新的,每次都需要重新编译。
我们再来看all的定义。
ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND)
all: $(ALL)它依赖对象u-boot.bin。我们再来看u-boot.bin的定义。最终依赖
$(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) $(obj)u-boot.lds
$(GEN_UBOOT)。它最终调用
$(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS)
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS)
-Map u-boot.map -o u-boot
来生成u-boot。$(LD)是arm-eabi-ld.bfd这个工具。