學習UBOOT首先得學習Mafefile,推薦一篇文章《跟我一起寫寫Makefile》。
uboot 的makefile分主目錄中的主makefile和各級目錄中的子Makefile,移植Uboot,得理解主makefile以及其整體架構。
主makefile主要幹兩件事:
1:配置適合特定平臺的各種參數和文件
2:制定make規則,生成uboot.bin
關於對makefile的分析,主要參考:
u-boot的Makefile分析
http://blog.csdn.net/chongchongliu/archive/2008/11/02/3207360.aspx
http://liaowb1234.blog.163.com/blog/static/77155547201001284114270/
以下貼第一個連接的原文部分內容
U-BOOT是一個LINUX下的工程,在編譯之前必須已經安裝對應體系結構的交叉編譯環境,這裏只針對ARM,編譯器系列軟件爲 ppc_6xx-。U-BOOT的下載地址: http://sourceforge.net/projects/u-boot
我下載的是1.1.5版本
要了解一個LINUX工程的結構必須看懂Makefile,尤其是頂層的,沒辦法,UNIX世界就是這麼無奈,什麼東西都用文檔去管理、配置。首先在這方面我是個新手,時間所限只粗淺地看了一些Makefile規則,請各位多多指教。以cpci5200爲例:
幾個重要的文件分析:
u-boot-1.1.5/Makefile
u-boot-1.1.5/mkconfig
u-boot-1.1.5/config.mk
u-boot根目錄下的Makefile文件(u-boot-1.1.5/Makefile)它負責配置u-boot的編譯方式,具體說來包括:使用何種指令集,需包含哪些接口驅動、庫等。Makefile的內容從上到下分別是:分定義編譯環境:使用何種編譯器、編譯方式、目標文件的生成及它們最終鏡像中的鏈接次序等。Mkconfig和config.mk在接下來的分析中會涉及到。
在編譯U-BOOT之前,先要執行
# make cpci5200_config
cpci5200_config是Makefile的一個目標,定義如下:
cpci5200_config: unconfig
@$(MKCONFIG) -a cpci5200 ppc mpc5xxx cpci5200 esd
其中,unconfig定義如下:
unconfig:
@rm -f $(obj)include/config.h $(obj)include/config.mk /
$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp
顯然,執行# make cpci5200_config時,先執行unconfig目標,注意不指定輸出目標時,obj,src變量均爲空,unconfig下面的命令清理上一 次執行make *_config時生成的頭文件和makefile的包含文件。主要是include/config.h 和include/config.mk文件。
然後才執行命令
@$(MKCONFIG) -a cpci5200 ppc mpc5xxx cpci5200 esd
$(MKCONFIG)就會被替換成$(SRCTREE)/mkconfig文件路徑, MKCONFIG 是頂層目錄下的mkcofig腳本文件(u-boot-1.1.5/mkconfig),後面五個是傳入的參數。Mkconfig文件的詳細分析見文檔末尾。
注意一下u-boot對板卡的分類方法:
Target:宿主機平臺
Architecture:定義芯片架構(如MIPS、POWERPC、ARM等)
CPU:定義芯片指令集版本(如ARM7、ARM9、ARM11等)
Board:芯片廠商,它細分爲兩類
[VENDOR]:按廠商劃分(如AT9200、S3C44B0等)
[SOC]:按SOC類型(如S3C2440、S3C2410等)
1)對於cpci5200_config而言,mkconfig主要做三件事:
在include文件夾下建立相應的文件(夾)軟(符號)連接,
#如果是PPC體系將執行以下操作:
#ln -s asm-ppc asm
#ln -s arch-mpc5xxx asm-ppc/arch
#ln -s proc-armv asm-ppc/proc
生成Makefile包含文件include/config.mk,內容很簡單,定義了四個變量:
ARCH = ppc
CPU = mpc5xxx
BOARD = cpci5200
VENDOR = esd
這些變量可以供其它的makefile使用,作爲一個基本配置.
生成include/config.h頭文件,只有一行:
echo“/* Automatically generated - do not edit */”>>config.h
echo“#include <config/$1.h>”>>config.h
這兩行代碼生成一個include/config.h文件,這個文件很簡單,只有一句話:
#include <$1.h> 當然這裏的$1時要被替換成不同的board名字的.這個取決於我們在主Makefile中xxxx_config目標中的xxxx是什麼.
mkconfig腳本文件的執行至此結束
2)分析config.mk的內容:
u-boot根目錄下自帶一個config.mk文件(u-boot-1.1.5/config.mk),應 該說這纔是真正的Makefile,以上介紹的兩個腳本Makefile和mkconfig完成了環境配置之後,在該文件中才定義具體的編譯規則,所以你會發現在各個子模塊(board、 cpu、lib_xxx、net、disk...)目錄中的Makefile第一句就是:include $(TOPDIR)/config.mk。文件內容分析如下:
這個文件的功能就是給各個在編譯過程中的變量賦值,包括編譯執行的函數與編譯的時候所帶的參數等等。還會根據是否定義了ARCH,CPU,SOC,VENDOR,BOARD來決定是否包含相應位置的config.mk文件,這些個文件裏,也是定義了相應的平臺在編譯的時候應該加的參數。所以如果你爲你自己的開發板取了別的名字了,那麼就要檢查一下這個文件,看一下相應的位置上的config.mk文件有沒有,內容是否爲你要想的。
l 包含體系,開發板,CPU特定的規則文件:
#指定預編譯體系結構選項
ifdef ARCH
sinclude $(TOPDIR)/$(ARCH)_config.mk # include architecture dependend rules
endif
#定義編譯時對齊,浮點等選項
ifdef CPU
sinclude $(TOPDIR)/cpu/$(CPU)/config.mk # include CPU specific rules
endif
ifdef SOC
sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk # include SoC specific rules
endif
ifdef VENDOR
BOARDDIR = $(VENDOR)/$(BOARD)
else
BOARDDIR = $(BOARD)
Endif
#指定特定板子的鏡像連接時的內存基地址,重要!
ifdef BOARD
sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
endif
l 定義交叉編譯鏈工具
# Include the make variables (CC, etc...)
#
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
RANLIB = $(CROSS_COMPILE)RANLIB
l 定義AR選項ARFLAGS,調試選項DBGFLAGS,優化選項OPTFLAGS 預處理選項CPPFLAGS,C編譯器選項CFLAGS,連接選項LDFLAGS
#制定了在編譯的時候告訴編譯器生成的代碼的基地址是TEXT_BASE
CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) /
-D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) /
AFLAGS := $(AFLAGS_DEBUG) -D__ASSEMBLY__ $(CPPFLAGS)
#指定了起始地址TEXT_BASE
LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
l 指定編譯規則
ifndef REMOTE_BUILD
%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
else
$(obj)%.s: %.S
$(CPP) $(AFLAGS) -o $@ $<
$(obj)%.o: %.S
$(CC) $(AFLAGS) -c -o $@ $<
$(obj)%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
endif