u-boot启动代码start.S详解 |
1)定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。 (2)设置异常向量(Exception Vector)。 (3)设置CPU的速度、时钟频率及终端控制寄存器。 (4)初始化内存控制器。 (5)将ROM中的程序复制到RAM中。 (6)初始化堆栈。 (7)转到RAM中执行,该工作可使用指令ldr pc来完成。
.globl _start //u-boot启动入口
_start: b reset //复位向量并且跳转到reset ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ldr pc, _data_abort ldr pc, _not_used ldr pc, _irq //中断向量 ldr pc, _fiq //中断向量 b sleep_setting //跳转到sleep_setting
系统上电或reset后,cpu的PC一般都指向0x0地址,在0x0地址上的指令是
reset: //复位启动子程序 /******** 设置CPU为SVC32模式***********/ mrs r0,cpsr //将CPSR状态寄存器读取,保存到R0中 bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0 //将R0写入状态寄存器中 /************** 关闭看门狗 ******************/ ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] /************** 关闭所有中断 *****************/ mov r1, #0xffffffff ldr r0, =INTMSK str r1, [r0] ldr r2, =0x7ff ldr r0, =INTSUBMSK str r2, [r0]
/************** 初始化系统时钟 *****************/
ldr r0, =LOCKTIME ldr r1, =0xffffff str r1, [r0]
clear_bss:
ldr r0, _bss_start //找到bss的起始地址 add r0, r0, #4 //从bss的第一个字开始 ldr r1, _bss_end // bss末尾地址 mov r2, #0x00000000 //清零
clbss_l:str r2, [r0] // bss段空间地址清零循环
add r0, r0, #4 cmp r0, r1 bne clbss_l
/***************** 关键的初始化子程序 ************************/
/ * cpu初始化关键寄存器 设置重要寄存器 设置内存时钟 * / cpu_init_crit: /** flush v4 I/D caches*/ mov r0, #0 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
/************* disable MMU stuff and caches ****************/
mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0
/******* 在重新定位前,我们要设置RAM的时间,因为内存时钟依赖开发板硬件的,你将会找到board目录底下的memsetup.S。**************/
mov ip, lr #ifndef CONFIG_S3C2440A_JTAG_BOOT bl memsetup //调用memsetup子程序(在board/smdk2442memsetup.S) #endif mov lr, ip mov pc, lr //子程序返回
memsetup:
/**************** 初始化内存 **************/ mov r1, #MEM_CTL_BASE adrl r2, mem_cfg_val add r3, r1, #52 1: ldr r4, [r2], #4 str r4, [r1], #4 cmp r1, r3 bne 1b /*********** 跳转到原来进来的下一个指令(start.S文件里) ***************/ mov pc, lr //子程序返回 并通过下段代码拷贝到内存里 /****************** 建立堆栈 *******************/
/**************** 跳转到C代码去 **************/
ldr pc, _start_armboot //跳转到start_armboot函数入口,start_armboot字保存函数入口指针 _start_armboot: .word start_armboot //start_armboot函数在lib_arm /board.c中实现 从此进入第二阶段C语言代码部分 |
u-boot启动代码start.S详解
最新推荐文章于 2022-06-24 18:53:56 发布