一、u-boot启动流程
第一步:
S5pc100中IROM中的代码 自动将NAND FLASH的前16KB拷贝到SRAM的0x34000 ,然后bootload的第一部分开始执行,初始化DRAM。
第二步:
bootload将nandflash中所有的bootload拷贝到DRAM中。
第三步:
跳转到DRAM中开始执行bootload的第二部分代码。
二、第一阶段启动流程
裁剪之后的start.S文件如下:
- .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: .word undefined_instruction
- _software_interrupt: .word software_interrupt
- _prefetch_abort: .word prefetch_abort
- _data_abort: .word data_abort
- _not_used: .word not_used
- _irq: .word irq
- _fiq: .word fiq
- _pad: .word 0x12345678 /* now 16*4=64 */
- .balignl 16,0xdeadbeef
- /**************************************设置异常向量表************************************/
- _TEXT_BASE:
- #TEXT_BASE 0x20f00000
- .word TEXT_BASE
- _ARMboot_start:
- #_start 0x20f00000
- .word _start
- /*
- * These are defined in the board-specific linker script.
- *链接脚本指定:
- *__bss_start bss段起始地址
- *__end bss段结束地址
- */
- _bss_start:
- .word __bss_start
- _bss_end:
- .word _end
- /*
- * the actual reset code
- */
- /******************************设置ARM核为SVC管理模式********************************/
- reset:
- /*
- * set the cpu to SVC32 mode
- * 切换ARM核到管理模式
- */
- mrs r0, cpsr
- bic r0, r0, #0x1f
- orr r0, r0, #0xd3
- msr cpsr,r0
- /*****************************设置ARM核为SVC管理模式*********************************/
- bl cpu_init_crit
- /*********************************搬移u-boot到DRAM************************************/
- #if NOR FLASH 启动
- 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 stack_setup
- ldr r2, _armboot_start
- ldr r3, _bss_start
- sub r2, r3, r2 @ r2 <- size of armboot
- add r2, r0, r2 @ r2 <- source end address
- copy_loop: @ copy 32 bytes at a time
- 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
- #else NAND FLASH 启动
- relocate: @ relocate U-Boot to RAM
- adr r0, _start @ r0 <- current position of code
- ldr r1, _TEXT_BASE @ test if we run from DRAM or SRAM
- cmp r0, r1 @ don't reloc during debug
- beq stack_setup
- ldr sp,_TEXT_BASE
- ldr r0,_TEXT_BASE
- mov r1,#0x0
- mov r2,#0x50000
- bl copy_uboot_to_dram
- #endif
- /**************************搬移u-boot到DRAM************************************/
- /**********************************设置栈空间****************************************/
- /* Set up the stack */
- stack_setup:
- ldr r0, _TEXT_BASE @ upper 128 KiB: relocated uboot
- sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area [1M + 128KB]
- sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo [128字节]
- sub sp, r0, #12 @ leave 3 words for abort-stack
- and sp, sp, #~7 @ 8 byte alinged for (ldr/str)d
- /*******************************设置栈空间********************************************/
- /**********************************清除BSS段*******************************************/
- /* Clear BSS (if any). Is below tx (watch load addr - need space) */
- clear_bss:
- ldr r0, _bss_start @ find start of bss segment
- ldr r1, _bss_end @ stop here
- mov r2, #0x00000000 @ clear value
- clbss_l:
- str r2, [r0] @ clear BSS location
- cmp r0, r1 @ are we at the end yet
- add r0, r0, #4 @ increment clear index pointer
- bne clbss_l @ keep clearing till at end
- /*********************************清除BSS段*******************************************/
- /***************************调到内存中执行第二阶段****************************************/
- //跳到内存中执行第二阶段代码
- ldr pc, _start_armboot @ jump to C code
- /************************调到内存中执行第二阶段*******************************************/
- _start_armboot: .word start_armboot
- cpu_init_crit:
- /*
- * Invalidate L1 I/D:使cache无效
- */
- mov r0, #0 @ set up for MCR
- mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
- mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
- /*
- * disable MMU stuff and caches:关MMU
- */
- mrc p15, 0, r0, c1, c0, 0
- bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
- bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
- orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
- orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB
- mcr p15, 0, r0, c1, c0, 0
- /*
- * Jump to board specific initialization...
- * The Mask ROM will have already initialized
- * basic memory. Go here to bump up clock rate and handle
- * wake up conditions.
- */
- mov ip, lr @ persevere link reg across call
- bl lowlevel_init @ go setup pll,mux,memory
- mov lr, ip @ restore link
- mov pc, lr @ back to my caller
- lowlevel_init:
- mov r9, lr
- /* r5 has always zero */
- mov r5, #0
- ldr r8, =S5PC100_GPIO_BASE
- /* Disable Watchdog :关开门狗 */
- ldr r0, =S5PC100_WATCHDOG_BASE @0xEA200000
- orr r0, r0, #0x0
- str r5, [r0]
- /* setting SRAM */
- ldr r0, =S5PC100_SROMC_BASE
- ldr r1, =0x9
- str r1, [r0]
- /* S5PC100 has 3 groups of interrupt sources */
- ldr r0, =S5PC100_VIC0_BASE @0xE4000000
- ldr r1, =S5PC100_VIC1_BASE @0xE4000000
- ldr r2, =S5PC100_VIC2_BASE @0xE4000000
- /* Disable all interrupts (VIC0, VIC1 and VIC2) : 禁用中断 */
- mvn r3, #0x0
- str r3, [r0, #0x14] @INTENCLEAR
- str r3, [r1, #0x14] @INTENCLEAR
- str r3, [r2, #0x14] @INTENCLEAR
- /* Set all interrupts as IRQ */
- str r5, [r0, #0xc] @INTSELECT
- str r5, [r1, #0xc] @INTSELECT
- str r5, [r2, #0xc] @INTSELECT
- /* Pending Interrupt Clear :清除基地址寄存器的值*/
- str r5, [r0, #0xf00] @INTADDRESS
- str r5, [r1, #0xf00] @INTADDRESS
- str r5, [r2, #0xf00] @INTADDRESS
- /* for UART */
- bl uart_asm_init
- /* for TZPC */
- bl tzpc_asm_init
- /* 系统时钟初始化 */
- bl system_clock_init
- /*内存控制器初始化*/
- bl mem_ctrl_asm_init
- 1:
- mov lr, r9
- mov pc, lr
总结:
<1>设置异常向量表
<2>设置ARM核为管理模式
<3>使cache无效,关闭MMU
<4>关闭看门狗
<5>设置向量中断控制器
[1]禁用所有的中断
[2]设置所有的中断都为IRQ异常
[3]清除向量地址寄存器
<6>初始化串口引脚
<7>系统时钟初始化
<8>初始化内存控制器
<9>将u_boot搬移到内存
<10>设置栈空间
<11>清除BSS段
<12>跳到内存中执行第二阶段代码[start_armboot]
|