1, ARM startup process
Most of the chips based on ARM are complex on-chip systems. Most of the hardware modules in this complex system are configurable. It is up to the software to set the required working state. Therefore, before the user's application, a special piece of code is needed to complete the initialization of the system. Because this kind of code is directly used to program the processor core and hardware controller, it usually uses assembly language. General contents include:
Interrupt vector table
Initialize the memory system
Initial Stack
Initialize ports and devices with special requirements
Initialize user program execution environment
Change processor mode
Call home application
2, ARM startup file
Taking stm32 startup file as an example, stm32 startup file is generally included in the assembly file (. s file) of a specific single-chip computer model. The figure below is a brief description of the startup file
As we expected, the startup file mainly includes initialization stack, initialization program pointer (PC), initialization interrupt vector table, configuration of system clock and external Sram (optional), jump to main function
3, Specific analysis of startup file code
The first part is to configure the stack size heap size, as shown in the figure above
AREA STACK, NOINIT, READWRITE, ALIGN=3; define stack, which can be initially 0, 8-byte aligned (heap code similar to the same function)
Stack? MEM space stack? Size; allocates 0x400 consecutive bytes and initializes to 0 (heap code similar to the same function)
__Initial? Sp; assembly code address label (heap code similar to the same function)
PRESERVE8; specifies the 8-byte alignment of the current file stack
Thumb; tells the assembler that the following is the Thumb instruction for 32, and if necessary, the assembler will insert bits to ensure alignment
The second part defines interrupt vector table
AREA RESET, DATA, READONLY ;Define reset vector segment, read only EXPORT __Vectors ;Define a global label that can be used in other files. Interrupt address here __Vectors DCD __initial_sp ; to__initial_sp distribution4byte32Address of bit0x0 DCD Reset_Handler ; Give label Reset Handler The assigned address is0x00000004 DCD NMI_Handler ; Give label NMI Handler Allocation address0x00000008 DCD HardFault_Handler ; Hard Fault Handler DCD ...... __Vectors_End
[note] DCD means to allocate a memory unit and initialize it with the instruction data
The third part: definition of reset'handler and false exception handler
AREA |.text|, CODE, READONLY; the code segment is defined as read-only
Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main LDR R0, =SystemInit //Load the address of SystemInit into register R0. BLX R0 //Program jump to address execution program in R0 LDR R0, =__main //Load the address of main into register R0 BX R0 //The program jumps to the address in R0 to execute the program, and then goes to the well-known C world. ENDP //Indicates the end of a subroutine
//PROC defines a subroutine called reset'handler
//EXPORT means that the subroutine reset? Handler can be called by other modules
//The keyword [WEAK] indicates a WEAK definition. If the compiler finds that a function with the same name is defined elsewhere, it links it with the address elsewhere. If there is no definition elsewhere, the compiler does not report an error, and links it with the address here.
//IMPORT informs the compiler that the label to be used is in another file
//SystemInit is a function provided by the runtime library to complete system initialization
//__main is the function provided for runtime library to complete stack initialization
Other interrupt handling subroutines are called Dummy Exception Handlers. By default, a loop can be redefined
NMI_Handler PROC EXPORT NMI_Handler [WEAK] B . //Jump in place (dead cycle) ENDP
Part 4 initialization of heap and stack
IF :DEF:__MICROLIB //Usage of "DEF" -: DEF:X means that if x is defined, it is true; otherwise, it is false / / the compile option of MICROLIB indicates whether the C library of MICROLIB is used instead of the standard C library EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap __user_initial_stackheap LDR R0, = Heap_Mem //R0 address points to heap start address LDR R1, =(Stack_Mem + Stack_Size) //R1 address points to the highest address of the stack LDR R2, = (Heap_Mem + Heap_Size) //R2 address points to the highest address of the heap LDR R3, = Stack_Mem //R1 address points to the starting address of the stack BX LR ALIGN ENDIF END