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這個工具。