dm3730 xload启动过程略解
困惑于前面的博文中提到的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跳入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是最好的解决方法。
上一篇: Native.js技术简介及个人总结
下一篇: 动态加载js代码