s5pv210-uboot分析(二)

   本文继续上一篇博客分析    

    ldr        r0, =INF_REG_BASE             
    ldr        r1, [r0, #INF_REG3_OFFSET]
    cmp        r1, #BOOT_NAND        /* 0x0 => boot device is nand */    //读取启动信息寄存器并判断是否是从nand启动
    beq        nand_boot
    cmp        r1, #BOOT_ONENAND    /* 0x1 => boot device is onenand */
    beq        onenand_boot
    cmp        r1, #BOOT_MMCSD
    beq        mmcsd_boot
    cmp        r1, #BOOT_NOR
    beq        nor_boot
    cmp        r1, #BOOT_SEC_DEV
    beq        mmcsd_boot

执行nand_boot启动接口,本文只分析nand_boot启动方式

nand_boot:

    mov        r0, #0x1000       // 对r0寄存器赋值,值为 4kB
    bl        copy_from_nand
    b        after_copy

执行拷贝函数 copy_from_nand

/*
 * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)
 * r0: size to be compared
 * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size
 */
    .globl copy_from_nand
copy_from_nand:
    push    {lr}        /* save return address */

    mov    r9, r0
    
    mov    r9, #0x100        /* Compare about 8KB */     //比较512字节
    bl    copy_uboot_to_ram                                          //从nandflash中拷贝uboot代码到SDRAM中
    tst     r0, #0x0                                                             //判断是否拷贝完成 返回值是否为0 ro为返回值
    bne    copy_failed

#if defined(CONFIG_EVT1)
    ldr    r0, =0xd0020000                                          //SRAM的物理地址
#else    
    ldr    r0, =0xd0030000
#endif
    ldr    r1, _TEXT_PHY_BASE    /* 0x23e00000 */        //SDRAM的物理地址,即拷贝之后uboot的物理地址

#if !defined(CONFIG_SECURE_BOOT)
1:    ldr    r3, [r0], #4                                             //拷贝r0中的值到r3, r0+4
    ldr    r4, [r1], #4                                                 //拷贝r1中的值到r4, r0+4
    teq    r3, r4                                                          //比较r3 r4是否相等
    bne    compare_failed    /* not matched */
    subs    r9, r9, #4                                                   r9 = r9-4
    bne    1b
#endif

本处实现的功能为拷贝uboot到内存中,并比较SDRAM内存中的前4kb中的内容与SRAM中的前4kb数据是否一致,即判断是否拷贝成功   

 pop    {pc}        /* all is OK */

after_copy:   //代码重定位完成

#if defined(CONFIG_ENABLE_MMU)
enable_mmu:
    /* enable domain access */
    ldr    r5, =0x0000ffff
    mcr    p15, 0, r5, c3, c0, 0        @load domain access register

    /* Set the TTB register */
    ldr    r0, _mmu_table_base                               //映射表基地址,在lowlevel.s中以定义好
    ldr    r1, =CFG_PHY_UBOOT_BASE            //uboot物理基地址

   //二者加起来就找到了mmu映射表基地址
    ldr    r2, =0xfff00000
    bic    r0, r0, r2
    orr    r1, r0, r1
    mcr    p15, 0, r1, c2, c0, 0

    /* Enable the MMU */
mmu_on:
    mrc    p15, 0, r0, c1, c0, 0
    orr    r0, r0, #1
    mcr    p15, 0, r0, c1, c0, 0
    nop
    nop
    nop
    nop
#endif
开启MMU,并确定了mmu映射表基地址,

skip_hw_init:
    /* Set up the stack                            */
stack_setup://第三次设置栈
#if defined(CONFIG_MEMORY_UPPER_CODE) //定义了该宏
    ldr    sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0x1000)

CFG_UBOOT_BASE = 0xc3e00000 此处为虚拟地址,因为MMU已开启 CFG_UBOOT_SIZE  = (3*1024*1024)
#else
    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                        */
#if defined(CONFIG_USE_IRQ)
    sub    r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
    sub    sp, r0, #12        /* leave 3 words for abort-stack    */

#endif

clear_bss:
    ldr    r0, _bss_start        /* find start of bss segment        */  //清楚BSS段
    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                //执行start_armboot,

第一阶段完毕,执行第二阶段代码

猜你喜欢

转载自blog.csdn.net/coolperl/article/details/82555707