|
沙发

楼主 |
发表于 2009-9-7 21:26:31
|
只看该作者
src/blob/start.S | stage1 阶段
* Jump vector table as in table 3.1 in [1] */
.globl _start /*输出全局符号*/
_start: b reset /*Blob的入口处*/
/*ARM 的异常向量处理*/
b undefined_instruction
b software_interrupt
b prefetch_abort
b data_abort
b not_used
b irq
b fiq
... ... ...
/*stage2 部分运行的地址,通常在内存中,各种不同的平台有不同的定义,这些定义在 include/blob/arch/ 下*/
/* main memory starts at 0xc0000000 -->这个值根据平台的不同而不同*/
BLOB_START: .word BLOB_ABS_BASE_ADDR # 这里, BLOB_START 和 BLOB_ABS_BASE_ADDR 相同
/*复位运行代码 -- 这里的 CPU 为 Intel 的 PXA70*/
/* First, mask **ALL** interrupts */
mrs r0, cpsr #读取状态寄存器的内容到 r0
bic r0, r0, #0x1f #0x1f 对应于状态寄存器 cpsr 的后 5 位,为设置模式位,这里先对 M[4:0] 位都清 0
orr r0, r0, #0x13 #所有中断关闭,设置进入 SVC32 模式
msr cpsr, r0 #r0 中的值写回 cpsr
/*配置存储器等信息,包括 I/O 口,SDRAM 控制器以及各 Bank 存储模式等*/bl memsetup
bl ledinit #初始化发光二极管,针对不同硬件有不同实现,可以为空函数
......
/*从 Blob stage2 所在的内存开始测试连续的 1MB 空间是否可用*/mov r7, #0x1000 #4k
mov r6, r7, lsl #8 #r6 = 4k * 2^8 = 1024k = 1MB
ldr r5, BLOB_START #stage2 部分的开始地址装辱 r5
/*内存循环测试*/mem_test_loop:
mov r0, r5
bl testram # 进入内存测试函数
teq r0, 1 # testram 的返回值在 r0 中,如果为 1,则表示内存有问题,一次测试 4k
beq badram # 内存不可用处理函数
add r5, r5, r7 # 移动到下一个 4k 单元
subs r6, r6, r7 # 是否测试完
bne mem_test_loop # 没有测试完继续循环
/*计算 stage2 在 Flash 存储器中的位置并复制到内存中。这里,假设 Blob 的映像不会超过 64k,可根据实际需要扩大这个数值*/relocate:
adr r0, _start #源起始地址到 r0
add r2, r0, #(64 * 1024) #Blob映像的最大值
add r0, r0, #0x1000 #跳过前 4kb,就是 stage2 的起始位置, stage1 的大小为 4kb
ldr r1, BLOB_START
/* 开始把 stage2 复制到内存,这时
*r0 = 源起始地址
*r1 = 目的地址
*r2 = 源结束地址
*/ copy_loop:
ldmia r0!, {r3-r10} # r0从 4k 开始, r3-r10 为数据中转寄存器
stmia r1!, {r3-r10} # r3-r10 寄存器中的值复制到 r1 所指向的目的地址中
cmp r0, r2 #源开始地址是否等于源结束地址
ble copy_loop #不等就继续复制数据 /*经过上面的步骤后,Blob 的 stage2 已经复制到内存中,跳转过去运行*/
ldr r0, BLOB_START
mov pc, r0
这就是 stage1 的主体流程,完全由汇编语言写成,这部分程序工作时,也不需要堆栈空间。 stage1 主要完沉过了两个任务:配置处理器和复制 stage2 到内存并运行。复制以后的 FLASH 和 内存中的 BLOB 如下图所示: |
|