u-boot源碼分析 - 簡介,編譯

1   u-boot介紹

U-Boot是一種通用的Bootloader, U-Boot可以方便地移植到其他硬件平臺上,其源代碼也值得開

發者們研究學習。

最早,DENX軟件工程中心的Wolfgang Denk基於8xxrom的源碼創建了PPCBOOT工程,並且不斷添加處理器的支持。後來,Sysgo Gmbh把ppcboot移植到ARM平臺上,創建了ARMboot工程。然後以ppcboot工程和armboot工程爲基礎,創建了U-Boot工程。

現在U-Boot已經能夠支持PowerPC、ARM、X86、MIPS體系結構的上百種開發板,已經成爲功能最多、靈活性最強並且開發最積極的開放源碼Bootloader。目前仍然由DENX的Wolfgang Denk維護。

U-Boot的源碼包可以從sourceforge網站下載,還可以訂閱該網站活躍的U-Boot Users郵件論壇,這個郵件論壇對於U-Boot的開發和使用都很有幫助。

U-Boot軟件包下載網站:http://sourceforge.net/project/u-boot。

U-Boot郵件列表網站:http://lists.sourceforge.net/lists/listinfo/u-boot-users/。

DENX相關的網站:http://www.denx.de/re/DPLG.html。

 

本文以u-boot1.13爲例來對u-boot進行分析

 

2 u-boot源代碼目錄結構

 - board            存放電路板相關的目錄文件

- common           通用的多功能函數實現

- cpu              存放CPU相關的目錄文件

- disk             硬盤接口驅動程序

- doc              開發使用文檔

- drivers          通用驅動驅動程序

- dtt              數字溫度測量器或者傳感器的驅動

- examples         例子程序.

- fs               文件系統相關代碼

- include          頭文件

- lib_arm          存放對ARM體系結構通用的庫文件,主要用於實現ARM平臺通用的函數

- lib_generic      通用庫函數的實現

- lib_i386         存放對i386體系結構通用的庫文件

- lib_m68k         存放對m86k體系結構通用的庫文件

-lib_microblaze    存放對microblaze體系結構通用的庫文件

- lib_mips         存放對MIPS體系結構通用的庫文件

- lib_nios         存放對NIOS體系結構通用的庫文件

- lib_nios2        存放對NIOS2體系結構通用的庫文件

- lib_ppc          存放對Power PC體系結構通用的庫文件

- net              網絡相關代碼

- post             開機自檢的代碼

- rtc              RTC驅動

- tools            存放製作S-Record 或者 U-Boot格式的映像等工具

- Makefile         生成u-boot鏡像的Makefile文件

- mkconfig         用來生成各個板子的配置文件

- config.mk        被Makefile所包含,存放編譯選項和規則

除了這些目錄外,在根目錄下還有其他的一些文件, 同時該目錄下還有個README的文件,我們可以通過這個文件來熟悉u-boot。

移植過程中重點關注的是board, cpu, 以及Makefile等與平臺相關的目錄和文件。

 

3 u-boot源代碼編譯

U-Boot的源碼是通過GCC和Makefile組織編譯的。頂層目錄下的Makefile首先可以設置開發板的定義,然後遞歸地調用各級子目錄下的Makefile,最後把編譯過的程序鏈接成U-Boot映像。

   當我們拿到u-boot的代碼後我們就可以嘗試給我們自己的板子編譯一個u-boot的鏡像,而根目錄下的Makefile就是用來生成u-boot鏡像的。 但在編譯之前我們需要爲我們的特定板子產生一個描述這塊板子的配置文件,然後才能指導Makefile如何去編譯能跑在這塊板子上的u-boot鏡像。

   以後的文章中我們都以smdk2410的板子和linux內核爲例來分析。

  

3.1 特定板子的配置文件的生成

   實際上配置文件的生成也是通過根目錄下的Makefile來完成的, 我們以smdk2410爲例, 我們來看Makefile中的片斷:

 

