2025-12-17 1:39 AM
Hello,
In a typical example, there is the following linker script:
/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
:
:
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
On paper, the intention is the stack has an allocation of _Min_Stack_Size (0x400) bytes. So far so good.
However, the location _Min_Stack_Size seems to have nothing to do with _estack which the is actual address assigned to the MSP by the start-up code.
The map file shows that "stack" is located between 0x20000208 and 0x20000608.
._user_heap_stack
0x0000000020000004 0x604 load address 0x0000000008000c5c
0x0000000020000008 . = ALIGN (0x8)
*fill* 0x0000000020000004 0x4
[!provide] PROVIDE (end = .)
0x0000000020000008 PROVIDE (_end = .)
0x0000000020000208 . = (. + _Min_Heap_Size)
*fill* 0x0000000020000008 0x200
0x0000000020000608 . = (. + _Min_Stack_Size)
*fill* 0x0000000020000208 0x400
0x0000000020000608 . = ALIGN (0x8)
But the MSP is initialised to _estack which, in this case, is 0x2002 0000.
So my question is: If _Min_Stack_Size does not influence or limit the actual stack in practice, what purpose does _Min_Stack_Size serve in this script please?
Thank you.
2025-12-17 7:21 AM
> So my question is: If _Min_Stack_Size does not influence or limit the actual stack in practice, what purpose does _Min_Stack_Size serve in this script please?
The script ensures you have enough space for the stack. If you don't, the RAM region will overflow and the linker will fail.
The location of the stack always starts at the end.
> However, the location _Min_Stack_Size seems to have nothing to do with _estack which the is actual address assigned to the MSP by the start-up code.
This is true but irrelevant as the MSP always gets the same address regardless of stack size. Doing it this way gives the heap and stack as much free memory as possible before they collide, even if they exceed the minimums set.
2025-12-17 7:39 AM
Thank you but my point is that the memory area set aside by output section ._user_heap_section with _Min_Stack_Size (i.e. 0x20000208 to 0x20000608) is not the memory actually used for the stack.
The memory actually used for stack is _estack (i.e. 0x24048000) less 2k, for the sake of argument.
If the MSP were set to 0x20000608 in the start-up code this would make some sense but it isn't.
_Min_Stack_Size ensures nothing, hence the question.
2025-12-17 7:58 AM
> _Min_Stack_Size ensures nothing, hence the question.
Increase it to 1 MB and you will find otherwise.
2025-12-17 8:51 AM
After further thought, I concede that this is effective but only on the condition that nothing is located after .user_heap_stack. If another output section were located between .user_heap_stack and _estack then _Min_Stack_Size just serves to consume _Min_Stack_Size bytes and ensures nothing about the available stack size.
/* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* DO NOT locate symbols after ._user_heap_stack in RAM. */I think a comment as per line 12 above would be appropriate for anyone copying the example script to their application.