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。
阅读(2787) | 评论(0) | 转发(0) |