本文继续上一篇博客分析
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,
第一阶段完毕,执行第二阶段代码