AnsweredAssumed Answered

Linker Script , optimisation

Question asked by guif on Feb 28, 2014
Latest reply on Mar 3, 2014 by sung.chen_chung
Hello,

I would like to be sure I understand the linker script that I am using.
My main question is : the code is it copy to RAM before to be executed?  I think It's not the case, because the code is .text section, that is just copy to FLASH with >FLASH. 
(the linker script is a copy from ST source + some modifications )
001./*
002.*****************************************************************************
003.**
004.**  File        : stm32_mdp.ld
005.**
006.**  Abstract    : Linker script for stm32l1xx_mdp Device
007.**
008.**                Set heap size, stack size and stack location according
009.**                to application requirements.
010.**
011.**                Set memory bank area and size if external memory is used.
012.**
013.**  Target      : STMicroelectronics STM32
014.**
015.****  Distribution: The file is distributed �as is,� without any warranty
016.**                of any kind.
017.**
018.**  (c)Copyright Atollic AB.
019.**  You may use this file as-is or modify it according to the needs of your
020.**  project. Distribution of this file (unmodified or modified) is not
021.**  permitted. Atollic AB permit registered Atollic TrueSTUDIO(R) users the
022.**  rights to distribute the assembled, compiled & linked contents of this
023.**  file as part of an application binary file, provided that it is built
024.**  using the Atollic TrueSTUDIO(R) toolchain.
025.**
026.*****************************************************************************
027.*/
028. 
029./* Entry Point */
030.ENTRY(Reset_Handler)
031. 
032./* Highest address of the user mode stack */
033._estack = 0x20008000;    /* end of 32K RAM */
034.__ICFEDIT_region_RAM_end__ = _estack;
035. 
036./* Generate a link error if heap and stack don't fit into RAM */
037._Min_Heap_Size = 0;      /* required amount of heap  */
038._Min_Stack_Size = 0x200;  /* required amount of stack */
039. 
040./* Specify the memory areas */
041.MEMORY
042.{
043.  FLASH (rx)      : ORIGIN = 0x00000000, LENGTH = 256K /*- 0x3000*/
044.  RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 32K
045.  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K
046.}
047. 
048./* Define output sections */
049.SECTIONS
050.{
051.  /* The startup code goes first into FLASH */
052.  .isr_vector :
053.  {
054.    . = ALIGN(4);
055.    KEEP(*(.isr_vector)) /* Startup code */
056.    . = ALIGN(4);
057.  } >FLASH
058. 
059.  /* The version number is placed before the beginning of code */
060.  .nb_version :
061.  {
062.    . = ALIGN(4);
063.    KEEP(*(.nb_version)) /* KEEP the  variable even if not referenced */
064.    . = ALIGN(4);
065.  } >FLASH
066.   
067.  /* The program code and other data goes into FLASH */
068.  .text :
069.  {
070.    . = ALIGN(4);
071.     _stext = .;        /* define a global symbols at start of code */
072. 
073.    *(.text)           /* .text sections (code) */
074.    *(.text*)          /* .text* sections (code) */
075.    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
076.    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
077.    *(.glue_7)         /* glue arm to thumb code */
078.    *(.glue_7t)        /* glue thumb to arm code */
079.    *(.eh_frame)
080. 
081.    KEEP (*(.init))
082.    KEEP (*(.fini))
083. 
084.    . = ALIGN(4);
085.    _etext = .;        /* define a global symbols at end of code */
086.  } >FLASH
087. 
088.  __checksum = _stext;
089.__end_of_code = _etext;
090. 
091.   .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
092.    .ARM : {
093.    __exidx_start = .;
094.      *(.ARM.exidx*)
095.      __exidx_end = .;
096.    } >FLASH
097. 
098.  .preinit_array     :
099.  {
100.    PROVIDE_HIDDEN (__preinit_array_start = .);
101.    KEEP (*(.preinit_array*))
102.    PROVIDE_HIDDEN (__preinit_array_end = .);
103.  } >FLASH
104.  .init_array :
105.  {
106.    PROVIDE_HIDDEN (__init_array_start = .);
107.    KEEP (*(SORT(.init_array.*)))
108.    KEEP (*(.init_array*))
109.    PROVIDE_HIDDEN (__init_array_end = .);
110.  } >FLASH
111.  .fini_array :
112.  {
113.    PROVIDE_HIDDEN (__fini_array_start = .);
114.    KEEP (*(.fini_array*))
115.    KEEP (*(SORT(.fini_array.*)))
116.    PROVIDE_HIDDEN (__fini_array_end = .);
117.  } >FLASH
118. 
119.  /* used by the startup to initialize data */
120.  _sidata = .;
121. 
122.  /* Initialized data sections goes into RAM, load LMA copy after code */
123.  .data : AT ( _sidata )
124.  {
125.    . = ALIGN(4);
126.    _sdata = .;        /* create a global symbol at data start */
127.    *(.data)           /* .data sections */
128.    *(.data*)          /* .data* sections */
129. 
130.    . = ALIGN(4);
131.    _edata = .;        /* define a global symbol at data end */
132.  } >RAM
133.__ICFEDIT_region_RAM_end__ = _edata; /* used to check the RAM used */
134. 
135.  /* Uninitialized data section */
136.  . = ALIGN(4);
137.  .bss :
138.  {
139.    /* This is used by the startup in order to initialize the .bss secion */
140.    _sbss = .;         /* define a global symbol at bss start */
141.    __bss_start__ = _sbss;
142.    *(.bss)
143.    *(.bss*)
144.    *(COMMON)
145. 
146.    . = ALIGN(4);
147.    _ebss = .;         /* define a global symbol at bss end */
148.    __bss_end__ = _ebss;
149.  } >RAM
150. 
151.  PROVIDE ( end = _ebss );
152.  PROVIDE ( _end = _ebss );
153. 
154.  /* User_heap_stack section, used to check that there is enough RAM left */
155.  ._user_heap_stack :
156.  {
157.    . = ALIGN(4);
158.    . = . + _Min_Heap_Size;
159.    . = . + _Min_Stack_Size;
160.    . = ALIGN(4);
161.  } >RAM
162. 
163.  /* MEMORY_bank1 section, code must be located here explicitly            */
164.  /* Example: extern int foo(void) __attribute__ ((section (".mb1text"))); */
165.  .memory_b1_text :
166.  {
167.    *(.mb1text)        /* .mb1text sections (code) */
168.    *(.mb1text*)       /* .mb1text* sections (code)  */
169.    *(.mb1rodata)      /* read-only data (constants) */
170.    *(.mb1rodata*)
171.  } >MEMORY_B1
172. 
173.  /* Remove information from the standard libraries */
174.  /DISCARD/ :
175.  {
176.    libc.a ( * )
177.    libm.a ( * )
178.    libgcc.a ( * )
179.  }
180. 
181.  .ARM.attributes 0 : { *(.ARM.attributes) }
182.}


