分析 u-boot 的第一阶段代码(cpu/arm920t/start.S)
- UID
- 1029342
- 性别
- 男
|
分析 u-boot 的第一阶段代码(cpu/arm920t/start.S)
uboot中start.S详解(zt)
[cpp] view plaincopy
- #include <config.h>
- #include <version.h>
- /* 这段代码的主要作用是初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境 */
- #if defined(CONFIG_OMAP1610)
- #include <./configs/omap1510.h>
- #elif defined(CONFIG_OMAP730)
- #include <./configs/omap730.h>
- #endif
- /*************************************************************************
- *
- * Jump vector table as in table 3.1 in [1]
- *
- *************************************************************************/
- .globl _start
- _start: /* 系统复位位置, 各个异常向量对应的跳转代码 */
- b 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 /* 快速中断异常向量 */
- _undefined_instruction:
- .word undefined_instruction
- _software_interrupt:
- .word software_interrupt
- _prefetch_abort:
- .word prefetch_abort
- _data_abort:
- .word data_abort
- _not_used:
- .word not_used
- _irq:
- .word irq
- _fiq:
- .word fiq
- .balignl 16,0xdeadbeef
- /************************************************分析****************************************************
- * 从中我们可以看出,ARM支持7种异常。问题是发生了异常后ARM是如何响应的呢?
- * 第一个复位异常很好理解,它放在0x0的位置,一上电就执行它,而且我们的程序总是从
- * 复位异常处理程序开始执行的,因此复位异常处理程序不需要返回。那么什么时候会执行
- * 到后面几个异常处理函数呢?步骤是这样的:
- *
- * 当一个异常出现以后,ARM会自动执行以下几个步骤:
- * (1) 把下一条指令的地址放到连接寄存器LR(通常是R14),这样就能够在处理异常返回时从正确的位置继续执行。
- * (2) 将相应的CPSR(当前程序状态寄存器)复制到SPSR(备份的程序状态寄存器)中。从异常退出的时候,就可以由SPSR来恢复CPSR。
- * (3) 根据异常类型,强制设置CPSR的运行模式位。
- * (4) PC(程序计数器)被强制成相关异常向量处理函数地址,从而跳转到相应的异常处理程序中。
- *
- * 当异常处理完毕后,ARM会执行以下几步操作从异常返回:
- * (1) 将连接寄存器LR的值减去相应的偏移量后送到PC中
- * (2) 将SPSR复制回CPSR中
- * (3) 若在进入异常处理时设置了中断禁止位,要在此清除
- *
- * ARM规定了异常向量的地址:
- * b reset ; 复位 0x0
- * ldr pc, _undefined_instruction ; 未定义的指令异常 0x4
- * ldr pc, _software_interrupt ; 软件中断异常 0x8
- * ldr pc, _prefetch_abort ; 预取指令 0xc
- * ldr pc, _data_abort ; 数据 0x10
- * ldr pc, _not_used ; 未使用 0x14
- * ldr pc, _irq ; 慢速中断异常 0x18
- * ldr pc, _fiq ; 快速中断异常 0x1c
- * 这样理解这段代码就非常简单了。碰到异常时,PC会被强制设置为对应的异常向量,从而跳转到
- * 相应的处理程序,然后再返回到主程序继续执行。
- *
- * .balignl 16,0xdeadbeef, 将地址对齐到16的倍数,如果地址寄存器的值(PC)跳过4个字节才是16的倍数,
- * 则使用0xdeadbeef填充这4个字节,如果它跳过1、2、3个字节,则填充值不确定。如果地址寄存器的值(PC)
- * 是16的倍数,则无需移动。
- ********************************************************************************************************/
- /*************************************************************************
- *
- * Startup Code (reset vector)
- *
- * do important init only if we don't start from memory!
- * setup Memory and board specific bits prior to relocation.
- * relocate armboot to ram
- * setup stack
- *
- *************************************************************************/
- /* 保存变量的数据区 */
- _TEXT_BASE:
- .word TEXT_BASE
- .globl _armboot_start
- _armboot_start:
- .word _start
- /* These are defined in the board-specific linker script.*/
- .globl _bss_start
- _bss_start:
- .word __bss_start
- .globl _bss_end
- _bss_end:
- .word _end
- #ifdef CONFIG_USE_IRQ
- /* IRQ stack memory (calculated at run-time) */
- .globl IRQ_STACK_START
- IRQ_STACK_START:
- .word 0x0badc0de
- /* IRQ stack memory (calculated at run-time) */
- .globl FIQ_STACK_START
- FIQ_STACK_START:
- .word 0x0badc0de
- #endif
- /*************************************************分析**********************************************************
- * 上面这段代码,主要保存一些全局变量,用于BOOT程序从FLASH拷贝到RAM,或者其它的使用。
- * 还有一些变量的值是通过连接脚本得到的,比如TEXT_BASE位于/u-boot-1.1.6/board/xxx(开发板目录名称)/config.mk
- * 文件里。__bss_start、_end位于/u-boot-1.1.6/board/xxx(开发板目录名称)/u-boot.lds文件里,具体值是由编译器算出来的。
- ***************************************************************************************************************/
- /* the actual reset code*/
- /* 系统的复位代码。系统一上电,就跳到这里运行 */
- reset:
- /*
- * set the cpu to SVC32 mode
- */
- mrs r0,cpsr /* 取得当前程序状态寄存器cpsr到r0 */
- bic r0,r0,#0x1f /* 这里使用位清除指令,把中断全部清除,只置位模式控制位 为中断提供服务通常是 OS
- *设备驱动程序的责任,因此在 Boot Loader 的执行全过程中可以不必响应任何中断。
- */
- orr r0,r0,#0xd3 /* 计算为超级保护模式 */
- msr cpsr,r0 /* 设置cpsr为超级保护模式 */
- /***********************************************分析*************************************************************
- * 设置cpu运行在SVC32模式。ARM共有7种模式:
- * 用户模式(usr): arm处理器正常的程序执行状态
- * 快速中断模式(fiq): 用于高速数据传输或通道处理
- * 外部中断模式(irq): 用于通用的中断处理
- * 超级保护模式(svc): 操作系统使用的保护模式
- * 数据访问终止模式(abt): 当数据或指令预取终止时进入该模式,可用于虚拟存储及存储保护
- * 系统模式(sys): 运行具有特权的操作系统任务
- * 未定义指令中止模式(und): 当未定义的指令执行时进入该模式,可用于支持硬件协处理器的软件仿真
- *
- * 通过设置ARM的CPSR寄存器,让CPU运行在操作系统保护模式,为后面进行其它操作作好准备了。
- ****************************************************************************************************************/
- /*
- * we do sys-critical inits only at reboot,
- * not when booting from ram!
- */
- #ifndef CONFIG_SKIP_LOWLEVEL_INIT
- bl cpu_init_crit
- /******************************************************************************
- * BL为相对寻址,以程序计数器PC 的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址
- * ARM 指令集中的4条跳转指令可以完成从当前指令向前或向后的32MB 的地址空间的跳转,
- * 用的是相对寻址,它们是:B、BL、BLX、BX
- *******************************************************************************/
|
|
|
|
|
|