Uboot移植
第一阶段功能
硬件设备初始化
- 设置异常向量
arm异常向量表
地址 | 异常类型 | 进入模式 | 说明 |
---|---|---|---|
0x00000000 | 复位 | 管理模式 | 复位电平有效时产生 |
0x00000004 | 未定义指令 | 未定义指令模式 | 遇到ARM处理器无法识别的指令时产生 |
0x00000008 | 软件中断 | 管理模式 | SWI指令产生 |
0x0000000c | 预取指令 | 中止模式 | 当获取的指令不存在时产生 |
0x00000010 | 数据访问 | 中止模式 | 当获取的数据不存在时产生 |
0x00000014 | 保留 | 保留 | 保留 |
0x00000018 | IRQ | IRQ模式 | 中断请求有效,并且CRSR中的I位为0 |
0x0000001c | FIQ | FIQ模式 | 快速中断请求有效,并且CRSR中的F为0 |
cpu/arm*/start.s
.globl _start
_start: b 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
_undefined_instruction: .word _undefined_instruction
_software_interrupt: .word _software_interrupt
_prefetch_abort: .word _prefetch_abort
_data_abort: .word _data_abort
_not_used: .word _not_used
_irq: .word _irq
_fiq: .word _fiq
_pad: .word 0x12345678 /* now 16*4=64 */
- CPU进入SVC模式
设置禁止位置为1,从而屏蔽IRQ和FIQ中断
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0
- 设置控制寄存器地址
- 关闭看门狗
ldr r0, =ELFIN_WATCHDOG_BASE /* 0xE2700000 */
mov r1, #0
str r1, [r0]
- 屏蔽中断
/* Disable all interrupts (VIC0, VIC1 and VIC2) */
mvn r3, #0x0
str r3, [r0, #0x14] @ INTENCLEAR
str r3, [r1, #0x14] @ INTENCLEAR
str r3, [r2, #0x14] @ INTENCLEAR
/* Set all interrupts as IRQ */
str r5, [r0, #0xc] @ INTSELECT
str r5, [r1, #0xc] @ INTSELECT
str r5, [r2, #0xc] @ INTSELECT
/* Pending Interrupt Clear */
str r5, [r0, #0xf00] @ INTADDRESS
str r5, [r1, #0xf00] @ INTADDRESS
str r5, [r2, #0xf00] @ INTADDRESS
- 设置MPLLCON、UPLLCON、CLKDIVN
- 关闭MMU和cache
cpu_init_crit:
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
#ifdef CONFIG_SYS_ICACHE_OFF
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
#else
orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
#endif
mcr p15, 0, r0, c1, c0, 0
/*
* Jump to board specific initialization...
* The Mask ROM will have already initialized
* basic memory. Go here to bump up clock rate and handle
* wake up conditions.
*/
mov ip, lr @ persevere link reg across call
bl lowlevel_init @ go setup pll,mux,memory
mov lr, ip @ restore link
mov pc, lr @ back to my caller
- 初始化存储控制器
加载U-boot第二阶段代码到RAM空间
将uboot拷贝到DRAM最后面的内存区域中,为Linux腾出空间
设置好栈
通过对DRAM整体使用规划,在DRAM中合适的地方设置栈
清除BSS段
.macro CLEAR_BSS
ldr r0, =__bss_start /* this is auto-relocated! */
#ifdef CONFIG_USE_ARCH_MEMSET
ldr r3, =__bss_end /* this is auto-relocated! */
mov r1, #0x00000000 /* prepare zero to clear BSS */
subs r2, r3, r0 /* r2 = memset len */
bl memset
#else
ldr r1, =__bss_end /* this is auto-relocated! */
mov r2, #0x00000000 /* prepare zero to clear BSS */
clbss_l:cmp r0, r1 /* while not at end of BSS */
strlo r2, [r0] /* clear 32-bit BSS word */
addlo r0, r0, #4 /* move to next */
blo clbss_l
#endif
远跳转到第二阶段执行入口board_init_r,第一阶段执行完(BSS段是用来存储静态变量,全局变量的)
跳转到第二阶段代码入口
第二阶段功能
在第一阶段中,为第二阶段的函数调用提供了基础,比如gb结构,堆栈等,程序运行在main_loop中,根据获取到的bootcmd准备进入linux内核.
在第二阶段不管是bootz还是bootm命令,启动Linux的时候都会用到一个全局的变量:images,主要存放系统镜像相关数据.
而程序最终进入Linux内核的是do_bootm_linux()