从链接脚本可以知道,上电运行第一个文件是u-boot-1.1.6/cpu/arm920t/start.S
start.S完成的是u-boot启动的第一阶段,主要是完成一些硬件初始化并且转入u-boot第二阶段
总的来说有这么九个内容:
1、设置为SVC32模式
_start: b reset /*跳转到reset*/
……
reset:
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0 /*4行命令表示设置cpu为SVC32模式*/
2、关闭看门狗
#if defined(CONFIG_S3C2400)
# define pWTCON 0x15300000
# define INTMSK 0x14400008 /* Interupt-Controller base addresses */
# define CLKDIVN 0x14800014 /* clock divisor register */
#elif defined(CONFIG_S3C2410)
# define pWTCON 0x53000000
# define INTMOD 0X4A000004
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
# define CLKDIVN 0x4C000014 /* clock divisor register */
#endif
3、屏蔽中断
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
#endif /* 屏蔽所有中断 */
4、设置时钟
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
#define S3C2440_MPLL_400MHZ ((0x5c<<12)|(0x01<<4)|(0x01))
#define S3C2440_UPLL_48MHZ ((0x38<<12)|(0x02<<4)|(0x02))
#define S3C2440_CLKDIV (0x05) // | (1<<3)) /* FCLK:HCLK:PCLK = 1:4:8, UCLK = UPLL/2 */
ldr r1, =CLKDIVN
mov r2, #S3C2440_CLKDIV
str r2, [r1]
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
ldr r0,=LOCKTIME
ldr r1,=0xffffff
str r1,[r0]
// delay
mov r0, #0x200
1: subs r0, r0, #1
bne 1b
// Configure MPLL
ldr r0,=MPLLCON
ldr r1,=S3C2440_MPLL_400MHZ
str r1,[r0]
// delay
mov r0, #0x200
1: subs r0, r0, #1
bne 1b
//Configure UPLL
ldr r0, =UPLLCON
ldr r1, =S3C2440_UPLL_48MHZ
str r1, [r0]
// delay
mov r0, #0x200
1: subs r0, r0, #1
bne 1b
#endif /*这一段程序作用是初始化时钟*/
5、初始化SDRAM
#ifndef CONFIG_SKIP_LOWLEVEL_INIT /*判断SDRAM是否已经初始化*/
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 */
blne cpu_init_crit /*如果__start == _TEST_BASE(通过调试器下载代码),跳转*/
#endif
6、预留内存,设置栈
stack_setup:
ldr r0, _TEXT_BASE /*得到u-boot地址*/
sub r0, r0, #CFG_MALLOC_LEN /*预留堆空间*/
sub r0, r0, #CFG_GBL_DATA_SIZE /*预留GBL空间*/
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) /*预留IRQ、FIQ所需空间*/
#endif
sub sp, r0, #12 /*预留3字节空间,设置栈指针*/
7、代码重定位
relocate:
adr r0, _start /*得到_start地址*/
ldr r1, _TEXT_BASE /* 得到代码段地址*/
cmp r0, r1 /*比较两者,若地址不一致,说明代码并未放在运行地址,执行重定位,否则跳过重定位*/
beq clear_bss /*直接跳转到清除bss段*/
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /*设置重定位的程序参数r0、r1、r2、r3*/
bl CopyCode2Ram /*转入重定位*/
8、清除bss段
clear_bss: /*清除bss段*/
ldr r0, _bss_start /*bss段起始地址*/
ldr r1, _bss_end /*bss段结束地址*/
mov r2, #0x00000000
clbss_l:str r2, [r0] /*清除bss段的循环*/
add r0, r0, #4
cmp r0, r1
ble clbss_l
9、转入u-boot第二阶段
ldr pc, _start_armboot /*转入u-boot第二阶段*/
_start_armboot: .word start_armboot