In-depth analysis of C program startup code

Source: Internet
Author: User

I. Basic composition of image files
The image file loading time domain includes RO and RW segments, and the operation time domain includes RO, RW, and ZI segments. Where RO and RW ContentIn Loading and runningThey are the same, but the storage space may be different, The ZI segment is created by the initialization function at runtime.
RO: Read-Only, including CODE segment, Read-only data segment(Including variable Initialization Value-- It can be an arbitrary variable, the initial values of global/local and static/dynamic variables, or a data constant -- this constant can also be global or local. That is to say, the compiler must Variable Allocation storage space-- The variable is read-write and not in the RO segment. Variable initial value allocation storage space).
RW segment: Read/write segments, mainly RW-DATA, or RW-CODE. RW-DATA refers to already The initialized global variable.
ZI segment: Zero-Initialized segment, mainly including uninitialized global variables. The Compiler initializes them with 0 values. The data in this section is variable and can be read and written. However, when the image file is loaded, it does not allocate storage space for the ZI segment, although the Memory map file of the ADS compiler considers Total RW Size = (RW Data + ZI Data ).

Ii. Code, data and variable location in the Image File
The above briefly summarizes the composition of each segment of the image file. From the perspective of program composition, it can be divided into variables, data and code. Among them, variables are divided into global/local or static/dynamic. how are their buckets allocated?
Code: Read-OnlyThe compiler allocates the storage space and places it in the RO segment of the image file.
Data: The data mentioned here is a constant.(If it is variable, it is a variable), includingPointer constant, ThenRead-only dataThe compiler also allocates storage space to the RO segment of the image file.
Variable: mainly based on the lifetime, because the lifetime is defined according to the memory survival time, And the scope is irrelevant to the storage space allocation.
1. Global variables and static variables: including static local variables and global/static pointer variables, the compiler allocates storage space, initialized to the RW segment, or else to the ZI segment;
2. dynamic variables: local variables, including local pointer variables, function parameters, and return values, occupy the stack space.

Iii. Stack initialization during startup
Heap and stack: For ARM, the heap grows up and the stack grows down.
Local variables occupy the stack space (but the initial value is data, occupying the RO space );
The memory space applied by the dynamic applications such as malloc () and new functions occupies heap space.
---- × The following discussion does not use the semihosting mechanism × ----
Therefore, the stack space must be prepared for the C program before it is transferred to the C application. According to the memory resources of the target platform, the initialization function _ user_initial_stackheap () of the stack should be transplanted, mainly to set the heap and stack addresses correctly. It can be written in C or ARM assembly language, and at least the heap base address (saved in R0) is returned. The stack base address (saved in R1) is optional. Therefore, the _ user_initial_stackheap () function written in a simple assembly language is as follows:
EXPORT _ user_initial_stackheap
_ User_initial_stackheap
LDRR0, = 0x20000; heap base
LDRR1, = 0x40000; stack base, optional
Mov pc, R14
Note: If this function is not customized in the project, the compiler/Linker will use | Image $ ZI $ Limit | as heap by default) (that is, the heap and stack areas are placed above the ZI area, which is also considered a standard implementation [7]). However, if the scatter file is used to implement the Distributed Loading Mechanism, the linker does not generate symbols. | Image $ ZI $ Limit |, you must implement _ user_initial_stackheap () again () function and set the heap base address and stack top. Otherwise, an error will be reported during the connection.
Stack zones are also divided into single-zone models and dual-zone models. In a dual-zone model, you must set stack restrictions [, 7].
Note the following when redefining the _ user_initial_stackheap () function: First, do not use a stack with more than 96 bytes, and second, do not affect R12 (IP, used as a temporary register for inter-process calls. The third is to return the parameter values (R0: heap base; R1: stack base; R2: heap limit; R3: stack limit) according to the rule ), the fourth is to keep the heap area 8-byte aligned [6].

In the startup code, you also need to initialize the stack pointer of each processor mode. This problem is easily confused with the functions of the _ user_initial_stackheap () function mentioned above. You can describe the following points:
(1) In embedded applications, the startup code is divided into two parts: First, system initialization, including the establishment of the interrupt vector table, clock, storage system initialization, key I/O port initialization, and stack pointer initialization in various processor modes; the second is application initialization (or C library function initialization), including the moving of RW segments and clearing of ZI segments, and the establishment of C Application Stack (_ user_initial_stackheap () function initialization Stack pointer.
In this sense, the two are not directly related.
(2) but they are not unrelated. Taking the stack area of a single-zone model as an example, because the stack grows down, the stack grows up, and the stack pointer of the system mode (similar to the user mode, which is described by sharing an R13 register) actually, the upper limit of the model stack zone in the user mode is defined, and the base address specified in the _ user_initial_stackheap () function becomes the lower limit of the stack zone.
Therefore, if you have previously initialized the stack pointer in system mode (user mode), you do not need to redefine the stack base when redefining the _ user_initial_stackheap () function.

4. Content and initialization sequence of startup code
As mentioned above, the startup code includes system initialization and application program environment initialization. After initialization, you can call the user master program. References [1], [3], and [5] provide clear but simple steps for the content and process of the two parts, this is a little abstract for beginners.
If you do not need to use MMU for address re- ing, it is easier to understand the sample boot Code and analysis documents that can be collected on the Internet, and manually port and debug the code. If you use the Remap control register provided by the processor for address re ing, there are also related code on the Internet, such as the user's twentyone boot Code [4510 implementation and analysis of bootloader (with source code)] is very clear, in addition, in the ARM learning report series of articles also has a detailed analysis.
For the system initialization sequence in which MMU is used for address re ing during startup, a reference step is provided in the document "Debug MMU address ing program with AXD (2, and made some instructions. Through further reference to authoritative materials, we have made minor improvements and amendments to the system initialization sequence as follows:
① Prohibit all interruptions → ② initialize the clock → ③ initialize the memory → ④ initialize the stack pointer in each mode → ⑤ initialize GPIO → ⑥ copy the image file to the SDRAM → 7 → cancel enable MMU → initialize application (RW & ZI) → interrupt enabling exception → abort the call to the Master Program (dummyOS ).
It mainly adjusts the sequence of enabling abnormal interruptions and application initialization, that is, initializing the application before enabling abnormal interruptions.
......

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.