18.2.3 Initialize Stack Pointer and Heap
The Stack Pointer (sp
) register must be initialized in the
start-up code. To enable the start-up code to initialize the sp
register, the linker must initialize a variable which points to the end of KSEG0/KSEG1
data memory.
The linker allocates the stack to KSEG0 on devices featuring an L1 data cache. It allocates the stack to KSEG1 on devices that do not have an L1 cache.
This variable is named _stack
. The user can change the
minimum amount of stack space allocated by providing the command line option
--defsym _min_stack_size=N
to the linker.
_min_stack_size
is provided by the linker script with a default
value of 1024
. On a similar note, the user may wish to utilize a heap
with their application. While the start-up code does not need to initialize the heap,
the standard C libraries (sbrk
) must be made aware of the heap location
and its size. The linker creates a variable to identify the beginning of the heap. The
location of the heap is the end of the utilized KSEG0/KSEG1 data memory.
The linker allocates the heap to KSEG0 on devices that have an L1 cache. It allocates the heap to KSEG1 on devices that do not have an L1 cache.
This variable is named _heap
. A user can change the minimum amount of
heap space allocated by providing the command line option
--defsym=_min_heap_size=M
to the linker. If the heap is
used when the heap size is set to zero, the behavior is the same as when the heap usage
exceeds the minimum heap size. Namely, it overflows into the space allocated for the
stack.
The heap and the stack use the unallocated KSEG0/KSEG1 data memory, with the heap starting from a low address in KSEG0/KSEG1 data memory, and growing upwards towards the stack while the stack starts at a higher address in KSEG1 data memory and grows downwards towards the heap. The linker attempts to allocate the heap and stack together in the largest gap of memory available in the KSEG0/KSEG1 data memory region. If enough space is not available based on the minimum amount of heap size and stack size requested, the linker issues an error.
The linker must then group all of the above input sections together. This
grouping is handled by the default linker script. The run-time start-up code must
initialize the gp
register to point to the “middle” of this output
section. To enable the start-up code to initialize the gp
register, the
linker script must initialize a variable which is 32 KB from the start of the output
section containing the “small” variables and constants. This variable is named
_gp
(to match core linker scripts). Besides being initialized in
the standard GPR set, the Global Pointer must also be initialized in the register shadow
set.