什么是ARM的启动过程?
我们知道,对于X86架构:按下电源button后,机器开始执行代码0xFFFFFFF0,然后开始在BIOS中执行代码,以便进行硬件初始化。 BIOS执行后,使用bootloader将操作系统映像加载到内存中。 最后,OS代码开始运行。 对于ARM架构,使用后按下电源button是什么启动过程? 谢谢!
目前,在ARM架构中有两种exception模式(复位被认为是一种exception):
经典型号,用于Cortex前置芯片和目前的Cortex-A / R芯片。 其中,0的内存包含几个exception处理程序:
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)
当exception发生时,处理器只是从一个特定的偏移量开始执行,所以通常这个表包含代码中进一步完整处理程序的单指令分支。 典型的经典向量表如下所示:
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,这通常被实现为紧密耦合的存储器范围,以实现最快的exception处理。 但是,上电复位通常从0x00000000开始(但在某些芯片中,可以通过处理器引脚将其设置为0xFFFF0000)。
Cortex-M系列芯片中使用了新的微控制器模型。 在那里,0的向量表实际上是向量(指针)的表格,而不是指令。 第一个条目包含SP寄存器的启动值,第二个条目是复位向量。 这允许直接在C中写入重置处理程序,因为处理器设置了堆栈。 同样,表可以在运行时重新定位。 典型的Cortex-Mvector表如下所示:
__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或者苹果A4中,第一块执行的代码通常不是用户代码,而是片上的Boot ROM。 它可能会检查各种条件以确定从哪里加载用户代码以及是否加载它(例如,它可能需要有效的数字签名)。 在这种情况下,用户代码可能必须符合不同的启动约定。
上电后,CPU将开始执行exception模式,第一次复位,由于CPU在此时不知道寄存器的状态,因此复位必须作为主pipe模式运行,所以不能进入监督模式。小代码需要写(见最后)。 在此之后,可以通过将地址加载到PC中来处理其他exception。
.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架构,使用后按下电源button是什么启动过程?
这个答案主要是在上下文或现代Cortex-A CPU中; ARM平台种类繁多。 然而,对于一个类似PC(平板电脑,手机等)的ARM …
ARM CPU将从0x0或0xffff0000中获取指令(对于Cortex-M来说,它是数据而不是指令)。 典型的ARM SOC有一些使用这种机制的引导程序。 对于最终用户,您需要查阅手册以确定如何让您的代码运行。 也就是说,有许多ARM SOC内置了使用该向量的BIOS ,但是您需要使用不同的东西来让您的代码运行。
通常ARM SOC将支持多个引导设备。 该设备由一些FUSE(由制造工具设置)或采样引脚确定。 这些引脚在运行系统中是CPU输出,但是已经上拉/下拉以configuration引导设备。 每个启动设备都会有独特的细节; ROM很简单,但是NAND闪存,SPI闪存,MMC等需要一些configuration细节。 这些也通常由片上FUSE和/或采样引脚提供。 设备的一小部分可能被读取以进一步configuration设备。
对于深度embedded式的ARM芯片来说,它只能从板载闪存启动,而且这个过程要简单得多; 但我相信从这个问题的angular度来看,您指的是更先进的ARM CPU。 更高级的ARM系统有一个引导装载程序。 这是因为ROM加载程序加载的代码量通常受到限制和/或限制。 设置SDRAM通常也很复杂,引导加载程序可能被configuration为从configurationSDRAM的内部静态RAM运行。
看: 为什么我们需要一个引导程序
运行操作系统有其特殊的问题。 对于ARM Linux,它是ATAGS,现在是devicetree。 人们可以在那里编写自己的引导装载程序,或者使用u-boot最常用的许多开源项目之一。 U-Boot支持vxWorks,Linux,NetBSD,Plan9,OSE,QNX,Integrity和OpenRTOS以及二进制映像。
许多原始的ARM Linux设备都支持Linux的直接引导 ,而不需要引导加载程序。 但是,除了一些非常老的ARM SOC /内核外,Linux不支持这一点。