U-Boot源代码阅读笔记(一) —— 对start.S的分析<br /><br /> 本文主要分析与U-Boot启动过程相关的汇编代码cpu/pxa/start.S,目标平台以PXA270为例。 系统启动执行的第一条指令 /* armboot - Startup Code for XScale */<br />.globl _start<br />_start: b reset /*跳转到reset标号执行*/设置cpu为superviser模式 reset:<br /> mrs r0,cpsr /* 读cpsr寄存器状态 */<br /> bic r0,r0,#0x1f /* 位清除,清除0x1f对应的位 */<br /> orr r0,r0,#0x13 /* 设置M=10011,superviser 模式 */<br /> msr cpsr,r0 /* 写cpsr寄存器 */<br /><br /> bl cpu_init_crit /* 跳转到cpu_init_crit执行系统的关键初始化 */<br />cpu_init_crit:<br /> /* mask all IRQs */<br /> ldr r0, IC_BASE /* r0 <- Interrupt-Controller base address */<br /> mov r1, #0x00<br /> str r1, [r0, #ICMR_OFFSET] /* ICMR寄存器清零,屏蔽所有的中断 */<br /><br /> /*<br /> * before relocating, we have to setup RAM timing<br /> * because memory timing is board-dependend, you will<br /> * find a lowlevel_init.S in your board directory.<br /> */<br /> bl lowlevel_init /* 跳转到lowlevel_init执行SDRAM相关的初始化,参见对lowlevel_init.S的分析 */<br /><br />#if defined(CFG_CPUSPEED)<br />/*<br />* 系统频率的计算方法如下:<br />* Turbo-mode frequency (T) = 13-MHz processor-oscillator frequency * L * N<br />* Run-mode frequency (R) = 13-MHz processor-oscillator frequency * L<br />* System-bus frequency = 13-MHz processor-oscillator frequency * L / B,<br />* where B = 1 (when in fast-bus mode) or B = 2 (when not in fast-bus mode)<br />* For CCCR[A] = 0 :<br />* Memory-controller frequency = 13-MHz processor-oscillator frequency * L / M,<br />* where M = 1 (L = 2-10), M = 2 (L = 11-20), or M = 4 (L = 21-31)<br />* LCD frequency = 13-MHz processor-oscillator frequency * L / K,<br />* where K = 1 (L = 2-7), K = 2 (L = 8-16), or K = 4 (L = 17-31)<br />* For CLKCFG[ B] = 0 and CCCR[A] = 1 :<br />* Memory-controller frequency = 13-MHz processor-oscillator frequency * L / 2<br />* LCD frequency = 13-MHz processor-oscillator frequency * L / K,<br />* where K = 1 (L = 2-7), K = 2 (L = 8-16), or K = 4 (L = 17-31)<br />* For CLKCFG[ B] = 1 and CCCR[A] = 1 :<br />* Memory-controller frequency = 13-MHz processor-oscillator frequency * L<br />* LCD frequency = 13-MHz processor-oscillator frequency * L / K,<br />* where K = 1 (L = 2-7), K = 2 (L = 8-16), or K = 4 (L = 17-31)<br />*/<br /> /* set clock speed */<br /> ldr r0, =CC_BASE<br /> ldr r1, cpuspeed<br /> str r1, [r0, #CCCR_OFFSET] /* Core Clock Configuration Register */<br /> ldr r1, [r0, #CCCR_OFFSET] /* read back to make sure write action completed */<br /><br /> mov ip, lr /* 临时寄存器 <- 链接寄存器*/<br /> bl xlli_freq_change /* 跳到标号xlli_freq_change执行 */<br /> mov lr, ip<br /><br />/* Before enabling fast bus mode, must make sure Memory Controller is configured properly */<br />#if defined(CONFIG_SYSBUS_208)<br /> mov r0, #0x0B /* Fast bus | Freq. Change | Turbo mode */<br />#else<br /> mov r0, #0x03 /* ~Fast bus | Freq. Change | Turbo mode */<br />#endif<br /> mcr p14, 0, r0, c6, c0, 0 /* Write CCLKCFG */<br /><br />#if defined(CONFIG_MEMC_BS) /* memory controller buffer strength control */<br /> ldr r0, =MEMC_BASE<br /><br /> ldr r1, =CFG_BSCNTR0_VAL<br /> str r1, [r0, #BSCNTR0_OFFSET]<br /> ldr r1, =CFG_BSCNTR1_VAL<br /> str r1, [r0, #BSCNTR1_OFFSET]<br /> ldr r1, =CFG_BSCNTR2_VAL<br /> str r1, [r0, #BSCNTR2_OFFSET]<br /> ldr r1, =CFG_BSCNTR3_VAL<br /> str r1, [r0, #BSCNTR3_OFFSET]<br /><br /> ldr r1, [r0, #BSCNTR3_OFFSET] /* Make sure value is written */<br />#endif<br /><br />setspeed_done:<br />#endif<br /><br />.global normal_boot<br />normal_boot:<br /><br /> /* Memory interfaces are working. Disable MMU and enable I-cache. */<br /><br /> ldr r0, =0x2001 /* enable access to all coproc. */<br /> mcr p15, 0, r0, c15, c1, 0 /* enable access to CP13 CP0*/<br /> CPWAIT /* wait for effect */<br /><br /> mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */<br /> CPWAIT<br /><br /> mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */<br /> CPWAIT<br /><br /> mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */<br /> CPWAIT<br /><br /> /* Enable the Icache */<br /><br /> mrc p15, 0, r0, c1, c0, 0<br /> orr r0, r0, #0x1800 /* Instruction Cache Enable, Branch Target Buffer Enable */<br /> mcr p15, 0, r0, c1, c0, 0<br /> CPWAIT<br /><br />@ mov pc, lr<br /> b cpu_init_done /* call return back */<br /><br />/* Frequency Change Sequence from BLOB */<br />xlli_freq_change:<br /> mrc p14, 0, r0, c6, c0, 0 /* Get present status (preserve Turbo and Fast Bus bits) */<br /> orr r0, r0, #2 /* Set the F bit, Frequency Change, A change sequence is initiated when F is set. */<br /> mcr p14, 0, r0, c6, c0, 0 /* initiate the frequency change sequence */<br />/*<br />* If the clock frequency is chaged, the MDREFR Register must be rewritten, even<br />* if it's the same value. This will result in a refresh being performed and the<br />* refresh counter being reset to the reset interval. (Section 13.10.3, pg 13-17 of EAS)<br />*/<br /> ldr r4, =MEMC_BASE /* Get memory controller base address */<br /> ldr r1, [r4, #MDREFR_OFFSET] /* Get the current state of MDREFR */<br /> str r1, [r4, #MDREFR_OFFSET] /* Re-write this value */<br /><br /> mov pc, lr /* return to calling routine */<br /><br /><br /> /* RS: ??? */<br /> .macro CPWAIT /* Canonical method to wait for CP15 update */<br /> mrc p15,0,r0,c2,c0,0 /* arbitrary read of CP15 */<br /> mov r0,r0 /* nop, wait for it */<br /> sub pc,pc,#4 /* branch to next instruction */<br /> /* At this point, any previous CP15 writes are guaranteed to have taken effect. */<br /> .endm<br />系统初始化完成 cpu_init_done:<br /><br />#ifndef CONFIG_SKIP_RELOCATE_UBOOT<br />relocate: /* relocate U-Boot to RAM */<br /> adr r0, _start /* r0 <- current position of code */<br /> ldr r1, _TEXT_BASE /* test if we run from flash or RAM */<br /> cmp r0, r1 /* don't reloc during debug */<br /> beq stack_setup<br /><br /> ldr r2, _armboot_start<br /> ldr r3, _bss_start<br /> sub r2, r3, r2 /* r2 <- size of armboot */<br /> add r2, r0, r2 /* r2 <- source end address */<br /><br />copy_loop:<br /> ldmia r0!, {r3-r10} /* copy from source address [r0] */<br /> stmia r1!, {r3-r10} /* copy to target address [r1] */<br /> cmp r0, r2 /* until source end addreee [r2] */<br /> ble copy_loop<br />#endif /* CONFIG_SKIP_RELOCATE_UBOOT */<br /><br /> /* Set up the stack */<br />stack_setup:<br /> ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */<br /> sub r0, r0, #CFG_MALLOC_LEN /* malloc area */<br /> sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */<br />#ifdef CONFIG_USE_IRQ<br /> sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)<br />#endif<br /> sub sp, r0, #12 /* leave 3 words for abort-stack , sp —— 栈指针寄存器 */<br /><br />clear_bss:<br /> ldr r0, _bss_start /* find start of bss segment */<br /> ldr r1, _bss_end /* stop here */<br /> mov r2, #0x00000000 /* clear */<br /><br />clbss_l:str r2, [r0] /* clear loop... */<br /> add r0, r0, #4<br /> cmp r0, r1<br /> ble clbss_l<br />跳转到start_armboot执行<br /> ldr pc, _start_armboot /* 跳转到start_armboot执行, 参见对lib_arm/board.c的分析 */<br /><br />_start_armboot: .word start_armboot<br /><br /> <br /> <br /> |
|