{"id":4484,"date":"2019-01-02T14:31:11","date_gmt":"2019-01-02T22:31:11","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=4484"},"modified":"2019-01-02T14:33:37","modified_gmt":"2019-01-02T22:33:37","slug":"understanding-gnu-linker-scripts","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/arm\/linkerscripts\/","title":{"rendered":"Customizing Memory Layout of Embedded Programs with GNU Linker Scripts"},"content":{"rendered":"<p>This tutorial shows how to use linker scripts to control the memory layout of your embedded programs. We will create a basic &#8220;Blinking LED&#8221; program, add a new global variable to it and will use the linker script to place this variable in several specific memory locations. Before you begin, install VisualGDB 5.3 or later.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Embedded Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/01-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4485\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/01-newprj.png\" alt=\"\" width=\"941\" height=\"653\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/01-newprj.png 941w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/01-newprj-300x208.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/01-newprj-768x533.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/01-newprj-392x272.png 392w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/01-newprj-130x90.png 130w\" sizes=\"(max-width: 941px) 100vw, 941px\" \/><\/a><\/li>\n<li>Proceed with creating a new MSBuild-based project: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/02-msb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4486\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/02-msb.png\" alt=\"\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/02-msb.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/02-msb-300x235.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/02-msb-768x601.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>On the Device Selection page pick the toolchain and the device. In this tutorial we will use the STM32F4Discovery board and hence will select the STM32F407VG device:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/03-device.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4487\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/03-device.png\" alt=\"\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/03-device.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/03-device-300x235.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/03-device-768x601.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Select a sample project to clone. In this tutorial we will pick the simplest &#8220;LEDBlink&#8221; project:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/04-blink.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4488\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/04-blink.png\" alt=\"\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/04-blink.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/04-blink-300x235.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/04-blink-768x601.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Connect your debugger to the USB port and let VisualGDB detect it, or simply choose it from the list:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/05-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4489\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/05-debug.png\" alt=\"\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/05-debug.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/05-debug-300x235.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/05-debug-768x601.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to generate the project. Then open VisualGDB Project Properties, go to MSBuild Settings page and click &#8220;Linker Script -&gt; Copy to project directory&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/06-copyscript.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4490\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/06-copyscript.png\" alt=\"\" width=\"993\" height=\"622\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/06-copyscript.png 993w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/06-copyscript-300x188.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/06-copyscript-768x481.png 768w\" sizes=\"(max-width: 993px) 100vw, 993px\" \/><\/a><\/li>\n<li>Locate the linker script in Solution Explorer and open it:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/07-script.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4491\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/07-script.png\" alt=\"\" width=\"1097\" height=\"784\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/07-script.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/07-script-300x214.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/07-script-768x549.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/07-script-1024x732.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a><\/li>\n<li>Each linker script consists of the 2 main parts:\n<ol style=\"list-style-type: lower-alpha;\">\n<li>Definition of the memory regions, such as SRAM and FLASH.<\/li>\n<li>Rules that define where each part of the program (e.g. functions, variables or special artifacts such as the interrupt vector table) gets placed.<\/li>\n<\/ol>\n<p>Parts of the program with similar properties (e.g. all regular functions) are often grouped into sections &#8211; consecutive regions of memory sharing the same attributes. In this example, the first section going into the FLASH memory is <strong>.isr_vector<\/strong>.<br \/>\nYou can see to see the result of the linker script (i.e. the addresses assigned to each section and symbol in your program) by generating the map files as shown below:<\/p>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/08-map.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4492\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/08-map.png\" alt=\"\" width=\"838\" height=\"558\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/08-map.png 838w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/08-map-300x200.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/08-map-768x511.png 768w\" sizes=\"(max-width: 838px) 100vw, 838px\" \/><\/a><\/li>\n<li>Build the project and open the map file shown in the build output. Then search for <strong>.isr_vector<\/strong> in it:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/09-isr-vector.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4493\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/09-isr-vector.png\" alt=\"\" width=\"1097\" height=\"784\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/09-isr-vector.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/09-isr-vector-300x214.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/09-isr-vector-768x549.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/09-isr-vector-1024x732.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a>See how the <strong>.isr_vector<\/strong> section containing the <strong>g_pfnVectors<\/strong> variable got placed at the <strong>0x08000000<\/strong> address (beginning of the FLASH memory as defined in the linker script).<\/li>\n<li>Search for the <strong>g_pfnVectors<\/strong> variable in the source files. See how it is explicitly placed into the &#8220;.isr_vector&#8221; section using the &#8220;section&#8221; attribute:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/10-vectordef.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4494\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/10-vectordef.png\" alt=\"\" width=\"1097\" height=\"784\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/10-vectordef.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/10-vectordef-300x214.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/10-vectordef-768x549.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/10-vectordef-1024x732.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a>Regular functions and variables that do not have a &#8220;section&#8221; attribute will be placed into the &#8220;<strong>.text.&lt;function name&gt;<\/strong>&#8221; and &#8220;<strong>.data.&lt;variable name&gt;<\/strong>&#8221; sections. Having one section per function or variable allows linker to automatically discard the unused functions (the linker can drop the sections not referenced by any other section).<\/li>\n<li>Now we will add a new global variable and use the &#8220;section&#8221; attribute together with some linker script constructs to place it at a fixed location in the memory.\u00a0 Add the following code to your main source file:\n<pre class=\"\">int __attribute__((section(\".newsection\"))) VariableAt0x2000 = 1234;<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/11-newvar.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4495\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/11-newvar.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/11-newvar.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/11-newvar-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/11-newvar-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/11-newvar-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a><\/li>\n<li>Now add the following lines inside the <strong>.isr_vector<\/strong> section definition:\n<pre class=\"\">. = 0x2000;\r\nKEEP(*(.newsection))<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/12-script.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4496\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/12-script.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/12-script.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/12-script-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/12-script-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/12-script-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a>The &#8220;. = 0x2000&#8221; statement sets the &#8220;current address&#8221; pointer to 0x2000 (counting from the beginning of the section) and the <strong>*(.newsection)<\/strong> places the contents of the &#8220;.newscetion&#8221; sections from all source files at the current location. The KEEP() construct forces the linker to keep the sections in the final executable file even if they are not referenced by any other code (as we have not referenced the <strong>VariableAt0x2000<\/strong> variable from any code, it would have normally been discarded).<\/li>\n<li>Build the project again and check the map file. See how the <strong>VariableAt0x2000<\/strong> got placed inside the <strong>.isr_vector<\/strong> section exactly at the <strong>0x08002000<\/strong> address:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/13-map.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4497\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/13-map.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/13-map.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/13-map-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/13-map-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/13-map-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a><\/li>\n<li>If you want to align the variable at a certain boundary (e.g. 0x1000) instead of hardcoding the address, you can use the ALIGN() keyword as shown below:\n<pre class=\"\">.isr_vector :\r\n{\r\n\t. = ALIGN(4);\r\n\tKEEP(*(.isr_vector))\r\n\t. = ALIGN(4);\r\n\r\n\tFILL(0xff)\r\n\t. = ALIGN(0x1000);\r\n\tKEEP(*(.newsection))\r\n} &gt; FLASH<\/pre>\n<p>This will result in the following output:<\/p>\n<pre class=\"\"> *(.isr_vector)\r\n .isr_vector    0x08000000      0x188 VisualGDB\/Debug\/startup_stm32f407xx.o\r\n                0x08000000                g_pfnVectors\r\n                0x08000188                . = ALIGN (0x4)\r\n FILL mask 0xff\r\n                0x08001000                . = ALIGN (0x1000)\r\n *fill*         0x08000188      0xe78 ff\r\n *(.newsection)\r\n .newsection    0x08001000        0x4 VisualGDB\/Debug\/LEDBlink.o\r\n                0x08001000                VariableAt0x2000<\/pre>\n<\/li>\n<li>Now we will try placing our global variable inside another memory. The STM32F407VG device includes 64 kilobytes of CCMRAM (see the linker script), so we will place our variable there:\u00a0<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/15-ccmram.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4498\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/15-ccmram.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/15-ccmram.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/15-ccmram-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/15-ccmram-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/15-ccmram-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a>If your device has a single RAM region, you can split it into 2 parts by editing the MEMORY part of the linker script to try out the techniques from the rest of the tutorial.<\/li>\n<li>Remove the &#8220;.newsection&#8221; reference from <strong>.isr_vector<\/strong> and place it into a separate section at the end of the SECTIONS part of the linker script:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/16-ccmramvar.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4499\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/16-ccmramvar.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/16-ccmramvar.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/16-ccmramvar-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/16-ccmramvar-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/16-ccmramvar-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a><\/li>\n<li>Build the project and check the map file. See how the <strong>VariableAt0x2000<\/strong> got placed to <strong>0x10000000<\/strong> (beginning of CCMRAM):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/17-map.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4500\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/17-map.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/17-map.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/17-map-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/17-map-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/17-map-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a><\/li>\n<li>Despite being placed at the correct address, this memory layout will have several side effects that we will explain below. First of all, locate the <strong>.bin<\/strong> file generated for your project. Depending on the exact memory address of <strong>.newsection<\/strong>, it can be several megabytes to gigabytes long:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/18-bigfile.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4501\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/18-bigfile.png\" alt=\"\" width=\"786\" height=\"593\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/18-bigfile.png 786w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/18-bigfile-300x226.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/18-bigfile-768x579.png 768w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/a><\/li>\n<li>Then try modifying the variable from your program and run it. First time you start a debug session, the variable value will be correct:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/19-beforereset.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4502\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/19-beforereset.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/19-beforereset.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/19-beforereset-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/19-beforereset-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/19-beforereset-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a><\/li>\n<li>However, if you try resetting the program, you will see that the variable value will not be changed from the previous run (in this example it was incremented from 1234 to 1235 in the previosu run and got further incremented to 1236 just now):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/20-afterreset.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4503\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/20-afterreset.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/20-afterreset.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/20-afterreset-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/20-afterreset-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/20-afterreset-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><br \/>\n<\/a>Furthermore, if you try power-cycling your device and attach to the program without programming it, the variable in CCMRAM will not be initialized at all (depending on your device type, it will have either a value of 0, or a random value).<\/li>\n<li>Both the <strong>.bin<\/strong> file size and the incorrect initialization happen due to the same reason. Simply placing a variable at the address of <strong>0x10000000<\/strong>\u00a0would make the tools act as if it was a part of the FLASH memory:\n<ul>\n<li>The <strong>.bin<\/strong> file will contain a single consecutive snapshot of the target memory space between the lowest and the highest address in the ELF file (i.e. between <strong>g_pfnVectors<\/strong> at 0x08000000 and <strong>VariableAt0x2000<\/strong> at 0x10000000).<\/li>\n<li>When you program the FLASH memory, gdb will physically copy the initial value of <strong>VariableAt0x2000<\/strong> to the address of <strong>0x10000000<\/strong> where it will stay until the device is power-cycled.<\/li>\n<\/ul>\n<\/li>\n<li>One quick way to fix it would be to declare .newsection with the NOLOAD attribute:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/21-noload.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4504\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/21-noload.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/21-noload.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/21-noload-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/21-noload-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/21-noload-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a>This will prevent the <strong>objcopy<\/strong> tool from including its contents into the <strong>.bin<\/strong> file and gdb won&#8217;t program it either. Then you could manually assign the initial value of <strong>VariableAt0x2000<\/strong> from main() as the initial value specified in the variable definition will be ignored.<\/li>\n<li>A better way to fix this would be using a separate load address for <strong>.newsection<\/strong>. The load address specifies the location where the section contents (i.e. the 1234 value) will be physically loaded when programming the FLASH memory or generating the <strong>.bin<\/strong> file. Since only the FLASH memory retains the data written there after a power cycle, the load address should be located within it. Modify the <strong>.newsection<\/strong> definition as shown below to load its contents right after the contents of the\u00a0<strong>.data<\/strong> section (last section loaded into the FLASH memory):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/22-loadaddr.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4505\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/22-loadaddr.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/22-loadaddr.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/22-loadaddr-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/22-loadaddr-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/22-loadaddr-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a>The _sinewsection (<strong>S<\/strong>tart of <strong>I<\/strong>nitialization data for .newsection), _snewsection (<strong>S<\/strong>tart of .newsection) and _enewsection (<strong>E<\/strong>nd of .newsection) symbols will be used later to copy the data from FLASH into the actual CCMRAM.<\/li>\n<li>Build the project and run the arm-eabi-objdump tool to see the addresses of various sections:\n<pre class=\"\">arm-eabi-objdump -h &lt;ELF file&gt;<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/23-dump.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4506\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/23-dump.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/23-dump.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/23-dump-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/23-dump-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/23-dump-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a>Note that the VMA (virtual memory address) specifies to address where the program will expect the section contents to be at runtime (e.g. &#8220;int x = VariableAt0x2000&#8221; will be translated to &#8220;int x = *((int *)0x10000000)&#8221;. The LMA (load memory address) specifies the address where the section contents will be placed during memory programming (see how it points within the FLASH memory for both <strong>.data<\/strong> and <strong>.newsection<\/strong> sections).<\/li>\n<li>The only missing step is to actually copy the initial value of the <strong>VariableAt0x2000<\/strong> to its virtual address. This could be done using the <strong>_sinewdata<\/strong>, <strong>_snewdata<\/strong> and <strong>_enewdata<\/strong> symbols:\n<pre class=\"\">void InitializeNewSection()\r\n{\r\n    extern void *_sinewsection, *_snewsection, *_enewsection;\r\n    void **pSource, **pDest;\r\n    for (pSource = &amp;_sinewsection, pDest = &amp;_snewsection; pDest != &amp;_enewsection; pSource++, pDest++)\r\n        *pDest = *pSource;\r\n}<\/pre>\n<p>Note that this will copy the correct values for ALL variables inside <strong>.newsection<\/strong> as they will be automatically placed between the _snewsection and _enewsection symbols.<\/li>\n<li>Power cycle the board and start debugging, checking the value of <strong>VariableAt0x2000<\/strong>. See how it got initialized to 1234 inside <strong>InitializeNewSection()<\/strong> and incremented in <strong>main()<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/24-correctval.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4507\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/24-correctval.png\" alt=\"\" width=\"1097\" height=\"786\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/24-correctval.png 1097w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/24-correctval-300x215.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/24-correctval-768x550.png 768w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/01\/24-correctval-1024x734.png 1024w\" sizes=\"(max-width: 1097px) 100vw, 1097px\" \/><\/a><\/li>\n<\/ol>\n<p>If you are using the Custom edition of VisualGDB or higher, you can use the <a href=\"https:\/\/visualgdb.com\/tutorials\/arm\/memories\/\">External Memories page<\/a> of VisualGDB Project Properties to define additional memories like CCMRAM and let VisualGDB edit the linker script and generate the initialization code for you automatically.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use linker scripts to control the memory layout of your embedded programs. We will create<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[53,176],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4484"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=4484"}],"version-history":[{"count":4,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4484\/revisions"}],"predecessor-version":[{"id":4511,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4484\/revisions\/4511"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=4484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=4484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=4484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}