uboot構建框架7-u-boot.imx生成過程追蹤

還是先找到入口

上文《u-boot.bin生成過程追蹤》,我們探討了u-boot.bin的生成過程。在文章開頭的地方,我們講到終極目標,並且找到了主Makefile的終極目標所在。本文探討u-boot.imx文件的生成,因很多內容跟上文都一樣,所以在閱讀本文之前,還需要閱讀下上文的內容。

還是跟u-boot.bin一樣,我們在ALL-y裏面尋找u-boot.imx的定義。不過可惜,我們好像沒找到,但是這是不可能的,如果ALL-y裏面沒有指定u-boot.imx,那麼一定不會編譯出u-boot.imx。我們不妨打印一下這個ALL-y看看,我在主Makefile802頁加了一個打印,如下:

all:            $(ALL-y)
    @echo aaaaaaaaaaaaaaaaaa
    @echo $(ALL-y)
    @echo bbbbbbbbbbbbbbbbbb

我們看到如下輸出:

aaaaaaaaaaaaaaaaaa
checkarmreloc u-boot.imx u-boot.srec u-boot.bin u-boot.sym System.map u-boot.cfg binary_size_check
bbbbbbbbbbbbbbbbbb

看到沒有,這裏是有u-boot.imx的。那麼這個是在哪裏加入的呢?這裏我們就要略微動下腦子了,這個u-boot.imx後綴是imx,而且我們清楚,這個東西是NXP imx平臺特有的一個uboot鏡像,所以這個東西不大可能在主Makefile裏面直接寫進去。那一定是跟平臺相關的,但是跟平臺相關,東西也挺多,要找這個玩意在哪裏,也是有點困難啊。到了這裏了,咱不得不祭出我們搜索的法寶,有需要的朋友可以拿去,挺好用的一個工具,命令如下:

sunke@droresrv:~/work/MYiR-iMX-Uboot$ find . -type f -name "*" | xargs grep "u-boot.imx"

這裏我們全文遞歸查找字符串u-boot.imx。這裏輸出會比較多,我們把重要的輸出拿出來看:

./arch/arm/config.mk:ALL-y += u-boot.imx
ifeq ($(CONFIG_OF_SEPARATE),y)
ALL-y += u-boot-dtb.imx
else
ALL-y += u-boot.imx
endif

看到沒,這個config.mk裏面追加了u-boot.imx到ALL-y變量裏面。我們可以通過打印,驗證一下,是否真的是這裏引入了u-boot.imx。這裏我也不列出來了,我打印了之後發現確實是這裏引入的,大家可以自己試下。哪裏引入的u-boot.imx我們知道了,這個u-boot.imx的構建規則入口又在哪裏呢?我並沒有在主Makefile裏面找到u-boot.imx的規則,但是我找到了這條規則,主Makefile第839行:

%.imx: %.bin
        $(Q)$(MAKE) $(build)=arch/arm/imx-common $@

這是個模式規則,u-boot.imx會匹配這個規則。這裏又見到我們的老朋友build了,我們還是同樣的方式,展開一下:

$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj=arch/arm/imx-common u-boot.imx

這裏轉向去執行Makefile.build,obj變量使Makefile.build會引入arch/arm/imx-common/Makefile,我們在這個Makefile裏面找到了u-boot.imx規則,第57行:

u-boot.imx: u-boot.bin $(IMX_CONFIG) FORCE
        $(call if_changed,mkimage)

怎麼樣,這個入口終於被我們找到了。

先看一下依賴

上面我們找到了u-boot.imx的入口,我們看到它依賴u-boot.bin,這個u-boot.bin我們已經在《u-boot.bin生成過程追蹤》裏面分析過了,想要追蹤的可以看那裏。另外,u-boot.imx還依賴$(IMX_CONFIG),我們通過打印的方式看到,這個展開之後如下:

board/myir/mys_imx6ull/imximage.cfg.cfgtmp

這個文件實際上是imx image header中的DCD數據,其規則定義在arch/arm/imx-common/Makfile裏面,第48行,如下:

IMX_CONFIG = $(CONFIG_IMX_CONFIG:"%"=%).cfgtmp

其中定義了CONFIG_IMX_CONFIG變量,我們在include/autoconf.mk裏面找到了這個變量的定義:

CONFIG_IMX_CONFIG="board/myir/mys_imx6ull/imximage.cfg"

$(IMX_CONFIG)還有一個規則,arch/arm/imx-common/Makfile第50行,如下:

quiet_cmd_cpp_cfg = CFGS    $@  
      cmd_cpp_cfg = $(CPP) $(cpp_flags) -x c -o $@ $<

IMX_CONFIG = $(CONFIG_IMX_CONFIG:"%"=%).cfgtmp

$(IMX_CONFIG): %.cfgtmp: % FORCE
        $(Q)mkdir -p $(dir $@)
        $(call if_changed_dep,cpp_cfg)

這裏$(IMX_CONFIG)這個目標是通過cpp_cfg命令生成的,我們可以看到,這個命令使用了$(CPP),CPP變量在主Makefile的第341行有定義,如下:

CPP             = $(CC) -E

就是調用了gcc的-E選項而已,這個命令的詳細展開及運行,大家可以自己分析一下,這裏先不展開。我們重點看下u-boot.imx目標的命令。

再來看下命令

我們現在重點來展開分析u-boot.imx的命令,其調用了mkimage命令,這個通過if_changed函數展開之後,也就是命令cmd_mkimage。我們在Makefile.lib文件裏面找到了這個命令的定義,Makefile.lib第435行,如下:

# Additional commands for U-Boot
#
# mkimage
# ---------------------------------------------------------------------------
quiet_cmd_mkimage = MKIMAGE $@
cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \
        $(if $(KBUILD_VERBOSE:1=), >/dev/null)

這個調用了tools/mkimage程序,我們展開一下這個變量的值:

./tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d u-boot.bin u-boot.imx >/dev/null

這裏面有個$(MKIMAGEFLAGS_$(@F)),其中$(@F)是表示目標文件的完整文件名中除目錄以外的部分。在這裏其值就是依賴文件u-boot.imx。於是這個變量就編程"$(MKIMAGEFLAGS_u-boot.imx)",這個變量在arch/arm/imx-common/Makefile裏面定義,第54行:

MKIMAGEFLAGS_u-boot.imx = -n $(filter-out $< $(PHONY),$^) -T imximage \
        -e $(CONFIG_SYS_TEXT_BASE)

這裏我們直接展開如下:

MKIMAGEFLAGS_u-boot.imx = -n board/myir/mys_imx6ull/imximage.cfg.cfgtmp -T imximage -e 0x87800000

於是,整個cmd_mkimage命令展開就變成:

./tools/mkimage -n board/myir/mys_imx6ull/imximage.cfg.cfgtmp -T imximage -e 0x87800000 -d u-boot.bin u-boot.imx >/dev/null

看到沒,這個就是最終生成u-boot.imx的命令,要看明白裏面的具體生成過程,那麼就需要去研究下mkimage程序的原理了。本文因爲只追蹤u-boot.imx的生成過程,具體生成原理這裏就不贅述了,後續有機會分析uboot源代碼時再詳細展開吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章