----------------------------------------------------------------------------------------------------------
Author :tiger-john(冀博)
WebSite :blog.csdn.net/tigerjb
Email :jibo.tiger@gmail.com
Tiger声明:本人不排斥别人转载tiger-john的文章,只是请您注明出处3Q
---------------------------------------------------------------------------------------------------
一.RVDS startup flow
In RVDS compiler environment, an initialization sequence executes to set up the system before the main task is executed.
The Figure 1[1] shows the default initialization sequence (use BL __main method)
Figure 1 the default initialization sequence
The reset handler executes immediately on system startup. The block of code labeled $$Sub$$main executes immediately before the main application.
First: The reset handler is a short module coded in assembler that is executed on system reset. As a minimum, we must reset handler initializes stack pointers for the modes that your application is running in by ourselves.
Second: the reset handler typically branches to __main to begin the C library initialization sequence. __main branches directly to __scatterload. __scatterload is responsible for setting the runtime image memory map, whereas __rt_entry (runtime entry) is responsible for initializing the C library.
(1) __scatterload carries out code and data copying, decompression of RW data if necessary, and zeroing of ZI data.
(2) __scatter load branches to __rt_entry. This sets up the application stack and heap. So we can must implementation __user_initial_stackheap. If we don’t implement __user_initial_stackheap function, or the system raise error message: undefined symbol Image$$Limit (refer from sys_stackheap.o). Then initializes library functions and their data, and calls any constructors of global declared objects (this is only use C++ only)
(3)__rt_entry then branches to main () that is entry to our application. When the main application has finished executing, __rt_entry shuts down the library, then hands control back to the debugger.
Note:
(1)If we use BL __main, the RVDS compiler auto realize to copy data to memory and initialize ZI data of zero ,not we implement by ourselves. And, if use BL __main, the function main () has a special significance. The presence of a main () function forces the linker to link in the initialization code in __main and __rt_entry. Without a function labeled main () the initialization sequence is not linker in, and as a result, some standard C library functionality is not supported.
(2) If we use BL main, we must implement copy data to memory and initialize ZI data of zero. In this method, the application code entry label is arbitrary character. Only BL Label the same is function Label.
(3) In the GUN compiler environment the system can’t auto copy data to memory and initialize ZI data of zero. This usage of it is more closed to the second, but they have some slight difference.
二. RVDS startup project of Error message
In this section, during write startup project base on bare-metal using RVDS compiler environment I faced some errors message, analyzing the reasons and raising the method of avoiding and modifying these errors. For more details please check in startup project code.
1. Error message: startup.o (vectors) contains invalid call from ‘~PRES8’ function to ‘REQ8’ function serial_init.
(1) Error reason: This linker error is given where a stack alignment conflict is detected in object code. The “ABI for the ARM Architecture” demands that code maintains 8~bytes stack alignment at its interfaces. This allows efficient use of LDRD and STRD instructions (in ARM Architecture 5TE and later) to access 8-byte-aligned “double” and “long long” data types. Symbols like ‘~PRES8’ and ‘REQ8’ are “Build Attributes” of the objects. PRES8 means the object PRESERVES 8~byte alignment of the stack. ~PRES8 means the object REQuires 8-byte alignment of the stack. ~PRES8 means the object REQuires 8-byte alignment of the stack [2].
(2) Solution: Add ‘PRESERRVE8’ directive to the top of each assembler file.
PRESERVE8
AREA TEXT, CODE, READONLY
CODE32
2. Error message: Undefined symbol Image$$ZI$$Limit (referred from sys_stackheap.o)
(1) Error reason: Because the default implementation uses Image$$ZI$$Limit, you must re-implement __user_initial_stackheap (). The following error message is displayed from the linker: Undefined symbol Image&&ZI$$Limit (referred from sys_stackheap.o) [3]
(2)Solution: Re-implement the __user_initial_stackheap ()
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR r0, =bottom_of_heap
MOV pc, lr
AREA Heap, DATA, NOINIT
bottom_of_head SPACE 1
Reference:
1. RealView® Compilation Tools Version 2.2 Developer Guide
2. ARM Web Error link: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0437a/index.html
3. RealView® Compilation Tools Version 2.2 Linker and Utilities Guide