程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> dm3730 xload啟動過程略解

dm3730 xload啟動過程略解

編輯:關於JSP

困惑於前面的博文中提到的xload啟動的問題,這次仔細的看了一下,也從網上學習了一些xload的啟動過程。
從內部的fireware啟動xload開始,xload首先加載的是x-load.lds:
[html]
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 
OUTPUT_ARCH(arm) 
ENTRY(_start) 
SECTIONS 

    . = 0x00000000; 
 
    . = ALIGN(4); 
    .text      : 
    { 
      cpu/omap3/start.o (.text) 
      *(.text) 
    } 
 
    . = ALIGN(4); 
    .rodata : { *(.rodata) } 
 
    . = ALIGN(4); 
    .data : { *(.data) } 
 
    . = ALIGN(4); 
    .got : { *(.got) } 
 
    . = ALIGN(4); 
    __bss_start = .; 
    .bss : { *(.bss) } 
    _end = .; 

從這段代碼的text代碼段中可以看出,入口函數的ENTRY 為start函數,位於cpu/omap3/start.s中,這部份代碼完成了匯編和C語言的交互,部分代碼如下所示:
[html]
.globl _start 
_start:  
    b   reset            <span style="color:#FF6666;"> <span style="color:#FF0000;">//首先跳入reset函數,不再返回</span></span> 
    ldr pc, _hang 
    。。。。。。 
 
_hang: 
    .word do_hang 
     
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 /* now 16*4=64 */ 
 
.global _end_vect 
_end_vect: 
 
    .balignl 16,0xdeadbeef 
/* 
 ************************************************************************* 
 * 
 * Startup Code (reset vector) 
 * 
 * do important init only if we don't start from memory! 
 * setup Memory and board specific bits prior to relocation. 
 * relocate armboot to ram 
 * setup stack 
 * 
 ************************************************************************* 
 */ 
 
_TEXT_BASE: 
    .word   TEXT_BASE 
 
.globl _armboot_start 
_armboot_start: 
    .word _start 
 
/* 
 * These are defined in the board-specific linker script. 
 */ 
.globl _bss_start 
_bss_start: 
    .word __bss_start 
 
.globl _bss_end 
_bss_end: 
    .word _end 
 
/* 
 * the actual reset code 
 */ 
 
reset:  
    /* 
     * set the cpu to SVC32 mode 
     */ 
    ....... 
next: 
    ...... 
 
    bl  cpy_clk_code            /* put dpll adjust code behind vectors */  <span style="color:#FF0000;">//完成clk的初始化</span> 
  
    /* the mask ROM code should have PLL and others stable */ 
    bl  cpu_init_crit         <span style="color:#FF0000;">//這部分是解決我的問題的關鍵,這裡會調用C語言的內容。</span> 
 
relocate:               /* relocate U-Boot to RAM       */ 
    。。。。。。。。。。。。 
 
copy_loop: 
    。。。。。。。。。 
    /* Set up the stack                         */ 
stack_setup: 
    ldr r0, _TEXT_BASE      /* upper 128 KiB: relocated uboot   */ 
    sub sp, r0, #128        /* leave 32 words for abort-stack   */ 
    and sp, sp, #~7     /* 8 byte alinged for (ldr/str)d    */ 
 
    /* Clear BSS (if any).  Is below tx (watch load addr - need space)  */ 
clear_bss: 
    ldr r0, _bss_start      /* find start of bss segment        */ 
    ldr r1, _bss_end        /* stop here                        */ 
    mov     r2, #0x00000000     /* clear value                      */ 
clbss_l: 
    str r2, [r0]        /* clear BSS location               */ 
    cmp r0, r1          /* are we at the end yet            */ 
    add r0, r0, #4      /* increment clear index pointer    */ 
    bne clbss_l                 /* keep clearing till at end        */ 
 
    ldr pc, _start_armboot  /* jump to C code                   */  <span style="color:#FF0000;">//從這邊開始,其實是進入C語言加載uboot.bin啦</span>, 