And the gcc startup code  just copies the .data section to RAM, but does'nt copy the .text to RAM.(line 16)
01.    .section .text.Reset_Handler
02.  .weak Reset_Handler
03.  .type Reset_Handler, %function
04.Reset_Handler:
05. 
06./* Copy the data segment initializers from flash to SRAM */ 
07.  movs r1, #0
08.  b LoopCopyDataInit
09. 
10.CopyDataInit:
11.  ldr r3, =_sidata
12.  ldr r3, [r3, r1]
13.  str r3, [r0, r1]
14.  adds r1, r1, #4
15.     
16.LoopCopyDataInit:
17.  ldr r0, =_sdata
18.  ldr r3, =_edata
19.  adds r2, r0, r1
20.  cmp r2, r3
21.  bcc CopyDataInit
22.  ldr r2, =_sbss
23.  b LoopFillZerobss
24./* Zero fill the bss segment. */ 
25.FillZerobss:
26.  movs r3, #0
27.  str r3, [r2], #4
28.     
29.LoopFillZerobss:
30.  ldr r3, = _ebss
31.  cmp r2, r3
32.  bcc FillZerobss
33./* Call the application's entry point.*/
34.  bl main
35.  bx lr
36..size Reset_Handler, .-Reset_Handler


I would like to confirm with you that my code is not running from RAM but it's running from Flash.
If it's the case, I can optimize the speed of my application!

Thank you very much for your help,

Outcomes