U-Boot启动的函数调用过程(以arm926ejs为例)

本文转自:http://blog.csdn.net/hongkaicsu/article/details/5141985

调用链如下,后面是文字解说:

 reset -> cpu_init_crit -> lowlevel_init (板子相关)
           -> relocate (将U-boot重定位到RAM)
           -> stack_setup
           -> clear_bss
           -> start_armboot() (C程序) -> main_loop()

系统上电复位后首先跳转到一个指定的地址,ARM的话是0x00000000地址,即通常所说的复位异常向量地址。然后在这里存放了一条指令b reset,即跳转到reset过程执行。至于怎么把这条指令放在这里则是链接过程指定的。

reset过程会将首先将CPU设定为SVC32模式,然后调用cpu_init_crit过程,这个过程对Cache和MMU进行一些操作,主要是冲刷Cache和关闭Cache和MMU。为什么要做这些呢,这主要是为了将CPU设定到一个确定的状态,因为启动的时候CPU处于什么状态是未知的,Cache里面的内容也是不确定的,如果不关闭的话,可能会让CPU取到错误的指令。

然后它会调用lowlevel_init过程,注意lowlevel_init过程是与特定板子相关的,是移植时需要实现的过程。它位于./board/<board_name>/lowlevel_init.S文件中,主要是初始化一些板上的硬件控制器等,lowlevel_init结束后返回cpu_crit_init, cpu_crit_init返回到reset,然后接着执行。

接下来要执行的是relocate过程,它负责把U-Boot从Flash从定位到RAM中,执行完之后接下来依次执行stack_setup,clear_bss。

这两个都执行完毕,执行一条跳转指令(采用ldr pc, <addr>的形式)跳转到start_armboot执行。

在start_armboot之前都是arm汇编代码,从start_armboot开始就进入了C语言过程。它按照顺序执行一大堆初始化任务,这个和Linux内核的start_kernel有类似的地方。最后它调用main_loop()进入这么个死循环中,此后的事情就暂且先不关心了。

关于relocate

这个直译叫重定位,另外有一个remap,直译为重映射,要注意这两者是不一样的,这里现来看看重定位。

首先,系统启动时U-Boot的代码是在FLASH上面的,所以在relocate之前的所有代码都是在flash上面执行的,而且所有代码都是位于FLASH上的。而relocate则是把FLASH上的的代码搬移到RAM中。但是怎么保证relocate之后执行的是RAM中的代码而不是FLASH中的代码呢?

这个待会儿说,似乎涉及到PIC,大意是程序中的指令偏移会被替换成重定位后正确的地址位置,注意这个过程是在链接时,而不是运行时。具体怎么情况,稍后奉上。

关于remap

一般是CPU提供的硬件设置功能,它会允许把内存地址空间的某一段映射到某个位置,ARM中常见的是在上电复位的时候自动把引导加载程序锁在FLASH的地址映射到0x00000000,在引导加载的过程中由软件通过设置某个内存重映射寄存器,然后把主存地址重映射到0x00000000。在这种重映射的情况下,访问映射的地址相当于直接访问对应的FLASH或者主存的地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值