<span style="color:#FF0000;background-color: rgb(255, 255, 255);">當然這裡會完成串口的初始化</span><span style="color:#FF0000;background-color: rgb(255, 255, 255);">,因此系統的信息只有此時才可以printf,</span> 
_start_armboot: .word start_armboot 
 
 
/* 
 ************************************************************************* 
 * 
 * CPU_init_critical registers 
 * 
 * setup important registers 
 * setup memory timing 
 * 
 ************************************************************************* 
 */ 
cpu_init_crit:  <span style="color:#FF0000;">//cpu的初始化,是xload啟動uboot前需要完成的內容</span> 
    /* 
     * Invalidate L1 I/D 
     */ 
        mov r0, #0                 /* set up for MCR */ 
        mcr p15, 0, r0, c8, c7, 0  /* invalidate TLBs */ 
        mcr p15, 0, r0, c7, c5, 1  /* invalidate icache */ 
 
    /* Invalide L2 cache (gp device call point)  
     * - warning, this may have issues on EMU/HS devices 
     * this call can corrupt r0-r5 
     */ 
    mov r12, #0x1       @ set up to invalide L2  
smi:    .word 0xE1600070    @ Call SMI monitor 
 
    /* 
     * disable MMU stuff and caches 
     */ 
    。。。。。。。。。。。。 
#ifndef CONFIG_ICACHE_OFF 
    orr r0, r0, #0x00001800 @ set bit 11,12 (---I Z---) BTB,I-Cache 
#endif 
    mcr p15, 0, r0, c1, c0, 0 
 
    /* 
         * Jump to board specific initialization... The Mask ROM will have already initialized 
         * basic memory.  Go here to bump up clock rate and handle wake up conditions. 
     */ 
    。。。。。。。。。。。。 
    bl  lowlevel_init   /* go setup pll,mux,memory */ <span style="color:#FF0000;">//這裡比較重要,是我問題的核心所在,因為這裡會跳入另一個匯編文件 
platform.s中,如下 

<span style="color:#000000;">.globl lowlevel_init 
lowlevel_init: 
    ldr    sp,    SRAM_STACK 
        str     ip,    [sp]    /* stash old link register */ 
    mov    ip,    lr    /* save link reg across call */ 
    bl      s_init          /* go setup pll,mux,memory */     <span style="color:#FF0000;">//在這裡BL跳入c語言omap3530beagle.c中去,因此這裡的調用比較隱蔽,是匯編和C的交互 
一般在匯編後形成函數的未解決符號表和導出符號表,不同編譯器和語言形成的符號格式有所不同。在鏈接階段完成程序的鏈接,當然這裡屬於靜態過程)</span> 
        ldr     ip,    [sp]    /* restore save ip */      
    mov    lr,    ip    /* restore link reg */ 
 
    /* back to arch calling code */ 
    mov    pc,    lr 
 
    /* the literal pools origin */ 
    .ltorg 
。。。}</span></span> 
 
    mov   lr, ip          /* restore link */ 
    mov pc, lr          /* back to my caller */ 
/* 
 * exception handler 
 */ 
    .align  5 
do_hang: 
    ldr sp, _TEXT_BASE      /* use 32 words abort stack */ 
    bl  hang            /* hang and never return */ 
<span style="color:#FF0000;"> //這是這段匯編出現異常時的反映,會跳入c語言中的hang函數。</span> 
下面我們來看s_init函數:
[html] 
int s_init(int skip) 

        u32   rev; 
 
        rev = get_cpu_rev(); 
 
        watchdog_init(); 
    try_unlock_sram();    
        muxSetupAll(); 
        delay(100); 
    prcm_init(); 
config_3430sdram_ddr() 
 。。。。。。。 
        return(0); 

