1. 程式人生 > >底層移植之RBL, UBL, Uboot的關係

底層移植之RBL, UBL, Uboot的關係

首先RBL = ROM Bootloader,UBL= user Bootloader UBOOT = Universal Boot Loader。

        RBL為TI固化在晶片ROM中的bootloader,OMAP上電啟動過後首先將執行RBL,然後通過RBL載入UBL,再通過UBL載入uboot,而uboot就是用來載入Linux核心的。如果在具體應用過程中不需要使用到Linux(實際上一般都會用到的),uboot甚至是UBL都可以省去。

        UBL為一級Bootloader,uboot為二級Bootloader,一級Bootloader的大小是有限制的(應該是64KB以下,沒查到具體數值),這也是為什麼會有二級Bootloader的原因。如果一個應用程式小於這個大小,那麼我們可以不需要燒寫UBL

,而只用燒寫該應用程式相應的bin檔案(下面第3點將闡述如何得到這個檔案)就行了。
        UBL的程式設計,相對UBOOT、KERNEL、ROOTFS、裝置驅動、DSP開發來說,還是比較簡單。我們先從DAVINCI的啟動說起,瞭解UBL在DAVIN系統中的位置和作用。對於韌體程式燒寫在NAND FLASH 的Davinci dm644x嵌入式系統,上電啟動的過程如下:

1. RBL階段:
       系統復位後,儲存在片內ROM的RBL程式開始執行,RBL程式根據BTSEL[0-3]管腳的電平來判斷相應的啟動方式。[00]表明是NAND啟動方式,RBL程式便從外接nand flash中讀取UBL的資料到內部RAM中(UBL最大可達14K),然後轉至UBL程式碼執行;[01]表明是EMIFA啟動方式,RBL則直接轉至EMIFA EM_CS2 memory space(0x02000000)處開始執行,EMIFA的資料和地址匯流排寬度分別由EM_WIDTH和AEAW[4:0]引腳決定;[10]表明是HPI啟動方式,RBL通過HPI傳輸程式碼獲得UBL,然後轉至UBL程式碼處執行;[11]表明是UART啟動方式,RBL通過UART0傳輸程式碼獲得UBL,然後轉至UBL程式碼處執行。第一、三、四種方式都是RBL將UBL下載到ARM RAM0和ARM RAM1(0x0-0x3fff,共16K)中,然後轉至UBL執行。DSP的是自引導還是由ARM引導由DSP_BT引腳電平決定,如果為高則自引導,如果為低則由ARM引導。

2. UBL階段,也就是

u-boot階段
       ti官方提供的是u-boot,所以這裡闡述的是u-boot的啟動過程。在u-boot中最初階段主要完成系統時鐘、DDR頻率的初始化,準備好載入C程式執行的環境,這時候程式執行在ARM RAM中或nor flash中,由啟動方式決定。然後拷貝u-boot程式碼到DDR中,並跳轉到C程式的start_armboot處執行(在DDR2中)。
