Boot来DIY自己的arm11(6410)的bootloader(4)

#ifdef CONFIG_BOOT_MOVINAND
 ldr sp, _TEXT_PHY_BASE
 bl movi_bl2_copy
 b after_copy
#endif
//使用nandflash,此处忽略
#ifdef CONFIG_BOOT_ONENAND
 ldr sp, =0x50000000  @ temporary stack
//设置地址并分配空间
#ifdef CONFIG_S3C6400
 mov r1, =0x20000000  @ start buffer register
 orr r1, r1, #0xc30000
 orr r1, r1, #0xc800
#else
 mov r1, #0x23000000  @ start buffer register
 orr r1, r1, #0x30000
 orr r1, r1, #0xc800
#endif

ldr r2, [r1, #0x84]  @ ecc bypass
 orr r2, r2, #0x100
 str r2, [r1, #0x84]

sub r0, r1, #0x0400  @ start address1 register

str r3, [r0, #0x00]
 str r3, [r0, #0x04]  @ select dataram for DDP as 0

mov r4, #0x104  @ interrupt register

mov r6, #0x0c00  @ fixed dataram1 sector number
 str r6, [r1, #0x00]

mov r3, #0x0  @ DFS, FBA
 mov r5, #0x0000  @ FPA, FSA
 ldr r9, =CFG_PHY_UBOOT_BASE @ destination

onenand_bl2_load:
 str r3, [r0, #0x00]  @ save DFS, FBA
 str r5, [r0, #0x1c]  @ save FPA, FSA

mov r7, #0x0  @ clear interrupt
 str r7, [r1, r4]
 str r7, [r1, #0x80]  @ write load command

mov r8, #0x1000
onenand_wait_loop2:
 subs r8, r8, #0x1
 bne onenand_wait_loop2

onenand_wait_int:  @ wait INT and RI
 ldr r7, [r1, r4]
 mov r8, #0x8000
 orr r8, r8, #0x80
 tst r7, r8
 beq onenand_wait_int

mov r7, #0x0  @ clear interrupt
 str r7, [r1, r4]

mov r8, #0xc00  @ source address (dataram1)
 mov r10, #0x40  @ copy loop count (64 = 2048 / 32)

stmia sp, {r0-r7}  @ backup
//把代码拷贝至DRAM
onenand_copy_to_ram:
 ldmia r8!, {r0-r7}
 stmia r9!, {r0-r7}
 subs r10, r10, #0x1
 bne onenand_copy_to_ram

ldmia sp, {r0-r7}  @ restore

add r5, r5, #0x4  @ next FPA
 cmp r5, #0x100  @ last FPA?
 bne onenand_bl2_load

/* next block */
 mov r5, #0x0  @ reset FPA
 add r3, r3, #0x1  @ next FBA
 cmp r3, #0x2  @ last FBA?
 bne onenand_bl2_load
 b after_copy
#endif

#ifdef CONFIG_BOOT_ONENAND_IROM
 ldr sp, _TEXT_PHY_BASE
 bl onenand_bl2_copy
 b after_copy
#endif
//进入DRAM执行
after_copy:
#ifdef CONFIG_ENABLE_MMU
开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
 ldr r1, =CFG_PHY_UBOOT_BASE
 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  /* Set CR_M to enable MMU */
 mcr p15, 0, r0, c1, c0, 0
 nop
 nop
 nop
 nop
#endif

skip_hw_init:
 /* Set up the stack          */
stack_setup:
//分配堆栈
#ifdef CONFIG_MEMORY_UPPER_CODE
 ldr sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc)
#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                        */
#ifdef CONFIG_USE_IRQ
 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
 sub sp, r0, #12  /* leave 3 words for abort-stack    */

#endif
//将未初始化数据段_bss_start----_bss_end中的数据清零
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

#ifdef CONFIG_ENABLE_MMU
_mmu_table_base:
 .word mmu_table
#endif

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/2c4b5a376011f5a91a566a097dc0a659.html