u-boot启动流程分析

来源:互联网 发布:昆士兰会计硕士知乎 编辑:程序博客网 时间:2024/05/21 08:35

u-boot启动流程如下:

1)reset

2)设置CPU模式

3)关闭看门狗/中断

4)设置处理器时钟/片上总线

5)初始化调试串口

5)  MMU/外部总线/SDRAM等初始化

6)ROM代码/数据搬移到RAM

7)初始化外围设备/参数

8)启动完毕,进入main_loop循环

 

u-boot主要提供以下功能:

1)设置目标板硬件参数并初始化

2)为操作系统传递必要信息

3)执行交互式的底层操作

4)智能化装载操作系统

5)引导和运行的固定程序

6)支持大容量存储和USB接口

代码分析如下:

s3c2410复位以后,PC指针会指向0x0地址(在u-boot代码中,0x0地址是一个向量表)。

第一条指令跳转branch到复位代码start_code(位于cpu/arm920t/start.S汇编程序的53行)。

 .globl _start  

  _start:  b start_code

              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

复位指令跳转之后来到第154行,开始执行arm920t处理器的基本初始化。

首先修改当前程序状态寄存器CPSR,使处理器进入Supervisor工作模式与32 bit ARM模式,并关闭ARM9TDMI中断和快速中断,这是通过设置CPSR相应掩码实现的 :

start_code:    
           mrs r0,cpsr
           bic r0,r0,#0x1f
           orr r0,r0,#0xd3
           msr cpsr,r0 
紧接着,将S3C2410特有的WTCON寄存器清零,此举仅为关闭看门狗,代码位置是234行:

           ldr r0 ,#pWTCON

           mov r1,#0x0

           str   r1,[r0]

然后在241行,将S3C2410中断控制器INTMSK寄存器置为全1,INTSUBMSK置为0x7ff,禁止全部中断源。
           mov r1, #0xffffffff
           ldr r0, =INTMSK
           str r1, [r0]
 # if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_S3C2442) ||  defined(CONFIG_S3C2443)
          ldr r1, =INTSUBMSK_val
          ldr r0, =INTSUBMSK
          str r1, [r0]
 # endif

接下来在259行,访问arm920t控制寄存器CP15,并置位最高两位[31,30]。
此两位置为0b11后,处理器时钟被设置为异步模式,允许处理器异步访问总线:

          mrc p15, 0, r1, c1, c0, 0
          orr r1, r1, #0xc0000000
           mcr p15, 0, r1, c1, c0, 0
至此arm920t相关的配置完成。

根据不同的编译时选项和运行时参数,代码会在360行进入相应的分支,分别是nor启动和nand启动。

下面就nand启动进行描述:从nand启动,代码执行lowlevel_init,主要是清楚cpu cache,以及关闭mmu和i-cache,并且根据板子硬件配置初始化外部存储器总线和GPIO,最后把代码从nand flash中拷贝到RAM中并继续执行

s3c2410u-boot前4K搬移问题  

下面详细分析一下它的最前面的启动过程.

      1.在板子上电的一开始,首先自动判断是否是autoboot模式(这是由硬件设计阶段,由硬件工程师对mcu的引脚连线决定的),我所使用的s3c2410是带有nandflash的,并切被设置成autoboot,从nandflash开始启动. 


      2.在判断是autoboot模式后,mcu内置的nandflash控制器自动将nandflash的最前面的4k区域(这4k区域存放着 bootloader的最前面4k代码)拷贝到samsung所谓的"steppingstone"里面(实际上是一块4k大小的SRAM).


      3.在拷贝完前4k代码后,nandflash控制器自动将"steppingstone"映射到arm地址空间0x00000000开始的前4k区域.


      4.在映射过程完成后.nandflash控制器将pc指针直接指向arm地址空间的0x00000000位置,准备开始执行"steppingstone"上的代码.


      5.而"steppingstone"上从nandflash拷贝过来的4k代码,是程序员写的bootloader的前4k代码.这个 bootloader在之前写好,并已经被烧写到nandflash的0x00000000开始的最前面区域..而这"steppingstone"上的 4k代码就是bootloader的前4k代码.


      6.在pc指向arm地址空间的0x00000000后,系统就开始执行指令代码.这4k代码的任务是:初始化硬件,设置中断向量表,设置堆栈,然后一个很重要的任务是,将nandflash的最前面区域的bootloader(包含4k启动代码)拷贝到SDRAM中去,bootloader代码的大小是写好bootloader就确定的.然后只需要确定bootloader想映射到SDRAM的起始位置就ok.


      7.在完成对nandflash上的bootloader搬移后,找到4k代码的搬移代码最后一个指令的下一个指令在SDRAM的bootloader的地址,然后跳转到该位置,继续执行bootloader的剩余代码(引导系统).





