DM365的UBL源碼分析(一)

轉自:http://blog.chinaunix.net/space.php?uid=7214824&do=blog&id=160521

DM365是的啓動方式有兩種,通過BOOTSEL[2:0]引腳決定。當其爲001時,直接從AEMIF上啓 動,比如NOR和OneNAND。除此之外皆是從RBL啓動,順序爲RBL-UBL-UBOOT-KERNEL,比如NAND,串口,SD卡等。RBL會 搜尋block1到block24去找UBL,關於RBL啓動的詳細細節可以參考用戶指南關於ARM子系統的那篇文檔,很詳盡,下面只分析UBL的源碼。

 
      UBL源碼在PSP包裏的board_utilities\flash_utils目錄下,主要是COMMON目錄和各子平臺的目錄如DM36x等,內中除了UBL的源碼外還有CCS下JTAG的擦除燒寫源碼,串口燒寫源碼等。下面只分析UBL的啓動代碼。
 
      入門代碼是彙編文件start.S,主要是切換操作模式,建立堆棧等,然後跳轉到main函數,進入到Common\ubl\src目錄下的C文件ubl.c中。main函數如下:
 

// Main entry point

void main(void)
{
    
    // Call to real boot function code

    LOCAL_boot();
    
    // Jump to entry point

    DEBUG_printString("\r\nJumping to entry point at ");
    DEBUG_printHexInt(gEntryPoint);
    DEBUG_printString(".\r\n");
    APPEntry = (void (*)(void)) gEntryPoint;
    (*APPEntry)();     
}

      main函數主要調用了LOCAL_boot函數來進行實質的引導功能,下面是此函數的內容:

static Uint32 LOCAL_boot(void)
{
    DEVICE_BootMode bootMode;
    
    // Read boot mode

    bootMode = DEVICE_bootMode();
    
    if (bootMode == DEVICE_BOOTMODE_UART)
    {
        // Wait until the RBL is done using the UART.

        while((UART0->LSR & 0x40) == 0 );
    }
    
    // Platform Initialization

    if ( DEVICE_init() != E_PASS )
    {
        DEBUG_printString(devString);
        DEBUG_printString(" initialization failed!\r\n");
        asm(" MOV PC, #0");
    }
    else
    {
        DEBUG_printString(devString);
        DEBUG_printString(" initialization passed!\r\n");
    }
    
    // Set RAM pointer to beginning of RAM space

    UTIL_setCurrMemPtr(0);
    
    // Send some information to host

    DEBUG_printString("TI UBL Version: ");
    DEBUG_printString(UBL_VERSION_STRING);
    DEBUG_printString("\r\nBooting Catalog Boot Loader\r\nBootMode = ");
    
    // Select Boot Mode

#if defined(UBL_NAND)
    {
        //Report Bootmode to host

        DEBUG_printString("NAND\r\n");
        
        // Copy binary image application from NAND to RAM

        if (NANDBOOT_copy() != E_PASS)
        {
            DEBUG_printString("NAND Boot failed.\r\n");
            LOCAL_bootAbort();
        }
    }
#elif defined(UBL_NOR)
    {
        //Report Bootmode to host

        DEBUG_printString("NOR \r\n");
        
        // Copy binary application image from NOR to RAM

        if (NORBOOT_copy() != E_PASS)
        {
            DEBUG_printString("NOR Boot failed.\r\n");
            LOCAL_bootAbort();
        }
    }
#elif defined(UBL_SD_MMC)
    {
        //Report Bootmode to host

        DEBUG_printString("SD/MMC \r\n");
        
        // Copy binary of application image from SD/MMC card to RAM

        if (SDMMCBOOT_copy() != E_PASS)
        {
            DEBUG_printString("SD/MMC Boot failed.\r\n");
            LOCAL_bootAbort();
        }
    }
#else
    {
        //Report Bootmode to host

        DEBUG_printString("UART\r\n");
        UARTBOOT_copy();
    }
    
    
#endif
    
    DEBUG_printString(" DONE");
    
    UTIL_waitLoop(10000);
    
    DEVICE_TIMER0Stop();
    
    return E_PASS;
}


      先通過調用DEVICE_bootMode函數來判斷啓動方式(通過讀取SYS寄存器實現),而後調用了DEVICE_init函數來進行平臺的最底層初始化,包括電源域,時鐘,DDR,EMIF,UART,I2C,TIMER等,另有專篇分析。

      而後通過UTIL_setCurrMemPtr函數對全局變量currMemPtr賦值,以後用到。接着通過判斷不同的引導方式,採取不同的處理辦法,以 NAND啓動爲例,將調用NANDBOOT_copy函數,此函數另有專篇分析。此函數將NAND中的某些內容(就是UBOOT)搬移到RAM中,而後 UBL結束,控制權正式交給UBOOT。

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