Analysis of ARM start process and start code

Posted by nassertx on Wed, 08 Apr 2020 09:01:44 +0200

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

Topics: Assembly Language