6.2.3 U-Boot的編譯
U-Boot的源碼是通過GCC和Makefile組織編譯的。頂層目錄下的Makefile首先可以設置開發板的定義,然后遞歸地調用各級子目錄下的Makefile,最后把編譯過的程序鏈接成U-Boot映像。
1.頂層目錄下的Makefile
它負責U-Boot整體配置編譯。按照配置的順序閱讀其中關鍵的幾行。
每一種開發板在Makefile都需要有板子配置的定義。例如smdk2410開發板的定義如下。
smdk2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
執行配置U-Boot的命令make smdk2410_config,通過./mkconfig腳本生成include/config.
mk的配置文件。文件內容正是根據Makefile對開發板的配置生成的。
ARCH = arm
CPU = arm920t
BOARD = smdk2410
SOC = s3c24x0
上面的include/config.mk文件定義了ARCH、CPU、BOARD、SOC這些變量。這樣硬件平台依賴的目錄文件可以根據這些定義來確定。SMDK2410平台相關目錄如下。
board/smdk2410/
cpu/arm920t/
cpu/arm920t/s3c24x0/
lib_arm/
include/asm-arm/
include/configs/smdk2410.h
再回到頂層目錄的Makefile文件開始的部分,其中下列幾行包含了這些變量的定義。
# load ARCH, BOARD, and CPU configuration
include include/config.mk
export ARCH CPU BOARD VENDOR SOC
Makefile的編譯選項和規則在頂層目錄的config.mk文件中定義。各種體系結構通用的規則直接在這個文件中定義。通過ARCH、CPU、BOARD、SOC等變量為不同硬件平台定義不同選項。不同體系結構的規則分別包含在ppc_config.mk、arm_config.mk、mips_config.mk等文件中。
頂層目錄的Makefile中還要定義交叉編譯器,以及編譯U-Boot所依賴的目標文件。
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux- //交叉編譯器的前綴
#endif
export CROSS_COMPILE
…
# U-Boot objects....order is important (i.e. start must be first)
OBJS = cpu/$(CPU)/start.o //處理器相關的目標文件
…
LIBS = lib_generic/libgeneric.a //定義依賴的目錄,每個目錄下先把目標文件連接成*.a文件。
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
ifdef SOC
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
endif
LIBS += lib_$(ARCH)/lib$(ARCH).a
…
然后還有U-Boot映像編譯的依賴關系。
ALL = u-boot.srec u-boot.bin System.map
all: $(ALL)
u-boot.srec: u-boot
$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
u-boot.bin: u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
……
u-boot: depend $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM='$(OBJDUMP) -x $(LIBS) \
|sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
$(LD) $(LDFLAGS) $$UNDEF_SYM $(OBJS) \
--start-group $(LIBS) $(PLATFORM_LIBS) --end-group \
-Map u-boot.map -o u-boot
Makefile缺省的編譯目標為all,包括u-boot.srec、u-boot.bin、System.map。u-boot.srec和u-boot.bin又依賴於U-Boot。U-Boot就是通過ld命令按照u-boot.map地址表把目標文件組裝成u-boot。
其他Makefile內容就不再詳細分析了,上述代碼分析應該可以為閱讀代碼提供了一個線索。
2.開發板配置頭文件
除了編譯過程Makefile以外,還要在程序中為開發板定義配置選項或者參數。這個頭文件是include/configs/<board_name>.h。<board_name>用相應的BOARD定義代替。
這個頭文件中主要定義了兩類變量。
一類是選項,前綴是CONFIG_,用來選擇處理器、設備接口、命令、屬性等。例如:
#define CONFIG_ARM920T 1
#define CONFIG_DRIVER_CS8900 1
另一類是參數,前綴是CFG_,用來定義總線頻率、串口波特率、Flash地址等參數。例如:
#define CFG_FLASH_BASE 0x00000000
#define CFG_PROMPT "=>"
3.編譯結果
根據對Makefile的分析,編譯分為2步。第1步配置,例如:make smdk2410_config;第2步編譯,執行make就可以了。
編譯完成后,可以得到U-Boot各種格式的映像文件和符號表,如表6.3所示。
表6.3 U-Boot編譯生成的映像文件
文 件 名 稱
|
說 明
|
文 件 名 稱
|
說 明
|
System.map
|
U-Boot映像的符號表
|
u-boot.bin
|
U-Boot映像原始的二進制格式
|
u-boot
|
U-Boot映像的ELF格式
|
u-boot.srec
|
U-Boot映像的S-Record格式
|
U-Boot的3種映像格式都可以燒寫到Flash中,但需要看加載器能否識別這些格式。一般u-boot.bin最為常用,直接按照二進制格式下載,並且按照絕對地址燒寫到Flash中就可以了。U-Boot和u-boot.srec格式映像都自帶定位信息。
4.U-Boot工具
在tools目錄下還有些U-Boot的工具。這些工具有的也經常用到。表6.4說明了幾種工具的用途。
表6.4 U-Boot的工具
工 具 名 稱
|
說 明
|
工 具 名 稱
|
說 明
|
bmp_logo
|
制作標記的位圖結構體
|
img2srec
|
轉換SREC格式映像
|
envcrc
|
校驗u-boot內部嵌入的環境變量
|
mkimage
|
轉換U-Boot格式映像
|
gen_eth_addr
|
生成以太網接口MAC地址
|
updater
|
U-Boot自動更新昇級工具
|
這些工具都有源代碼,可以參考改寫其他工具。其中mkimage是很常用的一個工具,Linux內核映像和ramdisk文件系統映像都可以轉換成U-Boot的格式。
6.2.4 U-Boot的移植
U-Boot能夠支持多種體系結構的處理器,支持的開發板也越來越多。因為Bootloader是完全依賴硬件平台的,所以在新電路板上需要移植U-Boot程序。
開始移植U-Boot之前,先要熟悉硬件電路板和處理器。確認U-Boot是否已經支持新開發板的處理器和I/O設備。假如U-Boot已經支持一塊非常相似的電路板,那麼移植的過程將非常簡單。
移植U-Boot工作就是添加開發板硬件相關的文件、配置選項,然后配置編譯。
開始移植之前,需要先分析一下U-Boot已經支持的開發板,比較出硬件配置最接近的開發板。選擇的原則是,首先處理器相同,其次處理器體系結構相同,然后是以太網接口等外圍接口。還要驗證一下這個參考開發板的U-Boot,至少能夠配置編譯通過。
以S3C2410處理器的開發板為例,U-Boot-1.1.2版本已經支持SMDK2410開發板。我們可以基於SMDK2410移植,那麼先把SMDK2410編譯通過。
我們以S3C2410開發板fs2410為例說明。移植的過程參考SMDK2410開發板,SMDK2410在U-Boot-1.1.2中已經支持。
移植U-Boot的基本步驟如下。
(1)在頂層Makefile中為開發板添加新的配置選項,使用已有的配置項目為例。
smdk2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
參考上面2行,添加下面2行。
fs2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t fs2410 NULL s3c24x0
(2)創建一個新目錄存放開發板相關的代碼,並且添加文件。
board/fs2410/config.mk
board/fs2410/flash.c
board/fs2410/fs2410.c
board/fs2410/Makefile
board/fs2410/memsetup.S
board/fs2410/u-boot.lds
(3)為開發板添加新的配置文件
可以先復制參考開發板的配置文件,再修改。例如:
$cp include/configs/smdk2410.h include/configs/fs2410.h
如果是為一顆新的CPU移植,還要創建一個新的目錄存放CPU相關的代碼。
(4)配置開發板
$ make fs2410_config
(5)編譯U-Boot
執行make命令,編譯成功可以得到U-Boot映像。有些錯誤是跟配置選項是有關系的,通常打開某些功能選項會帶來一些錯誤,一開始可以盡量跟參考板配置相同。
(6)添加驅動或者功能選項
在能夠編譯通過的基礎上,還要實現U-Boot的以太網接口、Flash擦寫等功能。
對於FS2410開發板的以太網驅動和smdk2410完全相同,所以可以直接使用。CS8900驅動程序��