這也是我起初沒有看到的問題,因為按道理這部分是必須先於board.c的start_armboot函數,畢竟是CPU,看門狗和sdram等的初始化。
而在config_3430sdram_ddr函數中,會對sdram的大小進行判別如下:
[html] 
if (beagle_revision() == REVISION_XM) { 
        if (identify_xm_ddr() == MICRON_DDR) { 
            __raw_writel(0x2, SDRC_CS_CFG); /* 256MB/bank */ 
            __raw_writel(SDP_SDRC_MDCFG_0_DDR_MICRON_XM, SDRC_MCFG_0); 
            __raw_writel(SDP_SDRC_MDCFG_0_DDR_MICRON_XM, SDRC_MCFG_1); 
            __raw_writel(MICRON_V_ACTIMA_200, SDRC_ACTIM_CTRLA_0); 
            __raw_writel(MICRON_V_ACTIMB_200, SDRC_ACTIM_CTRLB_0); 
            __raw_writel(MICRON_V_ACTIMA_200, SDRC_ACTIM_CTRLA_1); 
            __raw_writel(MICRON_V_ACTIMB_200, SDRC_ACTIM_CTRLB_1); 
            __raw_writel(SDP_3430_SDRC_RFR_CTRL_200MHz, SDRC_RFR_CTRL_0); 
            __raw_writel(SDP_3430_SDRC_RFR_CTRL_200MHz, SDRC_RFR_CTRL_1); 
        } else { 
            __raw_writel(0x4, SDRC_CS_CFG); /* 512MB/bank */ 
            __raw_writel(SDP_SDRC_MDCFG_0_DDR_NUMONYX_XM, SDRC_MCFG_0); 
            __raw_writel(SDP_SDRC_MDCFG_0_DDR_NUMONYX_XM, SDRC_MCFG_1); 
            __raw_writel(NUMONYX_V_ACTIMA_165, SDRC_ACTIM_CTRLA_0); 
            __raw_writel(NUMONYX_V_ACTIMB_165, SDRC_ACTIM_CTRLB_0); 
            __raw_writel(NUMONYX_V_ACTIMA_165, SDRC_ACTIM_CTRLA_1); 
            __raw_writel(NUMONYX_V_ACTIMB_165, SDRC_ACTIM_CTRLB_1); 
            __raw_writel(SDP_3430_SDRC_RFR_CTRL_165MHz, SDRC_RFR_CTRL_0); 
            __raw_writel(SDP_3430_SDRC_RFR_CTRL_165MHz, SDRC_RFR_CTRL_1); 
        } 
    } else { 
        __raw_writel(0x1, SDRC_CS_CFG); /* 128MB/bank */ 
        __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_0); 
        __raw_writel(SDP_SDRC_MDCFG_0_DDR, SDRC_MCFG_1); 
        __raw_writel(MICRON_V_ACTIMA_165, SDRC_ACTIM_CTRLA_0); 
        __raw_writel(MICRON_V_ACTIMB_165, SDRC_ACTIM_CTRLB_0); 
        __raw_writel(MICRON_V_ACTIMA_165, SDRC_ACTIM_CTRLA_1); 
        __raw_writel(MICRON_V_ACTIMB_165, SDRC_ACTIM_CTRLB_1); 
        __raw_writel(SDP_3430_SDRC_RFR_CTRL_165MHz, SDRC_RFR_CTRL_0); 
        __raw_writel(SDP_3430_SDRC_RFR_CTRL_165MHz, SDRC_RFR_CTRL_1); 
    } 
[html] 
beagle_revision() == REVISION_XM 
這句代碼,很重要,也很bug,因為前面函數返回的數值在缺少那個補丁時返回2,後者默認是0,當然不會進行512M的sdram配置處。
       總結,因此前期xload不能正常啟動原因在於這裡,而不是start_armboot函數中。因為連sdram都沒初始化好,後續程序就不能正常運行了。故REVSION_XM=2是最好的解決方法。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved