uboot启动阶段分析

  1. uboot启动从_start开始,跳转到reset  
  2.     ldr pc, _undefined_instruction  //初始化中断向量表 
  3. 系统启动后直接跳转到reset
    1. reset:  
    2.     mrs r0, cpsr    //程序状态寄存器cpsr  
    3.     bic r0, r0, #0x1f   //cpsr的低五位被清零  
    4.     orr r0, r0, #0xd3   //关中断,并进入SVC32模式  
    5.     msr cpsr,r0   
    6.     bl cpu_init_crit    //跳转到cpu_init_crit,初始化内存,时钟等关键寄存器 
    7. reset设置为管理模式后进入cpu_init_crit

关闭cache和MMU,在arm中cache是cpu的内部缓存,MMU实现虚拟地址与物理地址的转换。

cache在cpu中用来存放常用的数据和指令,cache开启的情况下,cpu首先在cache中寻找需要的指令或数据,cache中没有再从RAM获取,uboot启动的时候不管cache是否初始化都不会有cpu需要的数据,uboot用来实现简单的初始化和引导操作,关闭cache优化uboot性能。

C语言不能控制cache的开关,但关键字volatile能够避免优化,所谓避免优化实际上就是编译器告诉cpu在获取这个变量时不要从cache中读取,因为这个变量是随时可变的,cache不能实时的反应这些变量的值,cpu每次读取都直接从变量实际地址读取。同样关闭MMU,在uboot刚启动的时候避免虚拟地址与物理地址的转换。

lowlevel_init是lowlevel_init.S下定义的全局函数,配置启动必须的硬件

  1. #ifdef CONFIG_EXYNOS4412  
  2.     bl set_ema_value    //如果4412版本号大于2.0,设置apll,我们是1.1版本,不需要  
  3. #endif  
  1. 查看cpu是怎么复位的,如果从睡眠唤醒进入复位则发生跳转,否则继续执行  
  2.     /* Sleep wakeup reset */  
  3.     ldr r2, =S5P_CHECK_SLEEP  
  4.     cmp r1, r2  
  5.     beq wakeup_reset  
  6.   
  7.     /* PS-Hold high */  
  8.     //拉高PSHOLD管脚,唤醒电源管理芯片  

 

bl pmic_init 上电启动,需要初始化电源,如果是从睡眠状态恢复,则没到这一步

bl read_om   需要确定启动设备

b load_uboot    //加载uboot镜像

系统复位或上电重启后进入reset,在reset中将cpu设为管理模式后进入cpu_init_crit,在这里初始化cache并且关闭cache和MMU,跳转到lowlevel_init,在lowlevel_init中,根据不同的外部条件进行不同操作,首先判断系统是否从睡眠状态中复位,如果是则跳转到wakeup_reset,我们分析启动过程,显然不是不发生跳转,接下来就启动开发板上的电源,并且确定启动设备,

          beq after_copy      /* r0 == r1 then skip sdram init and u-boot.bin loading */同时通过pc判断执行环境的位置,如果已经在RAM中则证明RMA初始化uboot的拷贝都已经完成了,可以跳过,否则继续执行,初始化内存和时钟,跳转到load_uboot加载uboot镜像。

 

posted @ 2015-05-19 11:19  polo2013  阅读(538)  评论(0)    收藏  举报