"); //-->
/******************************************************************
* 启动代码。
** 如果不作内存初始化,就只建立堆栈,重新定位代码到RAM位置。
* 然后就可以跳到第二阶段的代码运行了。
**********************************************************************/
/* 保存变量的数据区 */
_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
#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
上面这段代码,主要保存一些全局变量,用于BOOT程序从FLASH拷贝到RAM,或者其它的使用。还有一些变量的长度是
通过连接脚本里得到,实际上由编译器算出来的。
看了数据区,这次要看从引导那里跳到这里执行时,运行什么东西了。
/** 实际运行的复位代码。从一开始运行的代码,就跳到这里运行。*/
reset:
/* * 设置cpu运行在SVC32模式。*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0x13
msr cpsr,r0
具体分析如下:
/** 实际运行的复位代码。从一开始运行的代码,就跳到这里运行。*/
reset:
/** 设置cpu运行在SVC32模式。S3C44B0共有7种模式。 */
mrs r0,cpsr
取得当前程序状态寄存器cpsr到r0。
bic r0,r0,#0x1f
这里使用位清除指令,把中断全部清除,只置位模式控制位。
orr r0,r0,#0x13
计算为超级保护模式。
msr cpsr,r0
设置cpsr为超级保护模式。
通过设置ARM的CPSR寄存器,让CPU运行在操作系统模式,为后面进行其它操作作好准备了。后面的代码如下:
/* * 当是从FLASH启动时,就要进行内存测试,当
* 是从RAM启动时,一般就是开发本源程序时,就
* 可以跳过。
*
*/
#ifdef CONFIG_INIT_CRITICAL
bl cpu_init_crit
/*
* 在重新定位之前,要进行RAM访问时间测试,因为每个开发
* 都是不一样的。
* 可以在文件memsetup.S里看到它的说明。
*/
bl memsetup
#endif
/* 进行重定位 */
relocate: /* 重定位Boot代码到RAM内存,比如从FLASH移到RAM */
adr r0, _start /* 把_start的相对地址移到r0 */
ldr r1, _TEXT_BASE /* 把_TEXT_BASE地址,就是BOOT在RAM中运行地址 */
cmp r0, r1 /* 比较两个地址是否相同,如果相同,就已经在RAM运行,否则就是FLASH中运行。*/
beq stack_setup
/* 是在FLASH中运行,要把FLASH中的BOOT代码移到RAM中,然后再运行. */
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2保存引导代码大小 */
add r2, r0, r2 /* r2保存引导代码最后地址 */
copy_loop:
ldmia r0!, {r3-r10} /* 从源地址[r0]读取8个字节到寄存器,每读一个就更新一
次r0地址 */
stmia r1!, {r3-r10} /* 拷贝寄存器r3-r10的值保存到 [r1]指明的地址,每写一
个字节,就增加1. */
cmp r0, r2 /* 判断是否拷贝到[r2]地址,就是引导代码结束位置。 */
ble copy_loop /* 循环拷贝 */
/*拷贝中断向量表,实际是建立起二级中断向量表,当CPU中断时,先运行FLASH中断,接着就转移到实际中向表执行
中断程序。*/
adr r0, real_vectors
add r2, r0, #1024
ldr r1, =0x0c000000
add r1, r1, #0x08
vector_copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble vector_copy_loop
/* 建立起堆栈 */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
ldr pc, _start_armboot /* 已经准备好了堆栈,就可跳到C写的代码里,由于我的代码是ARM,就是
跳到lib_arm\board.c(208):void start_armboot (void)中运行。 */
_start_armboot: .word start_armboot
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。