一、源码详解(第一阶段)

入口

# < cpu\arm920t\start.S >

.globl _start

_start: b start_code

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

start_code:

    ......

启动流程

设置CPU为SVC32模式

# < cpu\arm920t\start.S >

// set the cpu to SVC32 mode

mrs r0, cpsr

bic r0, r0, #0x1f

orr r0, r0, #0xd3

msr cpsr, r0

 

说明:先设置为sys模式(sys模式具有可以直接切换到其他模式等特权),然后设置为svc模式。

关闭看门狗

# < cpu\arm920t\start.S >

    /* turn off the watchdog */

#  define pWTCON 0x53000000

ldr r0, =pWTCON

mov r1, #0x0

str r1, [r0]

关闭中断

# < cpu\arm920t\start.S >

// mask all IRQs by setting all bits in the INTMR - default

mov r1, #0xffffffff

ldr r0, =INTMSK

str r1, [r0]

# if defined(CONFIG_S3C2440)

ldr r1, =0x7ff

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

 

设置分频系数与锁相环(控制CPU频率FCLK的锁相环MPLL)

# < cpu\arm920t\start.S >

# if defined(CONFIG_S3C2440)

#  define CLKDIVN 0x4C000014 /* clock divisor register */

# define vMPLLCON 0x4C000004

# define MPSDIV ((0x7f<<12) | (0x2<<4) | (0x1<<0))

/* FCLK:HCLK:PCLK = 1:4:8 */

/* default FCLK is 405 MHz ! */

ldr r0, =CLKDIVN

mov r1, #5

str r1, [r0]

mrc p15, 0, r1, c1, c0, 0

orr r1, r1, #0xc0000000

mcr p15, 0, r1, c1, c0, 0

ldr r0, =vMPLLCON

ldr r1, =MPSDIV

str r1, [r0] /*MPLLCON vbird*/

# endif

/*

 * 对于MPLLCON寄存器,[19:12]为MDIV,[9:4]为PDIV,[1:0]为SDIV

 * 有如下计算公式:

 *  S3C2410: MPLL(FCLK) = (m * Fin)/(p * 2^s)

 *  S3C2440: MPLL(FCLK) = (2 * m * Fin)/(p * 2^s)

 *  其中: m = MDIV + 8, p = PDIV + 2, s = SDIV

 * 对于本开发板,Fin = 12MHz

 * 设置CLKDIVN,令分频比为:FCLK:HCLK:PCLK=1:4:8,

 * FCLK=400MHz,HCLK=100MHz,PCLK=50MHz

 */

 

 

CPU设置

# < cpu\arm920t\start.S >

// we do sys-critical inits only at reboot, not when booting from ram!

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

bl cpu_init_crit

#endif

# < cpu\arm920t\start.S >

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

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 */

/*

* 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

/*

* before relocating, we have to setup RAM timing

* because memory timing is board-dependend, you will

* find a lowlevel_init.S in your board directory.

*/

mov ip, lr

bl  lowlevel_init

mov lr, ip

mov pc, lr

#endif /* CONFIG_SKIP_LOWLEVEL_INIT */

关闭I/D cache(指令/数据缓存)

禁用MMU通道和缓存

设置RAM数据周期(在RAM运行带依赖RAM设置;代码重定位之前,设置RAM读写频率)

# < board\vbird\mini2440\lowlevel_init.S >

#define BWSCON 0x48000000

/* BWSCON */

#define DW8 (0x0)

#define DW16 (0x1)

#define DW32 (0x2)

#define WAIT (0x1<<2)

#define UBLB (0x1<<3)

#define B1_BWSCON (DW32)

#define B2_BWSCON (DW16)

#define B3_BWSCON (DW16 + WAIT + UBLB)

#define B4_BWSCON (DW16)

#define B5_BWSCON (DW16)

#define B6_BWSCON (DW32)

#define B7_BWSCON (DW32)

/* BANK0CON */

#define B0_Tacs 0x0 /*  0clk */

#define B0_Tcos 0x0 /*  0clk */

#define B0_Tacc 0x7 /* 14clk */

#define B0_Tcoh 0x0 /*  0clk */

#define B0_Tah 0x0 /*  0clk */

#define B0_Tacp 0x0

#define B0_PMC 0x0 /* normal */

/* BANK1CON */

