uboot 源码分析一

来源:互联网 发布:淘宝内部优惠券淘易惠 编辑:程序博客网 时间:2024/06/13 03:46

这一篇主要是了解uboot。

在分析uboot的Makefile的时候我们知道他的入口地址在cpu/arm920/start.s

打开文件cpu/arm920/start.s:
 (1)硬件设备初始化。

  依次完成各步奏的执行顺序:

   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.关看门狗。

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
ldr     r0, =pWTCON
mov     r1, #0x0
str     r1, [r0]

   3.屏蔽中断。

/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
#if 0
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif
#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
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
#endif

其中在跟踪cpu_init_crit 我们会定位到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 */

   4.初始化SDRAM——>设置栈 sp ->内存(继续跟踪/100ask24x0/lowlevel_init board)。

start.S 调用lowlevel_init函数来初始化存储控制器:

.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, _TEXT_BASE
sub r0, r0, r1
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 0xb1
    .word 0x30
    .word 0x30

   5.设置栈。

/* Set up the stack   */
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                        */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12/* leave 3 words for abort-stack    */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl clock_init
#endif    
#ifndef CONFIG_SKIP_RELOCATE_UBOOT

   6.时钟。

clock_init:

void cloclock_initck_init(void)
{
S3C24X0_CLOCK_POWER *clk_power = (S3C24X0_CLOCK_POWER *)0x4C000000;
    /* support both of S3C2410 and S3C2440, by www.100ask.net */
    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 the LOCKTIME 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 the LOCKTIME 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);
    }
}

   7.代码 flash->SDRAM

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

CopyCode2Ram

int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size)
{
    unsigned int *pdwDest;
    unsigned int *pdwSrc;
    int i;
    if (bBootFrmNORFlash())
    {
        pdwDest = (unsigned int *)buf;
        pdwSrc  = (unsigned int *)start_addr;
        /* 从 NOR Flash启动 */
        for (i = 0; i < size / 4; i++)
        {
            pdwDest[i] = pdwSrc[i];
        }
        return 0;
    }
    else
    {
        /* 初始化NAND Flash */
nand_init_ll();
        /* 从 NAND Flash启动 */
        nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));
return 0;
    }
}

   8.清bass段。

clear_bss:
ldr r0, _bss_start/* find start of bss segment        */
ldr r1, _bss_end/* stop here                        */
mov r2, #0x00000000/* clear        

   9.调用start-boot 第二阶段(c函数)。

_start_armboot:

   .....等等等等,基本上步奏都差不多这样。

(2)为加载BootLoader的第二阶段代码准备内存空间。

看看它的内存分配。

  

0 0
原创粉丝点击