困惑於前面的博文中提到的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是最好的解決方法。