| ARM Technical Support Knowledge Articles | |
Applies to: ARM Developer Suite (ADS), RealView Developer Kit (RVDK) for OKI, RealView Developer Kit for XScale (RVXDK), RealView Development Suite (RVDS)
If you have legacy source code you might see __user_initial_stackheap(), which sets up and returns the locations of the initial stack and heap. This is an old function that is only supported for backwards compatibility with legacy source code. The modern equivalent is __user_setup_stackheap(), which is available in RVDS 3.x and later. We recommened that you upgrade your source code to use __user_setup_stackheap() instead of __user_initial_stackheap(). For more information on __user_setup_stackheap() please see the section 2.10.4 '__user_setup_stackheap()' from the RVCT Libraries and Floating Point Support Guide. If it is not possible to upgrade your source code, then please read the relevant section below.
ADS 1.1 and earlier
The C library initialization code uses the linker symbol Image$$ZI$$Limit by default as the address of the base of the heap.
Unfortunately, when using scatter-loading with ADS 1.1 and earlier, the linker will set Image$$RW$$Limit to 0, which results in the heap being placed at the (usually inappropriate) address of 0x0. Subsequent use of the heap, either directly (e.g. with malloc()) or indirectly (by use of argc/argv), may corrupt the vector table and/or other code, typically resulting in unpredictable program failure at run time.
To prevent this, you must provide your own implementation of __use_initial_stackheap() to set the correct addresses for the stack base and heap base. At link-time, your function will then be linked into the image instead of the C-library's default implementation, which uses SWI SYS_HEAPINFO (0x16).
Example implementations in C and assembler (for the One Region Model) are shown below.
1. To place the application stack and heap at specific addresses:
#include <rt_misc.h>
__value_in_regs struct __initial_stackheap __user_initial_stackheap(unsigned R0, unsigned SP, unsigned R2, unsigned SL)
{
struct __initial_stackheap config;
config.stack_base = 0x00080000;
config.heap_base = 0x00060000;
return config;
}
2. To place the heap directly above a ZI region (and inherit the stack base from the execution environment):
IMPORT ||Image$$region_name$$ZI$$Limit||
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR r0, =||Image$$region_name$$ZI$$Limit||
MOV pc, lr
where region_name is the name of an execution region as defined in your scatter-loading description file.
ADS 1.2 and RVDS 2.x
In ADS 1.2 and later, the default implementation of __user_initial_stackheap() has been changed to use the value of the symbol Image$$ZI$$Limit instead of Image$$RW$$Limit. These symbols have the same value. The change was made for the sake of clarity. Section-related symbols like Image$$ZI$$Limit are left undefined when using scatter-loading. If you see the linker error:
Error: L6218E: Undefined symbol Image$$ZI$$Limit (referred from sys_stackheap.o)
... you must provide a reimplemention of __user_initial_stackheap() to set the heap and stack boundaries.
RVDS 3.x and later
In RVDS 3.x and later, the library includes more implementations of __user_initial_stackheap(), and can select the correct implementation for you automatically from information given in a scatter-loading description file. This means that it is not always necessary to reimplement this function if you are using scatter-loading files.
For more details on __user_initial_stackheap(), please refer to your toolkit's documentation, and the retarget.c file found within the Examples directory of your toolkit.
Article last edited on: 2009-07-06 09:29:27
Did you find this article helpful? Yes No
How can we improve this article?