ARM的启动过程是什么?

| 众所周知,对于X86架构:按下电源按钮后,机器开始在0xFFFFFFF0处执行代码,然后开始在BIOS中执行代码以进行硬件初始化。执行BIOS后,它将使用引导加载程序将OS映像加载到内存中。最后,OS代码开始运行。 对于ARM体系结构,使用后按电源按钮的启动过程是什么? 谢谢!     
已邀请:
当前,ARM体系结构中有两种异常模型(重置被认为是一种异常): 经典模型,用于Cortex之前的芯片和当前的Cortex-A / R芯片。其中,位于0的内存包含几个异常处理程序:
 Offset  Handler
 ===============
 00      Reset 
 04      Undefined Instruction
 08      Supervisor Call (SVC)
 0C      Prefetch Abort
 10      Data Abort
 14      (Reserved)
 18      Interrupt (IRQ)
 1C      Fast Interrupt (FIQ)
当发生异常时,处理器只是从一个特定的偏移量开始执行,因此通常该表包含单指令分支,这些分支指向代码中更进一步的完整处理程序。典型的经典向量表如下所示:
00000000   LDR   PC, =Reset
00000004   LDR   PC, =Undef
00000008   LDR   PC, =SVC
0000000C   LDR   PC, =PrefAbort
00000010   LDR   PC, =DataAbort
00000014   NOP
00000018   LDR   PC, =IRQ
0000001C   LDR   PC, =FIQ
在运行时,向量表可以重定位到0xFFFF0000,通常将其实现为紧密耦合的内存范围,以实现最快的异常处理。但是,上电复位通常从0x00000000开始(但是在某些芯片中,可以通过处理器引脚将其设置为0xFFFF0000)。 新的微控制器模型用于Cortex-M芯片系列。那里,向量表实际上是0的向量表(指针),而不是指令。第一个条目包含SP寄存器的启动值,第二个条目是复位向量。由于处理器设置了堆栈,因此这允许直接用C写复位处理程序。同样,可以在运行时重新定位表。 Cortex-M的典型向量表如下所示:
__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler
                [...more vectors...]
请注意,在诸如OMAP3或Apple的A4之类的现代复杂芯片中,执行的第一段代码通常不是用户代码,而是片上Boot ROM。它可能会检查各种条件,以确定从何处加载用户代码以及是否完全加载用户代码(例如,可能需要有效的数字签名)。在这种情况下,用户代码可能必须符合不同的启动约定。     
接通电源后,CPU将开始执行异常模式,第一个复位。由于复位必须以超级用户模式运行,因为CPU在执行时不知道寄存器的状态,因此无法进入超级用户模式。这个小代码需要编写(请参阅最后)。之后,可以通过将地址加载到PC中来处理其他异常。
.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

reset:
    mrs     r0,cpsr                 /* set the cpu to SVC32 mode        */
    bic     r0,r0,#0x1f             /* (superviser mode, M=10011)       */
    orr     r0,r0,#0x13
    msr     cpsr,r0
    
...最后,OS代码开始运行。对于ARM体系结构,使用后按电源按钮的启动过程是什么? 这个答案主要是在上下文或现代的Cortex-A CPU中;有各种各样的ARM平台。但是,对于像PC这样的ARM(平板电脑,手机等)... ARM CPU将从0x0或0xffff0000获取一条指令(对于Cortex-M,它是与指令相对的数据)。典型的ARM SOC有一些使用此机制的引导ROM。对于最终用户,您需要查阅手册来确定如何运行代码。即,有许多使用该向量的ARM SOC内置了BIOS,但是您需要使用其他方法来运行代码。 通常,ARM SOC将支持多个启动设备。该设备由某些保险丝(由制造工具设置)或采样引脚确定。引脚将是正在运行的系统中的CPU输出,但已被上拉/下拉来配置引导设备。每个引导设备将具有特殊的详细信息; ROM很简单,但是NAND闪存,SPI闪存,MMC等需要一些配置详细信息。这些通常也由片上保险丝和/或采样引脚提供。可以读取设备的一小部分以进一步配置设备。 对于深度嵌入式的ARM芯片,它可能仅从板载闪存启动,并且此过程要简单得多。但我相信从这个问题的上下文来看,您所指的是更高级的ARM CPU。更高级的ARM系统具有引导加载程序。这是因为ROM加载程序将加载的代码量通常受到限制和/或受限制。设置SDRAM通常也很复杂,并且引导加载程序的结构可能要从配置SDRAM的内部静态RAM运行。 请参阅:为什么我们需要引导加载程序 运行操作系统有其独特的问题。对于ARM Linux,它是ATAGS,现在是devicetree。人们可以在其中编写自己的启动加载程序,也可以使用许多开源项目之一,其中最常见的就是u-boot。 U-boot支持vxWorks,Linux,NetBSD,Plan9,OSE,QNX,Integrity和OpenRTOS以及二进制映像。 许多原始的ARM Linux设备都支持在没有引导加载程序的情况下直接引导Linux。但是,除了少数几个非常老的ARM SOC /内核之外,Linux在主线上不支持此功能。     

要回复问题请先登录注册