Analyzing the Reset Startup Process of ARM Cortex-M Core

The reset startup process of the ARM Cortex-M core is also known as the reset sequence. Below is a brief summary and analysis of this process.

The reset startup process of the ARM Cortex-M core is different from most other CPUs and also differs from previous ARM architectures (such as ARM920T, ARM7TDMI, etc.). Most CPUs begin execution from the first instruction at address 0x0000_0000 after a reset; however, this is not the case with the ARM Cortex-M core. Its reset sequence is as follows:
1. Retrieve the initial value of the MSP from address 0x0000_0000;
2. Retrieve the initial value of the PC from address 0x0000_0004, and then fetch instructions from the corresponding address.
This is illustrated in the diagram below:
Analyzing the Reset Startup Process of ARM Cortex-M Core
In fact, the address at 0x0000_0004 holds the default interrupt vector table (some references include the initial value of the MSP pointer at address 0x0000_0000 as part of the interrupt vector table, but this seems inappropriate). The layout of the interrupt vector table for the ARM Cortex-M core is shown in the diagram below:
Analyzing the Reset Startup Process of ARM Cortex-M Core
Note: The position of the interrupt vector table can be changed; this is the default setting.
It is important to note that in the ARM Cortex-M core, when an exception occurs, the code at the corresponding position in the interrupt vector table is not executed; instead, the data at that position is stored in the PC, and then instructions are fetched from that address. In summary, the interrupt vector table for the ARM Cortex-M should not contain jump instructions, but should instead contain the entry addresses for the ISR programs.
With the above analysis, the reset sequence is easy to understand; a reset is essentially an occurrence of a Reset exception. As can be seen from the diagram, the data stored at address 0x0000_0004 is precisely the entry address of the interrupt handler corresponding to the Reset exception.
Additionally, there are two detail issues that need attention:
1. The lowest three bits of the initial value stored at 0x0000_0000 must be 0;
2. The lowest bit of the address stored at 0x0000_0004 must be 1.
The first issue arises because the ARM AAPCS specifies the following constraints for stack usage:
5.2.1.1 Universal stack constraints At all times the following basic constraints must hold: Stack-limit < SP <= stack-base. The stack pointer must lie within the extent of the stack. SP mod 4 = 0. The stack must at all times be aligned to a word boundary. 5.2.1.2 Stack constraints at a public interface The stack must also conform to the following constraint at a public interface: SP mod 8 = 0. The stack must be double-word aligned.
In short, the specification states that the stack must always be aligned to a 4-byte boundary, and at the entry point, it must be aligned to an 8-byte boundary. The lowest two bits of the SP are set to 0 by hardware.
The second issue relates to the ARM mode and Thumb mode. In ARM, the address in the PC must be 32-bit aligned, with the lowest two bits also set to 0 by hardware. Therefore, the lowest two bits of the data written to the PC do not represent the actual address for fetching instructions. The lowest bit is used to determine whether the instruction is an ARM instruction or a Thumb instruction; if the lowest bit is 0, it indicates an ARM instruction; if the lowest bit is 1, it indicates a Thumb instruction. The Cortex-M core does not support ARM mode, and forcing a switch to ARM mode will trigger a Hard Fault.
Finally, let’s write a small program to verify the above analysis. This program is based on the STM32F4 series microcontroller and is intended to make the PA0 pin output a high level. This should also be the simplest implementation to achieve this goal.
rAHB1ENR        EQU     0x40023830AHB1ENRValue    EQU     0x00000001    rMODER          EQU     0x40020000MODERValue      EQU     0xA8000001    rODR            EQU     0x40020014ODRVaule        EQU     0x00000001
    AREA RESET, DATA, READONLY    DCD 0x00000400    DCD Start
    AREA |.text|, CODE, READONLY    ENTRY
Start    LDR R0, =rAHB1ENR    LDR R1, =AHB1ENRValue    STR R1, [R0]        LDR R0, =rMODER    LDR R1, =MODERValue    STR R1, [R0]        LDR R0, =rODR    LDR R1, =ODRVaule    STR R1, [R0]
    B .      END
The 11th line uses the DCD pseudo-instruction to allocate 4 bytes of storage space and sets its value to 0x0000_0400; the 12th line similarly places the address of the Start label at an offset of 4 bytes. The part after the Start label is the main program, which sequentially enables the RCC clock for GPIOA, sets PA0 to output mode, and sets PA0 high.
During linking, the RESET section will be placed at the beginning of the target file, so the data at address 0x0000_0000 will be 0x0000_0400, and the data at address 0x0000_0004 will be the entry address of the Start section.
However, it should be noted that in the STM32F4 chip, the internal Flash address starts from 0x0800_0000, and when the BOOT pin is set for Flash startup, the chip will automatically map the area from 0x0000_0000 to 0x000F_FFFF to the area from 0x0800_0000 to 0x080F_FFFF, making them equivalent.
Using Debug mode for debugging, the values of the CPU registers after reset are as follows:
Analyzing the Reset Startup Process of ARM Cortex-M Core
The data in Flash is as shown:
Analyzing the Reset Startup Process of ARM Cortex-M Core
As can be seen, the compiler intelligently sets the data at 0x0800_0004 to 0x0800_0009 instead of the actual address value of the Start label, indicating that this is a Thumb-2 instruction. After reset, the value in the PC is 0x0800_0008, and the value in the SP is 0x0000_0400, which is completely as expected.
Finally, it should be mentioned that the simple program above has an issue; in fact, the program portion after the Start label occupies the space of the interrupt vector table. This is not a problem when no exceptions occur, but if an exception does occur, the program execution will obviously fail.
Source: https://gaomf.cn/2016/04/27/ARM%20Cortex-M内核复位启动过程分析

Leave a Comment

×