结合Bootloader的相关知识,并参考ARM的汇编指令,分析下面的Bootloader代码。

来源:互联网 发布:sql 多个结果 编辑:程序博客网 时间:2024/06/05 19:28

globl _start
_start: b reset

reset:                           //复位起始

ldr r0, IC_BASE                 //将芯片基址载入R0寄存器中
mov r1, #0x00
str r1, [r0, #ICMR]             //初始化ICMR寄存器为0

ldr r0, PWR_BASE                //将电源管理基址载入R0寄存器中
ldr r1, cpuspeed                //设定CPU时钟
str r1, [r0, #PPCR]             //将设定的时钟载入PPCR寄存器中(我猜测是使能该时钟)

bl ledinit                     //初始化LED
bl memsetup                    //初始化外部Memory设置

//该段应该是完成复位控制器的配置,由于没有具体的CPU手册,因此无法知道是完成了什么配置,建议你对照CPU手册查看一下,下面几段相同

ldr r0, RST_BASE               //载入复位控制器基址
ldr r1, [r0, #RCSR]            //读取RCSR寄存器的值到R1中
and r1, r1, #0x0f              //保留R1的低四位
teq r1, #0x08                  //若R1的第3位不为0,则跳转至normal_boot,否则继续执行
bne normal_boot /* no, continue booting */

mov r1, #0x08                
str r1, [r0, #RCSR] ;              //将RCSR寄存器设置为0x08

/* handle Power Manager Sleep Status Register (PSSR), see 9.5.7.5 from [1]*/
ldr r1, [r0, #PSSR]            //载入PSSR寄存器的值到R1中
orr r1, r1, #0x08
orr r1, r1, #0x10              //将R1寄存器的值的第3、4位置1
str r1, [r0, #PSSR]            //将该值写回PSSR寄存器

/* get the value from the PSPR and jump to it */
ldr r0, PWR_BASE                 //读取电源管理基址到R0中
ldr r1, [r0, #PSPR]              //读取PSPR内的值(我估计是一个地址)
mov pc, r1                       //跳转至读取的地址

normal_boot:
mov r7, #0x1000                 
mov r6, r7, lsl #8 /* 4k << 2^8 = 1MB */  //将0x1000左移8位放入R6中
ldr r5, BLOB_START        //载入BLOB_START的内容到R5中

relocate:                     //重定位,为代码复制做准备
adr r0, _start               //获取_start的地址

add r2, r0, #(64 * 1024) /* blob maximum size is 64kB */ //取R0地址后64KB的代码
add r0, r0, #0x400  /* skip first 1024 bytes */  //跳过起始的1K代码不复制
ldr r1, BLOB_START                               //设定目标地址到R1中

/* r0 = source address
  * r1 = target address
  * r2 = source end address
  */
copy_loop:                      //复制代码。每次复制8Byte
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble copy_loop

bl led_off                   //复制完成关闭LED指示

ldr r0, BLOB_START           //获取程序入口
mov pc, r0                   //跳转至程序入口,第一阶段初始化完成

原创粉丝点击