uboot 源码阅读笔记 1
cpu/arm920t/start.S
在开始处首先定义了一个全局的标签,
.globl _start
这个是整个uboot程序的入口,可在链接脚本 board/s3c2410/u-boot.lds中找到。
这个标签所指的地址处就是一跳转指令
_start: b reset
开始复位。
reset:
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
/* disable IRQ and FIQ, ARM instruct set, supervisor mode. added by BoySKung*/
orr r0,r0,#0xd3
msr cpsr,r0
首先将cpu设置为supervisor模式。通过设置cpsr的低5位为10011实现,并禁止IRQ、FIQ。即cpsr的第七第六位设置为11.
接着关闭看门狗定时器
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
将看门狗定时器控制寄存器置0。
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
设置FCLK:HCLK:PCLK为1:2:4, 通过设置CLKDIVN控制寄存器的HDIVN、PDIVN值实现不同的比例
00(1:1:1)
01(1:1:2)
10(1:2:2)
11(1:2:4)
这些然后开初始化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 */
首先关闭ICache 和DCache.
/*
* 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
关闭MMU,数据存储格式为小端。开启数据地址对齐错误检测,使能ICACHE。
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a memsetup.S in your board directory.
*/
mov ip, lr
bl memsetup
mov lr, ip
mov pc, lr
还要对内存时序进行设置,因为内存时序是依赖于开发板的。
Cpu 初始化结束后,开始初始化串口uart
@ Initialize UART
@
@ r0 = number of UART port
InitUART:
ldr r1, =0x50000000
mov r2, #0x0
str r2, [r1, #0x8]
str r2, [r1, #0xc]
mov r2, #0x3
str r2, [r1, #0x0]
ldr r2, =0x245
str r2, [r1, #0x4]
/* 50700000 = PCLK = 202.8 / 4 = 50.7 when FCLK at 202.8 */
#define UART_BRD ((50700000 / (115200 * 16)) - 1)
mov r2, #UART_BRD
str r2, [r1, #0x28]
这里主要对uart的一些控制寄存器进行了设置,并设置了串口的波特率
mov r3, #100
mov r2, #0x0
1: sub r3, r3, #0x1
tst r2, r3
bne 1b
mov pc, lr
这里是一段延时,具体起什么作用还不清楚。
这些初始化都结束后开始代码重定位
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
重定位时,首先检查当前是不是在ram中运行,若是则不需重定位
紧接着设置堆栈
stack_setup:
@ldr r1, =0x48000004
@ldr r0, [r1]
@bl PrintHexWord
/* enter ansynchronous, when cpu at 202.8MHZ, it must into asynchronous mode*/
mrc p15, 0, r1, c1, c0, 0 @ read ctrl register
orr r1, r1, #0xc0000000 @ Asynchronous
mcr p15, 0, r1, c1, c0, 0 @ write ctrl register
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
清除bss段
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
add r0, r0, #4 /* start at first byte of bss */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:str r2, [r0] /* clear loop... */
add r0, r0, #4
cmp r0, r1
bne clbss_l
就是将bss段全部置0
最后
ldr pc, _start_armboot
开始进入c的世界,uboot启动的stage 2