uboot移植之启动过程--汇编过程start.s

来源:互联网 发布:剑灵淘宝金币怎么买 编辑:程序博客网 时间:2024/05/22 00:51

uboot移植之启动过程--汇编过程start.s

说明:本文基于uboot-1.16,代码来源其中,代码版权归原作者所有。

代码版权:Copyright (C) 2001 - 2011 by Wolfgang Denk, DENX Software Engineering.

                 Copyright (C) 2003 - 2011 by Detlev Zundel, DENX Software Engineering.

                 Copyright (C) 2003 - 2011 by contributing authors

出处:http://blog.csdn.net/hail100

                 uboot启动大致分2步: 第一步主要是完成关wacthdog、mmu,系统时钟的初始化,mem初始化,最后是uboot代码复制到RAM中,跳到c语言函数,这阶段主要用汇编在start.S,lowlevel_init.S中完成。第二步完成复杂设备的初始化,开启命令行,其主要由c语言完成。本文介绍smdk2410的start.S。

正文:

               smdk2410使用arm920T的内核,可以到arm官网上下载用户手册。http://infocenter.arm.com/help/index.jsp 。本文将结合用户手册和uboot代码介绍uboot启动第一阶段。主要代码在uboot-1.1.6/cpu/arm920t/start.S,注意是(.S)这文件在编译时要先经过预处理、有头文件的包含、宏定义的替代,(.s)不会预处理。

  /*
 *************************************************************************
 *
 * Jump vector table as in table 3.1 in [1]

 *   arm 都是通过跳转向量完成启动、中断
 *
 *************************************************************************
 */
.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

    .balignl 16,0xdeadbeef            ====================================================================================================================================

/*

 * the actual reset code
 */
@ 重启从这开始
reset:                                
    /*
     * set the cpu to SVC32 mode

     */

@ uboot需要在管理模式中执行,msr和mrs 都是伪指令

@ 并禁止fiq 和irq

    mrs     r0, cpsr
    bic      r0, r0, #0x1f
    orr      r0, r0, #0xd3
    msr    cpsr, r0
@ 关watchdog
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
    ldr        r0, =pWTCON
    mov     r1, #0x0
    str        r1, [r0]
@ 关中断
    /*
     * mask all IRQs by setting all bits in the INTMR - default
     */
    mov    r1,  #0xffffffff
    ldr       r0,  =INTMSK
    str       r1,  [r0]
# if defined(CONFIG_S3C2410)
    ldr      r1,  =0x3ff
    ldr      r0,  =INTSUBMSK
    str       r1,  [r0]
# endif

@ 设置时钟,设置其分频

@ 时钟的配置是很重要的,将对以后的其他配置产生影响

@ 因此要为后面的配置考虑好时序,尽量做到容易修改,用宏定义

@ 看好各个时钟所控制的设备,知道其频率

    /* FCLK:HCLK:PCLK = 1:2:4 */
    /* default FCLK is 120 MHz ! */
    ldr       r0,  =CLKDIVN
    mov    r1,  #3
    str       r1,  [r0]
#endif    /* CONFIG_S3C2400 || CONFIG_S3C2410 */
@ cpu初始化, 后面分析
    /*
     * we do sys-critical inits only at reboot,
     * not when booting from ram!
     */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
    bl      cpu_init_crit
#endif
@ 判断uboot是不是在RAM中启动
#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

@ 可以在前面找到_armboot_start,_bss_start的定义

@ __bss_start 在u-boot.lds 里

@ 这是从nor flash启动时, 完成uboot到ram的复制

@nand flash 的复制要复杂的多,需要控制nand分块复制

    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    */
@ 清零bss区
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
@ 从这开始跳到c语言入口
    ldr    pc, _start_armboot

_start_armboot:    .word start_armboot

====================================================================================================================================

cache和mmu的操作都是在协处理器中完成的,协处理器 p15的操作可以看arm920t用户手册。

cpu_init_crit:

@ 刷新cache
    /*
     * flush v4 I/D caches
     */
    mov    r0, #0
    mcr    p15, 0, r0, c7, c7, 0    /* flush v3/v4 cache */
    mcr    p15, 0, r0, c8, c7, 0    /* flush v4 TLB */
@ 禁止MMU 和 caches,这是cp15中的c1寄存器控制的
    /*
     * disable MMU stuff and caches
     */
    mrc    p15, 0, r0, c1, c0, 0
    bic     r0, r0, #0x00002300    @ clear bits 13, 9:8 (--V- --RS)
    bic     r0, r0, #0x00000087    @ clear bits 7, 2:0 (B--- -CAM)
    orr     r0, r0, #0x00000002    @ set bit 2 (A) Align
    orr     r0, r0, #0x00001000    @ set bit 12 (I) I-Cache
    mcr    p15, 0, r0, c1, c0, 0

    /*
     * 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.
     */
    mov    ip, lr

@ 跳到 lowlevel_init.S中,完成RAM时序配置

    bl    lowlevel_init
    mov    lr, ip
    mov    pc, lr

====================================================================================================================================

在u-boot-1.1.6/board/smdk2410/lowlevel_init.S中完成RAM时序的配置,这需要看系统频率和所用RAM工作时序,来配置smdk2410的RAM控制器。

_TEXT_BASE:
    .word    TEXT_BASE

.globl lowlevel_init
lowlevel_init:

@对于sdram的控制,主要是设置其控制器。其中有时序的配置,

@需要看ram的手册查询,要配置好系统时钟,计算出是多个ram控制器时钟

@还有就是看soc手册讲解的控制器配置流程

    /* memory control configuration */
    /* make r0 relative the current location so that it */
    /* reads SMRDATA out of FLASH rather than memory ! */
    ldr     r0, =SMRDATA
    ldr    r1, _TEXT_BASE
    sub    r0, r0, r1
    ldr    r1, =BWSCON    /* Bus Width Status Controller */
    add     r2, r0, #13*4
0:
    ldr     r3, [r0], #4
    str     r3, [r1], #4
    cmp     r2, r0
    bne     0b

    /* everything is fine now */
    mov    pc, lr

    .ltorg
/* the literal pools origin */

SMRDATA:
    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0x32
    .word 0x30
    .word 0x30

====================================================================================================================================

start.S最后中断的入口,中断的宏完成现场保存,跳到中断处理函数。do_xxx 都在 interrupt.c中处理。