start.S进一步、更详细的、深入的解释和分析 2013.04.26更新(二)

转自:http://zqwt.012.blog.163.com/blog/static/120446842013326690970/

 

/*****************************************************

* Startup Code (reset vector)  // 启动代码(复位向量)

 * do important init only if we don't start from memory!

* //如果不是一开始就从SDRAM里面启动,我们就在此做一些重要的初始化

 * relocate armboot to ram  //然后,搬运代码到SDRAM中的TEXT_BASE去执行

 * setup stack       // 设置堆栈

 * jump to second stage    // 跳到第二阶段去执行board.c */ 

_TEXT_BASE:

      .word   TEXT_BASE

l   TEXT_BASE在开发板相关的目录中的board/smdk2410/config.mk文档中定义, 即uboot要加载到sdram中的TEXT_BASE地址处去执行。

.globl _armboot_start

_armboot_start:

      .word  _start

l   用.globl声明 _armboot_start 并用_start 来进行初始化。在board/u-boot.lds中定义 ( _start定义在start.s中 --转者)

l   下面这几行代码是在S3C2410开发板的链接脚本board/u-boot.lds中给出定义的。( 只是__bss_start等定义在board/u-boot.lds中,并非代码  --转者)

声明_bss_start并用__bss_start来初始化,其中__bss_start定义在和板相关的u-boot.lds中。_bss_start保存的是__bss_start这个标号所在的地址,  这里涉及到当前代码所在的地址不是编译时链接的地址的情况(就我理解,即加载地址和运行地址的区别),这里直接取得该标号对应的地址,不受编译时链接地址的影响. _bss_end也是同样的道理。

.globl _bss_start

_bss_start:

      .word  __bss_start

 

.globl _bss_end

_bss_end:

      .word  _end

#ifdef CONFIG_USE_IRQ   // 如果定义了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

/*

 *  the actual reset code

 *  复位或者上电之后,代码从这里开始执行

 */

reset:

l   设置CPU的状态类型为SVC特权模式(一共7种权限,这是其中的一种)。

Reset即复位,在系统中经常会用到,该操作是异常处理的第一个操作,其主要目的是设置CPU模式为SVC特权模式。在此,有必要介绍一下ARM处理器的7种工作模式。



 l   CPSR(当前程序状态寄存器)的低5位用于定义当前操作模式,如图示:

start.S进一步、更详细的、深入的解释和分析 2013.04.26更新(二)_第1张图片


l   除用户模式外的其他6种模式称为特权模式。

特权模式中除系统模式以外的5种模式又称为异常模式,即 :

FIQ(Fast Interrupt Request)

IRQ(Interrupt ReQuest)

SVC(Supervisor)

中止(Abort)

未定义(Undefined)

l   ARM处理器总共有37个32位寄存器,可以分为以下两类寄存器:

?  31个通用寄存器(R0~R15)

R0~R15;

R13_svc、R14_svc;

R13_abt、R14_abt;

R13_und、R14_und;

R13_irq、R14_irq;

R8_frq-R14_frq。

?  6个状态寄存器

CPSR;SPSR_svc、SPSR_abt、SPSR_und、SPSR_irq和SPSR_fiq 。

start.S进一步、更详细的、深入的解释和分析 2013.04.26更新(二)_第2张图片


l   但是这32个寄存器不能同时被访问,具体哪些寄存器是可编程访问的,取决于微处理器的工作状态以及具体的运行模式。但在任何时候,通用寄存器R0~R14、程序计数器(R15)PC、一个或两个状态寄存器都是可访问的。通用寄存器包括R0~R15(31个),可以分为3类:

?  未分组寄存器R0~R7

R0~R7是不分组寄存器。在所有处理器模式下,未分组寄存器都指向同一个物理寄存器,也就是说它们每一个都访问的是同一个物理寄存器,它们未被系统用作特殊的用途。但必须得注意,未分组寄存器没有被系统用于特别的用途,任何可采用通用寄存器的应用场合都可以使用相同的未分组寄存器,这样可能会造成寄存器中数据的破坏,所以必须注意对同一寄存器在不同模式下使用时的数据保护。

?  分组寄存器R8~R14

分组寄存器R8-R12:

FIQ模式分组寄存器R8~R12。

FIQ以外的分组寄存器R8~R12。

分组寄存器R13、R14

寄存器R13通常用做堆栈指针SP。

寄存器R14用作子程序链接寄存器(Link Register-LR),也称为LR。

?  程序计数器R15

寄存器R15被用作程序计数器,也称为PC 。

R15值的改变将引起程序执行顺序的变化,这有可能引起程序执行中出现一些不可预料的结果。

ARM处理器采用多级流水线技术,因此保存在R15的程序地址并不是当前指令的地址。一些指令对于R15的用法有一些特殊的要求。在ARM状态下,R15的位[1:0]为0,位[31:2]用于保存PC;在Thumb状态下R15的位[0]为0,位[31:1]用于保存PC。

l   这里有必要了解一Thumb状态下的寄存器组织

Thumb状态下的寄存器集是ARM状态下寄存器集的子集。程序员可以直接访问8个通用的寄存器(R0~R7),程序计数器PC、堆栈指针SP、连接寄存器LR和当前状态寄存器CPSP。其实,每一种特权模式都各有一组SP,LR和SPSR。可以看看下面这张图:

start.S进一步、更详细的、深入的解释和分析 2013.04.26更新(二)_第3张图片

l   ARM程序状态寄存器

所有处理器模式下都可以访问当前的程序状态寄存器CPSR。CPSR包含条件码标志、中断禁止位、当前处理器模式以及其它状态和控制信息。

在每种异常模式下都有一个对应的物理寄存器——程序状态保存寄存器SPSR。当异常出现时,SPSR用于保存CPSR的状态,以便异常返回后恢复异常发生时的工作状态。

下面这张图是CPSR和SPSR的格式:

  start.S进一步、更详细的、深入的解释和分析 2013.04.26更新(二)_第4张图片

 

你可能感兴趣的:(start.S进一步、更详细的、深入的解释和分析 2013.04.26更新(二))