u-boot的具體設定過程如下:
      (1)U-boot程式碼中首先設定最基本的系統硬體環境,包括系統PLL及DDR2的初始化、PSC的配置及使能UART0、AEMIF等硬體模組;
      (2)配置系統的記憶體(通過ATAG_ MEM塊和mem=)NAND Flash和DDR2;
      (3)在flash中或通過tftp載入核心到指定的儲存地址;
      (4)初始化傳遞到核心的引導引數(EMAC地址,串列埠,控制檯,視訊格式等)
      (5)獲得ARM Linux機型別值(DVEVM為#901);
      (6)設定kernel tagged list;
      (7)用初始值設定ARM的暫存器;
      (8)呼叫linux核心;

針對DM644X的設定有:
      (1)關中斷和MMU。
      (2)使能DSP電源域(PTCMD),把DSP置為復位狀態。
      (3)初始化PLL,使能DDR2,軟復位DDR2並且重新使能DDR2,使其脫離復位狀態。
      (4)初始化系統PLL。
      (5)配置AEMIF引腳為NOR Flash介面。
      (6)VTP校準。

3. Linux核心啟動階段:


      (1)核心中的boot/compressed/head.s程式碼開始執行,儲存從u-boot中傳入的引數,然後會執行一段處理器相關的程式碼,中間再做些判斷和處理,最後對壓縮的核心進行解壓。

      (2)核心中的kernel/head.s程式碼開始執行,初始化頁表,cache和MMU等。

      (3)start_kernel()執行,根據從U-boot中得到引數及其他初始化設定(在board-evm.c中),進行一系列的核心初始化,比如io地址對映、定時器和串列埠初始化、記憶體頁表重新對映等。

      (4)Linux的第一個程序init()執行,該程序根據系統中的配置初始化系統。根據從U-boot中得到引數,從flash中或nfs中啟動檔案系統;
      (5)shell啟動。

        RBL(ARM ROM Boot Loader)在晶片出廠的時候就已經燒寫到ROM裡了,這不需要大家關心,上電後,RBL會自動從EMIFA EM_CS2 memory space (0x0200 0000). 執行指令,這個地址就是NAND FLASH 或NOR FLASH的片選起始地址。當你的系統設定為NAND BOOT的時候,UBL(User Boot Loader)是必不可少的,否則RBL不能直接把UBOOT給BOOT起來,因為RBL只支援14K NAND FLASH 的 BOOT程式,而UBOOT編譯出來後的bin檔案一般都大於80K,特別是版本越高,UBOOT的程式碼越大,所以這時候就需要寫一個UBL。UBL 從NAND FLASH 讀取UBOOT,然後把UBOOT COPY 到 DDR2(RAM)的相關地址上,然後把UBOOT 給BOOT 起來。根據TI DAVIN RBL的規定,不同型號的NAND FLASH,UBL儲存的地址是不同的,512位元組PAGE 的NAND(即SMALL PAGE),儲存的地址是:0x00004000;2048位元組PAGE的NAND (即LARGE PAGE)儲存的地址是:0x20000。至於如何通過XDS560模擬器燒寫UBL或通過UART BOOT燒寫UBL,本人放在DAVINCI UBOOT移植的文章介紹。(提示:RBL和UBL不要混淆!多看看BOOT的順序圖。)
        UBL的移植,比較簡單,當然,前提條件你已經搭好交叉編譯環境。進入UBL檔案包最上層的資料夾,使用make 就可以編譯出:ubl_davinci_nand.bin。UBL主要有:         ubl.c    dm644x.c   util.c   nand.c   nandboot.c   nor.c   norboot.c   uart.c   uartboot.c   ubl_davinci.lds
相關的*.h 檔案和兩個makefile檔案。如果最上層的makefile選擇$(MAKE) -C src FLASH=nand,表示使用ARM nand flash boot模式,這時NOR,UART BOOT模式相關的c檔案不會編譯。
介紹一下:
        ubl_davinci.lds: 指定UBL的SECTIONS及UBL本身的入口地址;
        ubl.c:從selfcopy函式開始執行,COPY自己到RAM,然後跳到正常入口地址,執行boot(),main()等函式,呼叫DM644xInit(),COPY UBOOT到RAM相關地址,最後執行UBOOT的入口地址(EntryPoint),這時UBOOT就可以運行了。
        dm644x.c:主要配置最小系統,比如關中斷、PLL1、PLL2設定、DDR2 時序設定、UART設定,等等。
        util.c:是一些相關的malloc等公共函式。
        nand.c:主要是NAND FLASH的驅動;
        nandboot.c:主要是實現NAND_Copy,把UBOOT從NAND COPY到相應的DDR2(RAM)裡。
        UBL要移植的東西不是很多,主要是在dm644x.c裡要定義好,Uint32 PLL1_Mult = 22;  // DSP=594 MHz for DM6446,DM6441一般使用Uint32 PLL1_Mult = 19;  // DSP=513 MHz。在PLL2Init()函式裡,使用不同型號的DDR,要設定不同的引數,即時序引數等,這是關鍵的地方。
        Nand.c及nand.h主要移植就是定義好UBOOT在NAND的儲存地址,不同型號的NAND FLASH ,比如SMALL PAGE(512位元組)和LARGE PAGE(2048位元組)這些都要修改除非你的NAND的型別和TI EVM 相容。
        nandboot.c主要任務就是如何把u-boot.bin或帶有頭的u-boot.img正確COPY到DDR裡,這裡最容易出問題,編譯出來的U-BOOT檔案一般帶有Valid magic number(MAGIC_NUMBER_VALID),入口地址entrypaoit,這些資訊不對都使UBOOT 執行不起來,建議看一下或COPY UBOOT的image.h。
        UBL把UBOOT執行起來,很多事情都可以做了,LINUX KERNEL,ROOTFS,NFS,DSP,裝置驅動,應用等等,都可開始按部就班開發。