Analysis of ARM Cortex-M Core Reset Boot Process

Click the blue “Linux Talk” above and select “Set as Favorite
Get the latest articles first
Analysis of ARM Cortex-M Core Reset Boot Process
1

The reset boot 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 boot 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 start running from the first instruction obtained at 0x0000_0000 after a reset, however, this is not the case for the ARM Cortex-M core. Its reset sequence is:

1. Get the initial value of MSP from address 0x0000_0000;

2. Get the initial value of PC from address 0x0000_0004, and then fetch the instruction from the address corresponding to this value.

As shown in the figure below:

Analysis of ARM Cortex-M Core Reset Boot Process

In fact, the default interrupt vector table starts at address 0x0000_0004 (some materials consider the initial value of the MSP pointer at address 0x0000_0000 as part of the interrupt vector table, which seems inappropriate). The layout of the interrupt vector table for the ARM Cortex-M core is shown in the figure below:

Analysis of ARM Cortex-M Core Reset Boot Process

Note: The location of the interrupt vector table can be changed; this is the default setting.

It is worth noting that in the ARM Cortex-M core, after an exception occurs, it does not execute the code at the corresponding position in the interrupt vector table, but instead stores the data at that position into PC, and then fetches the instruction from that address. In short, the interrupt vector table of the ARM Cortex-M should not contain jump instructions, but should contain the entry addresses of ISR programs.

With the above analysis, it is easy to understand the reset sequence. The reset is actually equivalent to an occurrence of a Reset exception, and as can be seen from the figure, the data stored at address 0x0000_0004 is exactly the entry address of the interrupt handler corresponding to the Reset exception.

Additionally, there are two detailed issues that need to be noted:

<span>1. </span><span>0x0000_0000</span> stores the initial value of MSP, and the lowest three bits must be 0;

2. 0x0000_0004 must store an address whose lowest bit must be 1.

The first issue is due to the ARM AAPCS convention 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 convention stipulates that the stack must always be 4-byte aligned, and must be 8-byte aligned at the entry point, and the lowest two bits of SP are set to 0 at the hardware level.

The second issue relates to the ARM and Thumb modes. In ARM, the address in PC must be 32-bit aligned, and its lowest two bits are also set to 0 at the hardware level, thus the lowest two bits of the data written to PC do not represent the actual addressing address. The lowest bit is used in ARM to determine whether the instruction is an ARM instruction or a Thumb instruction; if the lowest bit is 0, it represents an ARM instruction; if the lowest bit is 1, it represents a Thumb instruction. In the Cortex-M core, ARM mode is not supported, and forcing a switch to ARM mode will trigger a Hard Fault.

Finally, let’s write a small program to validate the above analysis. This program is based on the STM32F4 series microcontroller, and its purpose is to set the PA0 pin to high. This should also be the most concise way to achieve this goal.

rAHB1ENR        EQU     0x40023830
AHB1ENRValue    EQU     0x00000001

rMODER          EQU     0x40020000
MODERValue      EQU     0xA8000001

rODR            EQU     0x40020014
ODRVaule        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

Line 11 uses the DCD pseudo-instruction to allocate 4 bytes of storage space and sets its value to 0x0000_0400; line 12 similarly places the address of the Start label at an offset of 4 bytes; line 17 and the following part after the Start label is the main part of the program, which sequentially completes the steps of enabling the RCC clock for GPIOA, setting PA0 to output mode, and setting PA0 high.

During linking, the RESET section will be placed at the beginning of the target file, thus the data at address 0x0000_0000 is equivalent to 0x0000_0400, and the data at address 0x0000_0004 is the entry address of the Start part.

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 to Flash boot, the chip will automatically map the area 0x0000_0000 0x000F_FFFF to 0x0800_0000 0x080F_FFFF, at which point they can be regarded as equivalent.

Using Debug mode for debugging, the values of the CPU registers after reset are as follows:

Analysis of ARM Cortex-M Core Reset Boot Process

The data in Flash is shown in the figure:

Analysis of ARM Cortex-M Core Reset Boot Process

It can be seen that the compiler intelligently sets the data at 0x0800_0004 to 0x0800_0009, rather than the real address value of the Start label, which indicates that this is a Thumb-2 instruction. After reset, the value in PC is 0x0800_0008, and the value in SP is 0x0000_0400, which completely matches the expected result.

Finally, it is worth mentioning that the above simple program has a problem: the program in the Start part actually occupies the space of the interrupt vector table, which is not an issue when no exceptions occur, but once an exception occurs, the program execution will obviously go wrong.

Original: https://gaomf.cn/2016/04/27/ARM%20Cortex-M%20Core%20Reset%20Boot%20Process%20Analysis/

Author: Gao Mingfei

Analysis of ARM Cortex-M Core Reset Boot Process

Follow the WeChat official account “Linux Talk” and click “About Linux Talk” in the background to add the author’s WeChat.

Previous Recommendations

Still don’t know when to use UART, I2C, SPI protocols? This article will thoroughly explain!

Introducing a very useful Linux command, hurry up and use it!

How do bugs occur?

Detailed explanation | How the Linux driver entry function module_init is called

Leave a Comment