uboot笔记2

来源:互联网 发布:java shell 回写 编辑:程序博客网 时间:2024/06/05 06:06

UBOOT源码分析(uboot-1.1.6)

由链接文件可知,uboot第一个执行文件为start.S.

ARM单板上电,nand启动,先从flash中拷贝4K内容到soc内部ram中,开始运行。通过这段代码将boot代码拷贝到ram中来运行。

首先,设置异常向量表。

.globl _start

_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

 

_undefined_instruction:        .wordundefined_instruction

_software_interrupt:        .wordsoftware_interrupt

_prefetch_abort:        .wordprefetch_abort

_data_abort:                .worddata_abort

_not_used:                .wordnot_used

_irq:                        .wordirq

_fiq:                        .wordfiq

 

.balignl 16,0xdeadbeef

重启后,跳转到reset执行。

1、设置CPU为SVC管理模式

reset:

/*

 * set the cpu to SVC32 mode

 */

mrs        r0,cpsr

bic        r0,r0,#0x1f

orr        r0,r0,#0xd3

msr        cpsr,r0

2、关看门狗和禁止使能中断

/* turn off the watchdog*/

#ifdefined(CONFIG_S3C2400)

# definepWTCON                0x15300000

# defineINTMSK                0x14400008        /*Interupt-Controller base addresses */

# defineCLKDIVN        0x14800014        /*clock divisor register */

#elifdefined(CONFIG_S3C2410)

# definepWTCON                0x53000000

# define INTMOD     0X4A000004

# define INTMSK                0x4A000008        /*Interupt-Controller base addresses */

# defineINTSUBMSK        0x4A00001C

# defineCLKDIVN        0x4C000014        /*clock divisor register */

#endif

 

#ifdefined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)

ldr     r0, =pWTCON

mov     r1, #0x0

str     r1, [r0]

 

/*

 * mask all IRQs by setting all bits in theINTMR - default

 */

mov        r1,#0xffffffff

ldr        r0,=INTMSK

str        r1,[r0]

# ifdefined(CONFIG_S3C2410)

ldr        r1,=0x3ff

ldr        r0,=INTSUBMSK

str        r1,[r0]

# endif

3、初始化SDRAM

#ifndefCONFIG_SKIP_LOWLEVEL_INIT   没有定义该宏为正常启动过程,否则为调试启动,调试器直接下载uboot代码到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 duringdebug         */

blne        cpu_init_crit

#endif

_start,如果正常启动start位置为0。调试启动,调试器直接将代码下载链接地址(代码运行地址,0x33f80000)

_TEXT_BASE,为uboot.lds中指定的链接地址(0x33f80000)。

Cmp 如果这两个地址相同,说明为调试启动,那SDRAM已经被初始化过了。如果不同,那说明SDRAM还未被初始化,需要进入

cpu_init_crit里来初始化SDRAM。

4、cpu_init_crit

#ifndefCONFIG_SKIP_LOWLEVEL_INIT

cpu_init_crit:

/*

 * flush v4 I/D caches

 */

mov        r0,#0

mcr        p15,0, r0, c7, c7, 0        /* flush v3/v4cache */

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

/*

 * before relocating, we have to setup RAMtiming

 * because memory timing is board-dependend,you will

 * find a lowlevel_init.S in your boarddirectory.

 */

mov        ip,lr

bl        lowlevel_init

mov        lr,ip

mov        pc,lr

#endif /*CONFIG_SKIP_LOWLEVEL_INIT */

5、lowlevel_init

初始化sdram

 

.globl lowlevel_init

lowlevel_init:

/* memory controlconfiguration */

/* make r0 relative thecurrent location so that it */

/* reads SMRDATA out ofFLASH rather than memory ! */

ldr     r0, =SMRDATA

ldr        r1,_TEXT_BASE

sub        r0,r0, r1

ldr        r1,=BWSCON        /* Bus Width StatusController */

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

 

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 0xb1

    .word 0x30

    .word 0x30

这时候的代码、数据都只保存在flash上,内存中还没有,所以读取数据时要变换地址。

6、设置栈

/* Set up the stack                                                    */

stack_setup:

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

sub        r0,r0, #CFG_MALLOC_LEN        /* mallocarea                      */

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    */最后留出12个字节给abort异常,剩下就是栈,sp指向没有使用的内存即可。栈向下生长

SDRAM划分如下

7、设置时钟

由于

sub        sp,r0,#12                /*leave 3 words for abort-stack    */

中已经将SP指针设置好。故可以调用C函数,所以clock_init是C代码实现。

#ifndefCONFIG_SKIP_LOWLEVEL_INIT

    bl clock_init

#endif   

void clock_init(void)

{

S3C24X0_CLOCK_POWER*clk_power = (S3C24X0_CLOCK_POWER *)0x4C000000;

 

    /* support both of S3C2410 and S3C2440 */

    if (isS3C2410)

    {

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

        clk_power->CLKDIVN = S3C2410_CLKDIV;

 

        /* change to asynchronous bus mod */

        __asm__(    "mrc   p15, 0, r1, c1, c0, 0\n"   /* read ctrl register   */ 

                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */ 

                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */ 

                    :::"r1"

                    );

 

        /* to reduce PLL lock time, adjust theLOCKTIME register */

        clk_power->LOCKTIME = 0xFFFFFFFF;

 

        /* configure UPLL */

        clk_power->UPLLCON =S3C2410_UPLL_48MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (4000);

 

        /* configure MPLL */

        clk_power->MPLLCON =S3C2410_MPLL_200MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (8000);

    }

    else

    {

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

        clk_power->CLKDIVN = S3C2440_CLKDIV;

 

        /* change to asynchronous bus mod */

        __asm__(    "mrc   p15, 0, r1, c1, c0, 0\n"   /* read ctrl register   */ 

                    "orr    r1, r1, #0xc0000000\n"      /* Asynchronous         */ 

                    "mcr    p15, 0, r1, c1, c0, 0\n"    /* write ctrl register  */ 

                    :::"r1"

                    );

 

        /* to reduce PLL lock time, adjust theLOCKTIME register */

        clk_power->LOCKTIME = 0xFFFFFFFF;

 

        /* configure UPLL */

        clk_power->UPLLCON =S3C2440_UPLL_48MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (4000);

 

        /* configure MPLL */

        clk_power->MPLLCON =S3C2440_MPLL_400MHZ;

 

        /* some delay between MPLL and UPLL */

        delay (8000);

    }

}

8、重定位(代码从flash拷贝到SDRAM)

#ifndefCONFIG_SKIP_RELOCATE_UBOOT

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

beq     clear_bss

 

ldr        r2,_armboot_start

ldr        r3,_bss_start

sub        r2,r3,r2                /*r2 <- size of armboot            */

#if 1

bl  CopyCode2Ram        /*r0: source, r1: dest, r2: size */

#else

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

#endif

#endif        /*CONFIG_SKIP_RELOCATE_UBOOT */

9、清BSS段

lear_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

 

10、调用start_armboot(C函数)——第二阶段代码lib_arm/board.c

         ldr        pc,_start_armboot

 

 _start_armboot:        .wordstart_armboot

 

 


原创粉丝点击