博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
u-boot启动第一阶段
阅读量:4683 次
发布时间:2019-06-09

本文共 3757 字,大约阅读时间需要 12 分钟。

  目标板:2440开发板

  u-boot启动的第一阶段是在文件start.S中完成的,这个过程对不同硬件平台的设置是不同的。下面进入start.S  

 _start: b reset //跳转到reset

  //设置CPU为SVC32安全管理模式

    reset:      /*  * set the cpu to SVC32 mode  */  mrs    r0,cpsr  bic    r0,r0,#0x1f  orr    r0,r0,#0xd3  msr    cpsr,r0

  //关闭看门狗

#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] 
 

   //初始化内存

#ifndef CONFIG_SKIP_LOWLEVEL_INIT    adr    r0, _start        /* r0 <- current position of code   */    /*将_start的值赋给r0,如果_start的地址为0x33F80000,则说明内存已经被初始化,准备从0x33F80000运行程序    如果_start的值为0,则说明程序还没开始执行,内存没有被初始化*/    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */    //将链接地址_TEXT_BASE,给r1    cmp     r0, r1                  /* don't reloc during debug         */    /*cmp = 0时,则r0 = r1,那么程序已经把SDRAM初始化了*/    blne    cpu_init_crit    /* 当r0和r1不相等时,跳转到cpu_init_crit*/    #endif

 /*查找cpu_init_crit*/

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  关闭MMU,内存映射     */    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    bl    lowlevel_init  /*跳转到lowlevel_init,开始初始化SDRAM*/    mov    lr, ip    mov    pc, lr

  /*lowlevel_init的路径为/cpu/arm920t/ks8695/lowlevel_init.S ,在lowlevel_init.S中,对内存进行设置*/

  //设置堆栈

/* 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    */

  /*从上面的代码可以知道,栈区已经被分为好几个部分,栈的起始地址为_TEXT_BASE,依次分为堆区,全局数据区等如下图所示*/

  

  /*在栈设置好之后,就可以处理C程序了*/

#ifndef CONFIG_SKIP_LOWLEVEL_INIT        bl clock_init    #endif

  /*clock_init设置时钟,在上面的栈初始化结束之后执行,这儿处理的clock_init,是C语言程序*/

  进入/board/100ask24x0/boot_init.c,文件boot_init.c中的void clock_init(void),用的是c与汇编混合编程,c语言中嵌入汇编。

  /*下面这段代码就是,开始搬运u-boot到SDRAM中去*/

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     clear_bss

  //如果加载地址与链接地址相等,则开始清BSS段,BSS段中存放的是未初始化的静态变量和全局变量

  由u-boot.lds可以知道,BSS段从从_bss_start开始,在_end 结束

clear_bss:        ldr    r0, _bss_start        /* find start of bss segment        */        ldr    r1, _bss_end        /* stop here                        */        mov     r2, #0x00000000        /* clear                            */

  /*在清空BSS段之后,就跳转到_start_armboot,就开始从start_armboot运行C程序*/

ldr    pc, _start_armboot    _start_armboot:    .word start_armboot

  综合上边的过程,可以得到,start.S 中所作如下工作:

  1.设置设置CPU为SVC32安全管理模式
  2.关闭看门狗
  3.屏蔽中断
  4.开始初始化SDRAM
  5.设置堆栈
  6.clock_init设置时钟
  7.搬运u-boot到SDRAM中
  8.清BSS段
  9.调用start_armboot进入第二阶段

转载于:https://www.cnblogs.com/youthshouting/p/4417554.html

你可能感兴趣的文章
【CS231N】6、神经网络动态部分:损失函数等
查看>>
Python学习笔记(四)——编码和字符串
查看>>
使用正则表达式,取得点击次数,函数抽离
查看>>
hackerrank刷题总结
查看>>
重拾 BFC、IFC、GFC、FFC
查看>>
学习笔记6
查看>>
《软件工程概论》第8.9章核心内容
查看>>
Android中EditText,Button等控件的设置
查看>>
客户端与服务器新建套接字连接的一种方法
查看>>
Sqoop- sqoop将mysql数据表导入到hive报错
查看>>
LeetCode Encode and Decode Strings
查看>>
MySql常用指令
查看>>
requests模块(get请求)篇
查看>>
背包问题
查看>>
node 日志
查看>>
(转)正则表达式小括号的多义性
查看>>
script标签中defer和async属性的区别
查看>>
(源码下载)高灵活度,高适用性,高性能,轻量级的 ORM 实现
查看>>
PHPCMS V9多站点[站群功能]动态设置与静态设置子站内容URL
查看>>
linux 查看命令 ___软连接__大小排序 ___时间排序
查看>>