1.复位异常

(1)当内核的nRESET信号被拉低时,ARM处理器放弃正在执行的指令,当nRESET信号再次变高时,ARM处理器进行复位操作;

(2)系统复位后,进入管理模式对系统进行初始化,复位后,只有PC(0x00000000)和CPSR(nzcvqIFt_SVC)的值是固定的,另外寄存器的值是随机的。

2.IRQ异常

(1)当CPSR中的相应的中断屏蔽被清除时,内核的nIRQ信号被拉低时可产生IRQ异常;

(2)由于ARM处理器的三级流水线结构,当异常发生时,PC的值等于当前执行指令的地址+8(即正确的中断返回地址+4),因此R14保存的值是 中断返回地址+4 ,所以当异常要返回时须执行以下指令:

SUBS   PC,R14_irq,#4             ;PC=R14 - 4

注意:在SUB指令尾部有个S,并且PC是目标寄存器,所以程序返回时CPSR将自动从SPSR寄存器中恢复;

(3)将用户模式下的CPSR保存到SPSR_irq中;

(4)设置PC为IRQ异常处理程序的中断入口向量地址,在IRQ模式下该向量地址为0x00000018。

3.FIR异常

(1)当CPSR中的相应F位被清零时,内核的nFIR信号被拉低时可产生FIR异常,FIQ异常是优先级最高的中断;

(2)FIQ异常的进入和退出与IRQ异常类似;

(3) 快速中断模式有8个专用的寄存器,可用来满足寄存器保护的需要,因此从其他模式进入FIQ模式时这些寄存器不用压栈了,提高程序运行的速度,且在中断入口 地址的安排上,FIQ处于所有异常入口的最后,这是为了让用户可以从FIQ异常入口处(0x1c)就开始安排中断服务程序,而不需要再次跳转。

4.未定义指令异常

(1)当ARM在对一条未定义指令进行译码时,发现这是一条自己和系统内任何协处理器都无法执行的指令时,就会发生未定义指令异常;

(2)由于是在对未定义指令译码时发生异常,所以PC的值等于未定义指令的地址+4(即刚好为中断返回地址),因此R14保存的值是 中断返回地址 ,所以当异常要返回时可执行以下指令:

MOVS   PC,R14_und             

5.中止异常

中止表示当前存储器的访问不能完成,是由外部的ABOUT输入信号引起的异常,分为两类:

(1) 预取指中止:由程序存储器引起的中止异常;

(2) 数据中止:由数据存储器引起的中止异常;

5.1预取指中止异常

当 程序发生预取指中止时,ARM内核将预取的指令标记为无效,但在指令到达流水线的执行阶段时才进入异常,因此当前PC的值为当前执行指令的地址+8(即正 确的中断返回地址+4),因此R14保存的值是 中断返回地址+4 ,所以当修复了产生中止的原因后,不管在什么操作状态,处理器都会执行以下指令:

SUBS   PC,R14_abt,#4             ;PC=R14 - 4

5.2数据中止异常

当 发生数据中止异常时,异常会在“导致异常的指令”执行后的下一条指令时才发生,因此当前PC的值为“导致异常的指令”执行后的下一条指令的地址+8(即正 确的中断返回地址+8),因此R14保存的值是 中断返回地址+8,所以当修复了产生中止的原因后,不管在什么操作状态,处理器都会执行以下指令:

SUBS   PC,R14_abt,#8             ;PC=R14 - 8

注意:LPC2000系列ARM是基于ARM7TDMI内核的,不具有MMU,所以不应该发生中止异常,初学者时常会发生中止异常,大多数是因为编写的程序的问题。

6.SWI软件中断异常

(1)所有的任务都是运行在用户模式下的,因此任务只能读CPSR而不能写SPSR。任务切换到特权模式下唯一的途径就是使用一个SWI指令调用,SWI指令强迫处理器从用户模式切换到SVC管理模式,并且IRQ自动关闭,所以软件中断方式常被用于系统调用。

(2)系统调用的具体过程还是看有关uc/os-II等操作系统书,那里比较详细。

(3)SWI处理程序通过执行下面的指令返回:

MOVS   PC,R14_svc

具体为什么偏移量为0,我现在也还没有搞懂,请看到的大虾多多指点,留个言,谢谢了!!!

      经高手指点后明白了原来这么多异常的返回地址问题只要一句话:除 了数据中止以外,所有异常发生时R14保存的值都是跳转时的PC-4,只是软件原因引起的异常时执行时(PC为该指令地址+8)就发生异常跳转了,而硬件 引起的异常为了保证程序安全必须等到当前指令完成后(执行目标已经指向下一个指令,即PC为该指令地址+12)才会发生跳转。


原创粉丝点击