ARM 的启动过程是怎样的?

发布于 2024-11-10 04:44:35 字数 152 浏览 4 评论 0原文

我们知道,对于X86架构:按下电源按钮后,机器开始执行0xFFFFFFF0处的代码,然后开始执行BIOS中的代码以进行硬件初始化。 BIOS 执行后,它使用引导加载程序将操作系统映像加载到内存中。最后,操作系统代码开始运行。 对于ARM架构,使用按下电源按钮后的启动过程是怎样的? 谢谢!

As we know, for X86 architecture: After we press the power button, machine starts to execute code at 0xFFFFFFF0, then it starts to execute code in BIOS in order to do hardware initialization. After BIOS execution, it use bootloader to load the OS image into memory. At the end, OS code starts to run.
For ARM architecture, what is the booting process after use press the power button?
Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

偏闹i 2024-11-17 04:44:35

目前,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。它可能会检查各种条件以确定从哪里加载用户代码以及是否加载它(例如,它可能需要有效的数字签名)。在这种情况下,用户代码可能必须符合不同的启动约定。

Currently, there are two exception models in the ARM architecture (reset is considered a kind of exception):

The classic model, used in pre-Cortex chip and current Cortex-A/R chips. In it, the memory at 0 contains several exception handlers:

 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)

When the exception happens, the processor just starts execution from a specific offset, so usually this table contains single-instruction branches to the complete handlers further in the code. A typical classic vector table looks like following:

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

At runtime, the vector table can be relocated to 0xFFFF0000, which is often implemented as a tightly-coupled memory range for the fastest exception handling. However, the power-on reset usually begins at 0x00000000 (but in some chips can be set to 0xFFFF0000 by a processor pin).

The new microcontroller model is used in the Cortex-M line of chips. There, the vector table at 0 is actually a table of vectors (pointers), not instructions. The first entry contains the start-up value for the SP register, the second is the reset vector. This allows writing the reset handler directly in C, since the processor sets up the stack. Again, the table can be relocated at runtime. The typical vector table for Cortex-M begins like this:

__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...]

Note that in the modern complex chips such as OMAP3 or Apple's A4 the first piece of code which is executed is usually not user code but the on-chip Boot ROM. It might check various conditions to determine where to load the user code from and whether to load it at all (e.g. it could require a valid digital signature). In such cases, the user code might have to conform to different start-up conventions.

迷途知返 2024-11-17 04:44:35

...最后,操作系统代码开始运行。对于ARM架构,使用按下电源按钮后的启动过程是怎样的?

这个答案主要是在现代 Cortex-A CPU 的背景下; ARM 平台种类繁多。然而,对于类似 PC 的 ARM(平板电脑、手机等)...

ARM CPU 将从 0x0 或 0xffff0000 获取指令(对于 Cortex-M,它是数据而不是指令)。典型的 ARM SOC 有一些使用这种机制的 boot rom。对于最终用户,您需要查阅手册来确定如何让您的代码运行。即,许多使用向量的 ARM SOC 中都内置了 BIOS,但您需要使用不同的东西来运行代码。

通常,ARM SOC 将支持多个启动设备。该器件由一些 FUSE(由制造工具设置)或采样引脚确定。这些引脚将是运行系统中的 CPU 输出,但已被上拉/下拉以配置启动设备。每个启动设备都会有特殊的细节; ROM很简单,但是NAND flash、SPI flash、MMC等需要一些配置细节。这些通常也由片上保险丝和/或采样引脚提供。可以读取设备的一小部分以进一步配置设备。

对于深度嵌入的ARM芯片,可能只能从板载闪存启动,这个过程要简单得多;但我相信从问题的上下文来看,您指的是更先进的 ARM CPU。更先进的 ARM 系统具有引导加载程序。这是因为 ROM 加载程序将加载的代码量通常是有限的和/或受限的。设置 SDRAM 通常也很复杂,并且引导加载程序可能被构造为从配置 SDRAM 的内部静态 RAM 运行。

请参阅:为什么我们需要引导加载程序

操作系统有其自身的特殊问题。对于 ARM Linux,它是 ATAGS,现在是 devicetree。人们可能会编写自己的引导加载程序或使用众多开源项目之一,其中最常见的是 u-boot。 U-boots 支持 vxWorks、Linux、NetBSD、Plan9、OSE、QNX、Integrity 和 OpenRTOS 以及二进制映像。

许多原始 ARM Linux 设备支持 Linux 的直接引导,无需引导加载程序。然而,除了一些非常旧的 ARM SOC/内核之外,Linux 在主线中不支持此功能。

... At the end, OS code starts to run. For ARM architecture, what is the booting process after use press the power button?

This answer is mainly in the context or modern Cortex-A CPUs; there are a great variety of ARM platforms. However, for an ARM that is PC like (tablet, cell phone, etc) ...

The ARM CPU will fetch an instruction from either 0x0 or 0xffff0000 (for a Cortex-M, it is data as opposed to an instruction). Typical ARM SOC have some boot rom which uses this mechanism. For an end user, you need to consult a manual to determine how to get your code to run. Ie, there is a BIOS built in to many ARM SOC which use the vector, but you need to use something different to get your code to run.

Typically the ARM SOC will support multiple boot devices. The device is determined by some FUSE (set by a manufacturing tool) or by sampling pins. The pins will be CPU outputs in a running system, but have been pulled up/down to configure a boot device. Each boot device will have peculiar details; ROM is simple, but NAND flash, SPI flash, MMC, etc need some configuration details. These are also often provided by a on-chip FUSE and/or sampling pins. A small portion of the device maybe read to further configure the device.

For a deeply embedded ARM chip, it may only boot from on-board flash and this process is much simpler; but I believe from the context of the question you are referring to more advanced ARM CPUs. More advanced ARM systems have a boot loader. This is because the amount of code a ROM loader will load is often limited and/or restricted. It is also often complex to set up SDRAM and the boot loader may be structured to run from internal static RAM, which configures the SDRAM.

See: Why we need a bootloader

Running the OS has its own peculiar issues. For ARM Linux, it was ATAGS and is now devicetree. People may code there own boot loader or use one of the many open-source projects with u-boot being the most common. U-boots supports vxWorks, Linux, NetBSD, Plan9, OSE, QNX, Integrity, and OpenRTOS as well a binary images.

Many original ARM Linux devices supported a direct boot of Linux without a boot loader. However, Linux does not support this in the main line except for a few very old ARM SOCs/cores.

冷默言语 2024-11-17 04:44:35

上电后,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

After Power is ON The cpu will start executing exception mode 1st one is reset ,As Reset must run as superviser mode since CPU doesn't know the status of the register at this time of execution it cant go into the superviser mode .To achieve this small code need to be written (See at end). after this other exceptions can be handled by loading the address into 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文