U-boot启动第一阶段源码分析

    xiaoxiao2021-04-15  28

    原文转:http://blog.csdn.net/shiyi_2012/article/category/1107472

    #include 

    #include 

     

     

    .globl _start                  //定义全局变量

    _start: b       reset  ;     //跳转到reset标号处,现在到那个地方look

    //中断时候使用,产生中断时,跳到指定位置

    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  //实现16位字节对齐,不对其用0xdeadbeef 补齐

     

     

     

     

    _TEXT_BASE:

    .word TEXT_BASE

     

    .globl _armboot_start

    _armboot_start:

    .word _start

     

     

    .globl _bss_start

    _bss_start:

    .word __bss_start

     

    .globl _bss_end

    _bss_end:

    .word _end

     

    #ifdef CONFIG_USE_IRQ

     

    .globl IRQ_STACK_START

    IRQ_STACK_START:

    .word 0x0badc0de

     

     

    .globl FIQ_STACK_START

    FIQ_STACK_START:

    .word 0x0badc0de

    #endif

     

      // 使得CPU进入管理模式,也就是cprs=****10011

    reset:

    mrs r0,cpsr        ;

    bic r0,r0,#0x1f    ;

    orr r0,r0,#0xd3    ;

    msr cpsr,r0       ;

     

    //没用到的信息,跳过,是针对S3C2400

    #if defined(CONFIG_S3C2400)          

    # define pWTCON 0x15300000

    # define INTMSK 0x14400008

    # define CLKDIVN 0x14800014

    #elif defined(CONFIG_S3C2410)

    # define pWTCON 0x53000000

    # define INTMSK 0x4A000008

    # define INTSUBMSK 0x4A00001C

    # define CLKDIVN 0x4C000014

    #endif

     

    //关闭看门狗,等同于C语言的pWTCON =0x0

    #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)

    ldr     r0, =pWTCON  ; 

     mov     r1, #0x0     ; 

    str     r1, [r0]     ; //pWTCON=0x0

     

    //屏蔽所有中断,包括主中断屏蔽寄存器INTMSK,副中断屏蔽寄存器INTSUBMSK

    mov r1, #0xffffffff

    ldr r0, =INTMSK

    str r1, [r0]    ;// INTMSK=0xffffffff  主中断屏蔽寄存器共32位,置1表示屏蔽改为对应的中断

    # if defined(CONFIG_S3C2410)

    ldr r1, =0x3ff

    ldr r0, =INTSUBMSK

    str r1, [r0]   ;//INTSUBMSK=0x3ff  副中断有效位10,置1表示屏蔽改为对应的中断

    # endif

     

    //设置CPU与总线时钟的速度,一共有三个时钟源:FCLK,HCLK,PCLK,三者关系有CLKDIVN[1-0]位决定

     

    ldr r0, =CLKDIVN

    mov r1, #3

    str r1, [r0]  ;   //CLKDIVN=x03------->>HCLK=FCLK/2  PCLK=HCLK/2

    #endif     

     

    //主要对临界关键寄存器初始化,在重启时候才用到,如果从RAM中启动 则不执行

    #ifndef CONFIG_SKIP_LOWLEVEL_INIT

    bl cpu_init_crit   //调转到cpu_init_crit标号处

    #endif

    //重定向代码,实现的功能就是吧uboot代码搬到地址为 _TEXT_BASE地方

    //也就是复制Uboot的整个代码都复制到SDRAM

     

    #ifndef CONFIG_SKIP_RELOCATE_UBOOT

    relocate:

    adr r0, _start      //r0存放_start标号地址,也就是最上面的全局变量,程序开始的地方,表示当前运行代码起始地址,flash

    ldr r1, _TEXT_BASE   //将_TEXT_BASE 标号地址放到r1,0x33f80000

    cmp     r0, r1        // 判断r0和r1的值来看是否运行的代码是从flash开始的(0x00)   

    beq     stack_setup   //是从flash开始的,0x0

     

    ldr r2, _armboot_start  //r2=0x33f80000

    ldr r3, _bss_start       //r3=bss段起始地址

    sub r2, r3, r2    

    add r2, r0, r2    

     

    //把0x0(r0)的代码全部复制到0x33f80000(r2)

    copy_loop:

    ldmia r0!, {r3-r10}

    stmia r1!, {r3-r10} 

    cmp r0, r2

    ble copy_loop

    #endif

    add r0, r0, #4

    cmp r0, r1

    ble clbss_l

     

    #if 0

    //if0----endif为注销操作,可跳过

    if 0

    ldr     r0, =pWTCON

    mov     r1, #0x0

    str     r1, [r0]

     

    mov r1, #0xffffffff

    ldr r0, =INTMR

    str r1, [r0]

     

     

     

    ldr r0, =CLKDIVN

    mov r1, #3

    str r1, [r0]

     

    #endif

     

    //设置好堆栈,可以跳到Uboot启动第二阶段,即C语言那边去啦。

    ldr pc, _start_armboot

     

    _start_armboot: .word start_armboot

     

     

     

     

     

    #ifndef CONFIG_SKIP_LOWLEVEL_INIT

    cpu_init_crit:

     

    mov r0, #0

    mcr p15, 0, r0, c7, c7, 0

    mcr p15, 0, r0, c8, c7, 0

     

     

    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

     

     

    mov ip, lr ;  //下调命令要跳转,保护现场

    bl lowlevel_init    //13个控制器寄存器赋值,使得RAM空间可用,也是为uboot的第二阶段准备RAM空间,代码位于board/smdk2410/lowlevel.c

    mov lr, ip

    mov pc, lr  //返回

    #endif 

    uboot的作用:

    1.设置CPU的工作模式为管理模式

    2.关闭看门狗

    3.屏蔽中断

    4.设置CPU和总线的时钟FCLK相对于ARN929T而言,HCLK相对于AHB总线(ARM920T,内存控制器,中断控制器,LCD控制器,DMA和USB主模块使用),而PCLK相对于APB总线(外设:IIC\RTC\SPI\UART\GPIO)。

    5.为加载uboot第二阶段准备ram空间

    6.赋值uboot所有代码到RAM中

    转载请注明原文地址: https://ju.6miu.com/read-671916.html

    最新回复(0)