#define B1_Tacs 0x0 /*  0clk */

#define B1_Tcos 0x0 /*  0clk */

#define B1_Tacc 0x7 /* 14clk */

#define B1_Tcoh 0x0 /*  0clk */

#define B1_Tah 0x0 /*  0clk */

#define B1_Tacp 0x0

#define B1_PMC 0x0

#define B2_Tacs 0x0

#define B2_Tcos 0x0

#define B2_Tacc 0x7

#define B2_Tcoh 0x0

#define B2_Tah 0x0

#define B2_Tacp 0x0

#define B2_PMC 0x0

#define B3_Tacs 0x0 /*  0clk */

#define B3_Tcos 0x3 /*  4clk */

#define B3_Tacc 0x7 /* 14clk */

#define B3_Tcoh 0x1 /*  1clk */

#define B3_Tah 0x0 /*  0clk */

#define B3_Tacp 0x3     /*  6clk */

#define B3_PMC 0x0 /* normal */

#define B4_Tacs 0x0 /*  0clk */

#define B4_Tcos 0x0 /*  0clk */

#define B4_Tacc 0x7 /* 14clk */

#define B4_Tcoh 0x0 /*  0clk */

#define B4_Tah 0x0 /*  0clk */

#define B4_Tacp 0x0

#define B4_PMC 0x0 /* normal */

#define B5_Tacs 0x0 /*  0clk */

#define B5_Tcos 0x0 /*  0clk */

#define B5_Tacc 0x7 /* 14clk */

#define B5_Tcoh 0x0 /*  0clk */

#define B5_Tah 0x0 /*  0clk */

#define B5_Tacp 0x0

#define B5_PMC 0x0 /* normal */

#define B6_MT 0x3 /* SDRAM */

#define B6_Trcd 0x1

#define B6_SCAN 0x1 /* 9bit */

#define B7_MT 0x3 /* SDRAM */

#define B7_Trcd 0x1 /* 3clk */

#define B7_SCAN 0x1 /* 9bit */

/* REFRESH parameter */

#define REFEN 0x1 /* Refresh enable */

#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */

#define Trp 0x0 /* 2clk */

#define Trc 0x3 /* 7clk */

#define Tchr 0x2 /* 3clk */

#define REFCNT 1258 /* period=7.8125us, HCLK=101.25Mhz, (2048+1-7.8125*101.25) */

_TEXT_BASE:

.word TEXT_BASE    // 0x33F80000

.globl lowlevel_init

lowlevel_init:

/* memory control configuration */

/* make r0 relative the current location so that it */

/* reads SMRDATA out of FLASH rather than memory ! */

ldr     r0, =SMRDATA

ldr r1, =lowlevel_init

sub r0, r0, r1

adr r3, lowlevel_init

add r0, r0, r3

ldr r1, =BWSCON /* Bus Width Status Controller */

add     r2, r0, #13*4

0:

ldr     r3, [r0], #4

str     r3, [r1], #4

cmp     r2, r0

bne     0b

/* everything is fine now */

mov pc, lr

.ltorg

/* the literal pools origin */

SMRDATA:

    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))

    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))

    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))

    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))

    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))

    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))

    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))

    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))

    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))

    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)

    .word 0x32

    .word 0x30

    .word 0x30

说明:

计算lowlevel_init 到 SMRDATA 绝对地址差

lowlevel_init + 绝对地址差 =》SMRDATA 相对(lowlevel_init )地址

循环13次,每次4字节,设置BWSCON

判断代码位置

# < cpu\arm920t\start.S >

relocate1: /* 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

设置栈(为调转c语言准备环境);清除bss段

# < cpu\arm920t\start.S >

/* Set up the stack    */

stack_setup:

ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot   */

sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area              */

sub r0, r0, #CONFIG_SYS_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    */

clear_bss:

ldr r0, _bss_start /* find start of bss segment        */

ldr r1, _bss_end /* stop here                        */

mov r2, #0x00000000 /* clear                            */

clbss_l:

str r2, [r0] /* clear loop...                    */

add r0, r0, #4

cmp r0, r1

ble clbss_l

ldr pc, _start_armboot

_start_armboot: .word start_armboot

跳转第二阶段

猜你喜欢

转载自blog.csdn.net/liutit/article/details/130034140