上一篇分析makefile,到uboot的启动代码。
也称之为第一阶段。在lds链接脚本中指向cpu/arm920t/start.s&boot_init.s文件。
那么我们今天从start.s文件开始分析。
首先是硬件相关设定:
1、设置CPU工作模式为svc32
(这里为什么要设置为SVC32 mode,请参考https://blog.csdn.net/shao15232/article/details/106246517)
reset: /* 设置CPU工作模式为SVC32 */
/*
* set the cpu to SVC32 mode
*/
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr,r0
2、关看门狗
# define pWTCON 0x53000000
# define INTMOD 0X4A000004
# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
# define INTSUBMSK 0x4A00001C
# define CLKDIVN 0x4C000014 /* clock divisor register */
ldr r0, =pWTCON /*2410和2440关看门狗设置是一样的*/
mov r1, #0x0
str r1, [r0]
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
3、设置CPU时钟 MPLL UPLL CLK_DIV
#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 // read ctrl register
orr r1, r1, #0xc0000000 // Asynchronous
mcr p15, 0, r1, c1, c0, 0 // write ctrl register
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
4、根据GSTATUS[2] 来判断当前CPU应该被唤醒还是sleep
/* according to GSTATUS2[1],judgement sleep or wakeup*/
ldr r0, =GSTATUS2
ldr r1, [r0]
tst r1, #(1<<1) /* r1 & (1<<1) */
bne wake_up
5、设置栈
#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
#define CFG_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */
stack_setup:
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 */
6、relocate uboot 代码到RAM(这里可以是SDRAM也可以是SRAM芯片内置的4K RAM)
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 clear_bss
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
bl CopyCode2Ram /* r0: source, r1: dest, r2: size */
CopyCode2Ram需要看下面的代码:
/*主要是对NAND Flash的操作*/
#include <common.h>
#include <s3c2410.h>
#define BUSY 1
#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
#define NAND_SECTOR_SIZE_LP 2048
#define NAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1)
/* 供外部调用的函数 */
void nand_init_ll(v