zoukankan      html  css  js  c++  java
  • u-boot启动代码start.S详解360

    (1)定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。
    (2)设置异常向量(Exception Vector)。
    (3)设置CPU的速度、时钟频率及终端控制寄存器。
    (4)初始化内存控制器。
    (5)将ROM中的程序复制到RAM中。
    (6)初始化堆栈。
    (7)转到RAM中执行,该工作可使用指令ldr pc来完成。

    .globl _start                         //u-boot启动入口
    _start: b       reset               //复位向量并且跳转到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                     //中断向量
     b  sleep_setting             //跳转到sleep_setting
    系统上电或reset后,cpu的PC一般都指向0x0地址,在0x0地址上的指令是
    reset:                                 //复位启动子程序
    /******** 设置CPU为SVC32模式***********/
     mrs r0,cpsr                       //将CPSR状态寄存器读取,保存到R0中
     bic r0,r0,#0x1f
     orr r0,r0,#0xd3
     msr cpsr,r0                      //将R0写入状态寄存器中
    /************** 关闭看门狗 ******************/
     ldr      r0, =pWTCON
     mov     r1, #0x0
     str       r1, [r0]
    /************** 关闭所有中断 *****************/
     mov r1, #0xffffffff
     ldr r0, =INTMSK
     str r1, [r0]
     ldr r2, =0x7ff
     ldr r0, =INTSUBMSK
     str r2, [r0]
    /************** 初始化系统时钟 *****************/
     ldr r0, =LOCKTIME
     ldr     r1, =0xffffff 
     str     r1, [r0]
    clear_bss:
            ldr       r0, _bss_start           //找到bss的起始地址 
            add      r0, r0, #4              //从bss的第一个字开始 
            ldr       r1, _bss_end           // bss末尾地址 
            mov      r2, #0x00000000       //清零 
    clbss_l:str        r2, [r0]                // bss段空间地址清零循环 
            add     r0, r0, #4
            cmp     r0, r1
            bne      clbss_l
    /***************** 关键的初始化子程序 ************************/
    / * cpu初始化关键寄存器       设置重要寄存器          设置内存时钟  * /
    cpu_init_crit:           /** 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 */
    /************* 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
    /******* 在重新定位前,我们要设置RAM的时间,因为内存时钟依赖开发板硬件的,你将会找到board目录底下的memsetup.S。**************/
     mov ip, lr
    #ifndef CONFIG_S3C2440A_JTAG_BOOT
     bl memsetup        //调用memsetup子程序(在board/smdk2442memsetup.S)
    #endif
     mov lr, ip
     mov pc, lr                        //子程序返回
     
    memsetup:   
    /**************** 初始化内存 **************/
            mov     r1, #MEM_CTL_BASE
            adrl    r2, mem_cfg_val
            add     r3, r1, #52
    1:       ldr     r4, [r2], #4
            str     r4, [r1], #4
            cmp     r1, r3
            bne     1b
    /*********** 跳转到原来进来的下一个指令(start.S文件里) ***************/  
    mov     pc, lr                 //子程序返回
     

    并通过下段代码拷贝到内存里
    relocate:                             //把uboot重新定位到RAM
     adr r0, _start                  // r0 是代码的当前位置 
     ldr r2, _armboot_start               //r2 是armboot的开始地址
     ldr r3, _armboot_end                //r3 是armboot的结束地址
     sub r2, r3, r2                      // r2得到armboot的大小 
     ldr r1, _TEXT_BASE            // r1 得到目标地址  
     add r2, r0, r2                    // r2 得到源结束地址 
    copy_loop:                             //重新定位代码
     ldmia r0!, {r3-r10}                  //从源地址[r0]中复制
     stmia r1!, {r3-r10}                  //复制到目标地址[r1]
     cmp  r0, r2                        //复制数据块直到源数据末尾地址[r2]
     ble copy_loop

    /****************** 建立堆栈 *******************/
     ldr r0, _armboot_end               //armboot_end重定位
     add r0, r0, #CONFIG_STACKSIZE    //向下配置堆栈空间
     sub sp, r0, #12                  //为abort-stack预留个3字

    /**************** 跳转到C代码去 **************/
     ldr pc, _start_armboot           //跳转到start_armboot函数入口,start_armboot字保存函数入口指针
    _start_armboot: .word start_armboot    //start_armboot函数在lib_arm

    /board.c中实现
    从此进入第二阶段C语言代码部分
  • 相关阅读:
    ecmall挂件开发实例二(转)
    ecmall 挂件开发实例一
    ecmall公告挂件分析(转)--此挂件写法已有更新的写法。
    centos下svn的主要常用命令(解决商城系统添加的文件无法自动更新至svn服务器)
    lbypmall虚拟主机的设置
    解决EditPlus的默认编码方式有关问题(转)
    php mysql 字符集(三) (转)
    php mysql apache字符集(二) (转)
    php mysql apache 的字符集
    Android学习笔记——文件路径(/mnt/sdcard/...)、Uri(content://media/external/...)学习
  • 原文地址:https://www.cnblogs.com/cainiaoaixuexi/p/3272864.html
Copyright © 2011-2022 走看看