U-Boot源代码阅读笔记(一) —— 对start.S的分析

U-Boot源代码阅读笔记(一) —— 对start.S的分析
本文主要分析与U-Boot启动过程相关的汇编代码cpu/pxa/start.S,目标平台以PXA270为例。
  • 系统启动执行的第一条指令
/* armboot - Startup Code for XScale */
.globl _start
_start: b    reset    /*跳转到reset标号执行*/
  • 设置cpu为superviser模式
reset:
    mrs    r0,cpsr            /* 读cpsr寄存器状态 */
    bic    r0,r0,#0x1f       /* 位清除,清除0x1f对应的位 */
    orr    r0,r0,#0x13      /* 设置M=10011,superviser 模式 */
    msr    cpsr,r0           /* 写cpsr寄存器 */

    bl    cpu_init_crit        /* 跳转到cpu_init_crit执行系统的关键初始化 */
  • 系统关键初始化
cpu_init_crit:
    /* mask all IRQs  */
    ldr    r0, IC_BASE    /* r0 <- Interrupt-Controller base address */
    mov    r1, #0x00
    str    r1, [r0, #ICMR_OFFSET]    /* ICMR寄存器清零,屏蔽所有的中断 */

    /*
     * before relocating, we have to setup RAM timing
     * because memory timing is board-dependend, you will
     * find a lowlevel_init.S in your board directory.
     */
    bl    lowlevel_init    /* 跳转到lowlevel_init执行SDRAM相关的初始化,参见对lowlevel_init.S的分析 */

#if defined(CFG_CPUSPEED)
/*
 * 系统频率的计算方法如下:
 * Turbo-mode frequency (T) = 13-MHz processor-oscillator frequency * L * N
 * Run-mode frequency (R) = 13-MHz processor-oscillator frequency * L
 * System-bus frequency = 13-MHz processor-oscillator frequency * L / B,
 * where B = 1 (when in fast-bus mode) or B = 2 (when not in fast-bus mode)
 * For CCCR[A] = 0 :
 * Memory-controller frequency = 13-MHz processor-oscillator frequency * L / M,
 * where M = 1 (L = 2-10), M = 2 (L = 11-20), or M = 4 (L = 21-31)
 * LCD frequency = 13-MHz processor-oscillator frequency * L / K,
 * where K = 1 (L = 2-7), K = 2 (L = 8-16), or K = 4 (L = 17-31)
 * For CLKCFG[B] = 0 and CCCR[A] = 1 :
 * Memory-controller frequency = 13-MHz processor-oscillator frequency * L / 2
 * LCD frequency = 13-MHz processor-oscillator frequency * L / K,
 * where K = 1 (L = 2-7), K = 2 (L = 8-16), or K = 4 (L = 17-31)
 * For CLKCFG[B] = 1 and CCCR[A] = 1 :
 * Memory-controller frequency = 13-MHz processor-oscillator frequency * L
 * LCD frequency = 13-MHz processor-oscillator frequency * L / K,
 * where K = 1 (L = 2-7), K = 2 (L = 8-16), or K = 4 (L = 17-31)
 */
    /* set clock speed */
    ldr    r0, =CC_BASE
    ldr    r1, cpuspeed
    str    r1, [r0, #CCCR_OFFSET]    /* Core Clock Configuration Register */
    ldr    r1, [r0, #CCCR_OFFSET]        /* read back to make sure write action completed */

    mov    ip, lr    /* 临时寄存器  <- 链接寄存器*/
    bl    xlli_freq_change    /* 跳到标号xlli_freq_change执行 */
    mov    lr, ip

/* Before enabling fast bus mode, must make sure Memory Controller is configured properly */
#if defined(CONFIG_SYSBUS_208)
    mov    r0, #0x0B        /*  Fast bus | Freq. Change | Turbo mode */
#else
    mov    r0, #0x03        /* ~Fast bus | Freq. Change | Turbo mode */
#endif
    mcr    p14, 0, r0, c6, c0, 0    /* Write CCLKCFG */

#if defined(CONFIG_MEMC_BS)    /* memory controller buffer strength control */
    ldr    r0, =MEMC_BASE

    ldr    r1, =CFG_BSCNTR0_VAL
    str     r1, [r0, #BSCNTR0_OFFSET]
    ldr    r1, =CFG_BSCNTR1_VAL
    str     r1, [r0, #BSCNTR1_OFFSET]
    ldr    r1, =CFG_BSCNTR2_VAL
    str     r1, [r0, #BSCNTR2_OFFSET]
    ldr    r1, =CFG_BSCNTR3_VAL
    str     r1, [r0, #BSCNTR3_OFFSET]

    ldr    r1, [r0, #BSCNTR3_OFFSET]    /* Make sure value is written */
#endif

setspeed_done:
#endif

.global normal_boot
normal_boot:

    /* Memory interfaces are working. Disable MMU and enable I-cache.   */

    ldr    r0, =0x2001        /* enable access to all coproc.        */
    mcr    p15, 0, r0, c15, c1, 0    /* enable access to CP13 CP0*/
    CPWAIT    /* wait for effect */

    mcr    p15, 0, r0, c7, c10, 4    /* drain the write & fill buffers   */
    CPWAIT

    mcr    p15, 0, r0, c7, c7, 0    /* flush Icache, Dcache and BTB        */
    CPWAIT

    mcr    p15, 0, r0, c8, c7, 0    /* flush instuction and data TLBs   */
    CPWAIT

    /* Enable the Icache                            */

    mrc    p15, 0, r0, c1, c0, 0
    orr    r0, r0, #0x1800    /* Instruction Cache Enable, Branch Target Buffer Enable */
    mcr    p15, 0, r0, c1, c0, 0
    CPWAIT

@    mov    pc, lr
    b    cpu_init_done        /* call return back */

/* Frequency Change Sequence from BLOB */
xlli_freq_change:
        mrc     p14, 0, r0, c6, c0, 0       /* Get present status (preserve Turbo and Fast Bus bits) */
        orr     r0,  r0,  #2                /* Set the F bit, Frequency Change, A change sequence is initiated when F is set. */
        mcr     p14, 0, r0, c6, c0, 0       /* initiate the frequency change sequence */
/*
 *      If the clock frequency is chaged, the MDREFR Register must be  rewritten, even
 *      if it's the same value. This will result in a refresh being performed and the
 *      refresh counter being reset to the reset interval. (Section 13.10.3, pg 13-17 of EAS)
 */
        ldr     r4,  =MEMC_BASE               /* Get memory controller base address */
        ldr     r1,  [r4, #MDREFR_OFFSET]      /* Get the current state of MDREFR */
        str     r1,  [r4, #MDREFR_OFFSET]      /* Re-write this value */

        mov     pc,  lr         /* return to calling routine */


    /* RS: ???                                */
    .macro CPWAIT    /* Canonical method to wait for CP15 update */
    mrc  p15,0,r0,c2,c0,0    /* arbitrary read of CP15 */
    mov  r0,r0        /* nop, wait for it */
    sub  pc,pc,#4    /* branch to next instruction */
    /* At this point, any previous CP15 writes are guaranteed to have taken effect. */
    .endm
  • 系统初始化完成
cpu_init_done:

#ifndef CONFIG_SKIP_RELOCATE_UBOOT
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:
    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
#endif    /* CONFIG_SKIP_RELOCATE_UBOOT */

    /* Set up the stack                            */
stack_setup:
    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 ,  sp —— 栈指针寄存器   */

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
  • 跳转到start_armboot执行
    ldr    pc, _start_armboot    /* 跳转到start_armboot执行, 参见对lib_arm/board.c的分析 */

_start_armboot: .word start_armboot

你可能感兴趣的:(c,汇编,buffer,Access,action,branch)