OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /*OUTPUT_FORMAT 定义输出文件格式*/
OUTPUT_ARCH(arm) /*OUTPUT_ARCH 为设置输出文件的体系结构*/
ENTRY(_start) /*ENTRY括号里的符号被设置为入口地址,这里由 _start 符号指定,通常在 src/blob/start.S 中*/
SECTIONS
{
. = 0x00000000; /*第1阶段代码从 0x0 开始, Blob 从这里启动*/
. = ALIGN(4);
.text : { *(.text) }
. = ALIGN(4);
.rodata : { *(.rodata) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
. = ALIGN(4);
.bss : { *(.bss) }
}
* 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
... ... ...
/* 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
bl memsetup
bl ledinit #初始化发光二极管,针对不同硬件有不同实现,可以为空函数
......
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 # 没有测试完继续循环
relocate:
adr r0, _start #源起始地址到 r0
add r2, r0, #(64 * 1024) #Blob映像的最大值
add r0, r0, #0x1000 #跳过前 4kb,就是 stage2 的起始位置, stage1 的大小为 4kb
ldr r1, BLOB_START
copy_loop:
ldmia r0!, {r3-r10} # r0从 4k 开始, r3-r10 为数据中转寄存器
stmia r1!, {r3-r10} # r3-r10 寄存器中的值复制到 r1 所指向的目的地址中
cmp r0, r2 #源开始地址是否等于源结束地址
ble copy_loop #不等就继续复制数据
ldr r0, BLOB_START
mov pc, r0
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) | Powered by Discuz! X3.2 |