/Makefile:

smdk2410_config :   unconfig   //smdk2410板子

    @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0 //後面是傳給mkconfig的參數

 

如果要生成配置文件,只要打入命令:

   make smdk2410_config

這樣系統就會調用當前目錄下的mkconfig腳本在./include下生成一個叫config.mk的配置文件。文件內容就是我們提供的參數。

其中參數的意思如下:

arm:  CPU的架構

arm920t: CPU的類型,

smdk2410: 開發板的型號

NULL: 開發者或經銷商(verdor)

s3c24x0: 片上系統(SOC)

詳細的參數信息,和如何生成config.mk的內容可看mkconfig腳本,這裏就不介紹了。

這樣配置後硬件平臺依賴的目錄文件也就確定下來了,smdk2410平臺相關的目錄:

board/smdk2410/

cpu/arm920t/

cpu/arm920t/s3c24x0/

lib_arm/

include/asm-arm/

同時還有一個重要的文件:

include/configs/smdk2410.h  

這個要我們自己添加,用來定義開發板的配置選項或者參數(具體參數參見README)

我們在移植的時候也按這種步驟添加代碼就行了。

 

3.2 u-boot鏡像生成

我們先來大致瞭解下Makefile文件:

 

/Makefile:

ifeq (include/config.mk,$(wildcard include/config.mk))

# load ARCH, BOARD, and CPU configuration

include include/config.mk     //引用上面我們生成的配置文件,獲得ARCH, BOARD等變量

export  ARCH CPU BOARD VENDOR SOC    //全局可見

# load other configuration

include $(TOPDIR)/config.mk   //引用頂層配置文件,獲得編譯選項等信息

 

……

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

ifeq ($(CPU),i386)

OBJS += cpu/$(CPU)/start16.o

OBJS += cpu/$(CPU)/reset.o

endif

ifeq ($(CPU),ppc4xx)

OBJS += cpu/$(CPU)/resetvec.o

endif

ifeq ($(CPU),mpc83xx)

OBJS += cpu/$(CPU)/resetvec.o

endif

ifeq ($(CPU),mpc85xx)

OBJS += cpu/$(CPU)/resetvec.o

endif

 

LIBS  = lib_generic/libgeneric.a      //定義要依賴的庫

……

……

ALL = u-boot.srec u-boot.bin System.map

 

all:        $(ALL)   //U-Boot映像編譯的依賴關係

 

u-boot.hex: u-boot

        $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@

 

u-boot.srec:    u-boot

        $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@

 

u-boot.bin: u-boot

        $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@

 

u-boot.img: u-boot.bin

        ./tools/mkimage -A $(ARCH) -T firmware -C none /

        -a $(TEXT_BASE) -e 0 /

        -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' include/version.h | /

            sed -e 's/"[    ]*$$/ for $(BOARD) board"/') /

        -d $< $@

 

u-boot.dis: u-boot

        $(OBJDUMP) -d $< > $@

 

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) --end-group $(PLATFORM_LIBS) /

            -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。這些分析應該可以爲閱讀代碼提供了一個線索。

因此如果要生成u-boot的鏡像, 我們就可以通過這個命令來完成:

make all

這將生成如下幾個文件:

u-boot.bin : 原始的二進制鏡像

u-boot: ELF二進制格式的鏡像

u-boot.srec: 是motorola S-Record格式的文件。

U-Boot的3種映像格式都可以燒寫到Flash中,但需要看加載器能否識別這些格式。一般u-boot.bin最爲常用,直接按照二進制格式下載,並且按照絕對地址燒寫到Flash中就可以了。U-Boot和u-boot.srec格式映像都自帶定位信息。

 

總結: 由分析可知, 編譯u-boot由兩個階段完成:

1.   爲特定的板子生成配置文件

2.   編譯u-boot使之產生鏡像。


轉載自:http://blog.csdn.net/aaronychen/article/details/2793569


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