A deep analysis of _c language based on C program startup code

Source: Internet
Author: User
first, the basic composition of the image file
The image file loading time domain includes the RO and RW segments, while the runtime domain includes the RO, rw, and Zi three segments. Where the RO and RW segments contentIn load time and run timeis the same, but the storage space may be different, The zi segment is created by the initialization function at run time.
RO segment: Read-only section, including the source program Code Segmentread-only data segments(including initialization of variables valueCan be any variable, the initial value of global/local, static/dynamic variables, and also include data constants--this constant can also be global or local. That is, the compiler is meant to variable allocation storage spaceVariable is read-write, not in the RO section, but also for initial allocation of variables to storage space, they are two different things).
RW section: can read and write section, mainly refers to Rw-data, may also have Rw-code。 Rw-data refers to the already the global variable that is initialized.
Zi segment: zero-initialized segment, which includes uninitialized global variables, is initialized by the compiler with a value of 0. The data in this section is also writable because it is a variable, but it does not allocate storage space for the ZI segment when the image file is loaded, although the total RW Size = (rw data + ZI data) is considered in the memory map file of the ads compiler.

location of code, data and variables in the image file
It briefly summarizes the composition of each segment of the image file. From the composition of the program, can be divided into variables, data and code, where the variables are divided into global/local or static/dynamic, their storage space is how to allocate it?
code: Generally read-only, the compiler allocates storage space and puts it in the RO segment of the image file.
data: The data here refers to constants(if variable is a variable), also include Pointer Constants, then Also data that belongs to read-only, and the compiler allocates storage space to the RO segment of the image file.
Variables: primarily based on the lifetime, because the lifetime is defined in memory, and the scope is independent of the storage space allocation.
1. Global variables and static variables: including static local variables and global/static pointer variable, the compiler allocates storage space, initialized to the RW section, otherwise put to zi paragraph;
2. Dynamic variables: Mainly refers to local variables, including local pointer variables, function parameters, return values, etc., occupy the stack space.

third, the stack initialization in the start-up process of explanation
Heap and stack: for ARM, the heap is growing upward and the stack is growing downward.
The local variable occupies the stack space (but its initialization value is data and occupies the RO space);
The memory space (heap) space that is applied dynamically in the program, such as malloc () and the new function request.
———— x The following discussion does not use the semihosting mechanism x ————
Therefore, before you transfer to the C application, you must prepare the stack space for the C program. Depending on the storage resources of the target platform, the initialization function of the stack (__USER_INITIAL_STACKHEAP) is migrated, primarily by properly setting up the heap (heap) and stack (stack) addresses. It can be written using either C or ARM assembly language, and at least a heap base address (saved in R0), and a stack base address (saved in R1) is optional. Thus a simple assembly language written by the __user_initial_stackheap () function is as follows:
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDRR0, =0x20000; Heap base
LDRR1, =0x40000 stack base, optional
MOV PC, R14
Note that if you do not customize this function in the project, by default the compiler/linker will put | image$ $ZI $ $Limit | As the base address of the heap (heap) (that is, placing the heap and stack areas above the ZI area is also considered the standard implementation [7]). However, if you implement a decentralized loading mechanism using the scatter file, the linker does not generate symbols | image$ $ZI $ $Limit |, then you must implement the __user_initial_stackheap () function again and set the heap base address and top of the stack, otherwise the link will be an error.
The stack area is also divided into a single region model and a two-zone model, in which the stack limit [4,6,7] must also be set.
A few things to note about redefining the __user_initial_stackheap () function: One is not to use stack over 96 bytes, the other is to not affect R12 (IP, as a staging register for interprocess calls), and three is to return parameter values by rule (r0:heap Base;r1:stack base;r2:heap limit;r3:stack limit), four is to keep the heap area 8 bytes aligned [6].

In the startup code, you also initialize the stack pointers for each processor mode. This problem is easily confused with the role of the __user_initial_stackheap () function mentioned above. The following points can be explained:
(1) In the embedded application, the startup code is divided into two parts: first, the initialization of the system, including the establishment of interrupt vector table, clock, storage system initialization, critical I/O port initialization, stack pointer initialization in each processor mode, etc. the second is the initialization of the application (or C library function initialization), Includes the removal of the RW section and the establishment of the Zi 0, C application Stack area (__user_initial_stackheap () function initialization stack pointer), and so on.
In this sense, there is no direct relationship between the two.
(2) But the two are not without contact. Take the stack area of a single area model as an example, because the stack is growing downward, the heap is growing up, the system pattern stack pointer (same as user mode, shared by a R13 register) actually defines the upper bound of the single area model stack area in user mode, while the __user_initial_stackheap () The heap base address specified in the function becomes the lower bound of the stack area.
Therefore, if you have previously initialized the stack pointer for system mode (user mode), you do not need to redefine stack base when you redefine the __user_initial_stackheap () function.

Iv. discussion on the content and initialization sequence of startup code
As noted earlier, the startup code includes two parts of system initialization and initialization of the application's operating environment, and when initialized, the user main program can be called. References [1], [3], and [5], and so on, List a very clear but straightforward step for the content and process of two sections, which is a little abstract for beginners.
If you do not need to use MMU for address remapping, it is easier to understand the combination of sample boot code that can be collected on the web, as well as analysis documents, plus your own hands-on porting and debugging. If you are using the processor's own remap control registers for address remapping, there are related code online, such as the User TwentyOne boot code "4510 bootloader Implementation and analysis (source code)" is very clear, in addition, in the "Arm study report" A detailed analysis is also available in the series of articles.
For the sequence of system initialization to use MMU for address remapping during startup, a reference step is given in the paper "Using Axd Debug MMU address mapper (ii)", and some explanations are made. By further reference to authoritative information, here, the system initialization sequence has been improved and amended as follows:
① disables all interrupts →② initialization clock →③ initialization memory →④ initialize the stack pointer in various modes →⑤ initialize Gpio→⑥ copy image file to Sdram→⑦ create address remapping table →⑧ enable Mmu→⑨ application initialization (rw& Zi zone) →⑩ enable abnormal interrupt →⑾ call main program (Dummyos).
It mainly adjusts the order of abnormal interrupt and application initialization, that is, initialize the application first, and then interrupt the program unexpectedly.
......
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.