u-boot 上电后,首先会到 start.S 文件中执行 reset 的动作!所以这里的分析也是从 reset 这里开始讲!
_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
...
reset:
// disable watchdog timer
mov r0, #WTCON_BASE
ldr r1, =0x0
str r1, [r0, #oWTCON]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r0, #INT_BASE
ldr r1, =0xffffffff
str r1, [r0, #oINTMSK]
ldr r1, =0x7ff
str r1, [r0, #oINTSUBMSK] /* mask interrupt server */
/* clock setting */
mov r0, #CLK_BASE
ldr r1, =0xffffffff
str r1, [r0, #oLOCKTIME] /* PLL lock time count register */
/* FCLK:HCLK:PCLK */
ldr r1, =0x0
str r1, [r0, #oCAMDIVN] /* setting camera clock setting , not use */
ldr r1, =_clkdivn /* 0x07, 1:3:6 */
str r1, [r0, #oCLKDIVN] /* clock divider control register */
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 */
/* UPLL setup */
ldr r1, =_upllcon
str r1, [r0, #oUPLLCON]
nop
nop
nop /* wait until upll has the effect */
nop
nop
/* PLL setup */
ldr r1, =_mpllcon
str r1, [r0, #oMPLLCON]
/* configure memory */
bl memset
/* Power Manage */
/* Check if this is a wake-up from sleep */
ldr r1, PMST_ADDR
ldr r0, [r1]
tst r0, #(PMST_SMR)
bne WakeupStart
// powon on
#ifdef CONFIG_S3C2440_NAND_BOOT
bl copy_myself
/* add by yczman to clear bss */
ldr r0, =_bss_start
ldr r1, =_bss_end
sub r1, r1, r0 /* r1:bss size, r0:bbs start */
bl mem_clear
/* jump to ram */
ldr r1, =on_the_ram
add pc, r1, #0
nop
nop
1:
b 1b /* infinite loop */
on_the_ram:
#endif
/* enable IRQ interrupt yczman */
msr cpsr_c, #0x5f /* set the I-bit = 0, enable the IRQ interrupt */
/* get read to call C functions */
ldr sp, DW_STACK_START /* setup stack pointer */
mov fp, #0 /* no previous frame, so fp=0 */
mov a2, #0 /* set argv to NULL */
// for debug
#if 0
/* ALL LED ON */
mov r1, #0x56000000 /* #GPIO_CTL_BASE */
add r1, r1, #0x10 /* oGPIO_B */
ldr r2, =(1<<16) /* GPB8 Output */
str r2, [r1, #0x0] /* oGPIO_CON */
ldr r2, =(0<<8) /* GPB8 Pll up */
str r2, [r1, #0x8] /* oGPIO_UP */
ldr r2, =(0<<8) /* GPB8 low */
str r2, [r1, #0x4] /* oGPIO_DAT */
#endif
ldr pc, _start_armboot
mov pc, #0 /* reboot */
#ifdef CONFIG_S3C2440_NAND_BOOT
copy_myself:
mov r10, lr
mov r1, #NAND_CTL_BASE /* NAND_CTL_BASE = 0x4E000000 */
ldr r2, =((3<<12)|(7<<8)|(3<<4)|(0<<0))
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
ldr r2, =((1<<4)|(0<<1)|(1<<0)) /* initial ECC, force CE to low, nandflash enable */
str r2, [r1, #oNFCONT]
ldr r2, =0x6 /* RnB Clear */
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]
mov r2, #0xff /* RESET command(reset nandflash) */
strb r2, [r1, #oNFCMD] /* str 1byte */
mov r3, #0 /* wait */
1:
add r3, r3, #0x1 /* r3=r3+1 */
cmp r3, #0xa
blt 1b /* jmp to 1 if r3<0x0a */
2:
ldr r2, [r1, #oNFSTAT] /* wait ready */
tst r2, #0x1 /* tst r2 first bit */
beq 2b /* jmp to 2 if no ready(0:busy, 1: enable operate) */
ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 /* Flash Memory Chip Disable */
str r2, [r1, #oNFCONT]
/* get read to call C functions (for nand_read()) */
ldr sp, DW_STACK_START /* setup stack pointer 0x31f00000 */
mov fp, #0 /* no previous frame, so fp=0 */
/* copy u-boot to RAM */
ldr r0, =UBOOT_RAM_BASE /* u-boot在RAM中的地址(32M中的31.5M-32M处, 512K) 0x31f8000 */
mov r1, #0x0 /* address u-boot在flash中地址 */
mov r2, #0x30000 /* size 长度192K */
bl nand_read_ll /* copy nand to ram */
tst r0, #0x0
beq ok_nand_read
ok_nand_read:
/* verify */
mov r0, #0 /* SDRAM */
ldr r1, =UBOOT_RAM_BASE /* u-boot在RAM中的地址 */
mov r2, #0x400 /* 4 bytes * 1024 = 4K-bytes */
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2,#4
beq done_nand_read
bne go_next
notmatch:
1:
b 1b
done_nand_read:
mov pc, r10
/*
* setup memory registers and memory timing
*/
memset:
/* initialise the static memory */
/* set memory control registers */
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
mov pc, lr
/*
* clear memory
* r0: start address
* r1: length
*/
mem_clear:
mov r2, #0
mov r3, r2
clear_loop:
stmia r0!, {r2}
subs r1, r1, #4
bne clear_loop
mov pc, lr