Linker script. The following section, the first character, _srelocate, is invalid (GCC error?)

Problem

My problem is that when I use the following script, which is designed to put code in RAM, the redistribution section is filled with dummy data.

My question is:

  • Why is the _srelocate character 4 bytes larger than the _etext character? Shouldn't they be the same?

  • Also, if the answer is 1. NO, should I copy from _etext + 4 to _srelocate ?

Background and associated code

I work with an Atmel ATSAM3N4X processor (ARM Cortex M3) and would like to help a bit with initializing the script and .relocate linker section.

The reason for this is that the _etext character is 4 bytes less than the _srelocate character.

The following script builder is the default script generated by Atmel Studio 6 (if you want the ram / rom character layout to appear in the Application ).

 /* ---------------------------------------------------------------------------- * SAM Software Package License * ---------------------------------------------------------------------------- * Copyright (c) 2012, Atmel Corporation * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * Atmel name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ---------------------------------------------------------------------------- */ /* Section Definitions */ SECTIONS { .text : { . = ALIGN(4); _sfixed = .; KEEP(*(.vectors .vectors.*)) *(.text .text.* .gnu.linkonce.t.*) *(.glue_7t) *(.glue_7) *(.rodata .rodata* .gnu.linkonce.r.*) *(.ARM.extab* .gnu.linkonce.armextab.*) /* Support C constructors, and C destructors in both user code and the C library. This also provides support for C++ code. */ . = ALIGN(4); KEEP(*(.init)) . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) __preinit_array_end = .; . = ALIGN(4); __init_array_start = .; KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; . = ALIGN(0x4); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*crtend.o(.ctors)) . = ALIGN(4); KEEP(*(.fini)) . = ALIGN(4); __fini_array_start = .; KEEP (*(.fini_array)) KEEP (*(SORT(.fini_array.*))) __fini_array_end = .; KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*crtend.o(.dtors)) . = ALIGN(4); _efixed = .; /* End of text section */ } > ram . = ALIGN(4); _etext = .; .relocate : AT (_etext) { . = ALIGN(4); _srelocate = .; *(.ramfunc .ramfunc.*); *(.data .data.*); . = ALIGN(4); _erelocate = .; } > ram /* .bss section which is used for uninitialized data */ .bss (NOLOAD) : { . = ALIGN(4); _sbss = . ; _szero = .; *(.bss .bss.*) *(COMMON) . = ALIGN(4); _ebss = . ; _ezero = .; } > ram /* stack section */ .stack (NOLOAD): { . = ALIGN(8); _sstack = .; . = . + STACK_SIZE; . = ALIGN(8); _estack = .; } > ram /* .ARM.exidx is sorted, so has to go in its own output section. */ PROVIDE_HIDDEN (__exidx_start = .); .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > ram PROVIDE_HIDDEN (__exidx_end = .); . = ALIGN(4); _end = . ; } 

I used nm to see what the meanings of the characters mean, and I included them below:

 2000115c A _etext 20001160 D _srelocate 200015c8 D _erelocate 

Now Atmel Studio 6 automatically generated my project and gave me Reset_Handler() , which copies the .relocate section from _etext to _srelocate and clears the .bss section. The project comes with two linker scripts, one for execution based on FLASH and one for code based on RAM. By default, code based on FLASH is used, but I changed it to the linker script (above) based on RAM and ran into a problem.

The initialization code that copies the .relocate section from FLASH to RAM is also auto-generated, and I did not change it when I changed the linker scripts. It looks like this:

 void Reset_Handler(void) { uint32_t *pSrc, *pDest, Size; /* Initialize the relocate segment */ pSrc = &_etext; pDest = &_srelocate; if (pSrc != pDest) { for (; pDest < &_erelocate;) { *pDest++ = *pSrc++; } } /* Clear the zero segment */ for (pDest = &_szero; pDest < &_ezero;) { *pDest++ = 0; } /* Set the vector table base address */ pSrc = (uint32_t *) & _sfixed; SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk); if (((uint32_t) pSrc >= IRAM_ADDR) && ((uint32_t) pSrc < IRAM_ADDR + IRAM_SIZE)) { SCB->VTOR |= (1UL) << SCB_VTOR_TBLBASE_Pos; } /* Initialize the C library */ __libc_init_array(); /* Branch to main function */ main(); /* Infinite loop */ while (1); } 

Change 1:

Using objdump -t CodeFile.elf > CodeFile.symbols , I found this symbol at the beginning of my .relocate section, which seems to suggest that _srelocate does not point to the beginning of .relocate .

  2000115c g O .relocate 00000000 .hidden __TMC_END__ 

What is this symbol?

I looked through it and found this error in GCC 4.7, but I can’t understand if it’s fixed or not in my version.

My compiler is arm-none-eabi-gcc and declares its version as 4.7.0 ... The linker is arm-none-eabi-ld , and its version is 2.22 .

Edit 2:

I did some research about this, and he wrote in this related SO question that I asked. Take a look at this as well, as this explains that the problem is a GCC error.

open

Memory layout for linker scripts

 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) SEARCH_DIR(.) /* Memory Spaces Definitions */ MEMORY { rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00040000 /* flash, 256K */ ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00006000 /* sram, 24K */ } /* The stack size used by the application. NOTE: you need to adjust */ STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x800 ; 
+2
source share
2 answers

I found the answer to my question a long time ago, but it seems that it is still a bit unclear in my righteous people, so let me formalize it here.

The problem is that due to an error in GCC, the linker inserts an extra TMC_END character, occupying 4 bytes between the _etext and _srelocate . This is not true, because this symbol has nothing to do with the code that I write, and I do not even use this function. I discovered and explained this in my other SO question .

Workaround:

The Atmel example code, by right, assumes that if your code does not work in flash memory, your _srelocate character _srelocate and _etext character _etext will be different, one of which will have an address starting with 0x004... and the other with 0x20...

If your code has run out of RAM, this means that you have a bootloader that copies the appropriate partitions to the correct memory location, so the _srelocate character address will also be in RAM and will be equal to the _srelocate character address.

Therefore, Atmel tries to make sure that the _srelocate section _srelocate always in RAM.

Due to an error in GCC, the solution was to change the code to check if the address of the _srelocate character _srelocate in RAM, for example:

 // I can't remember what #define Atmel has for SRAM so I'm just going to // use this one for the purposes of my example. #define SRAM_START_ADDRESS 0x20000000 void Reset_Handler(void) { uint32_t *pSrc, *pDest, Size; /* Initialize the relocate segment */ pSrc = &_etext; // Could either be in Flash or SRAM depending on your configuration. pDest = &_srelocate; // Always in SRAM or there something strange going on... if ((intptr_t)pSrc < (intptr_t)SRAM_START_ADDRESS) { // <<<< Changed code here <<<< // We enter here only if pSrc is pointing to a location in Flash. // If that the case, we need to copy the memory from Flash to SRAM. for (; pDest < &_erelocate;) { *pDest++ = *pSrc++; } } /* Clear the zero segment */ for (pDest = &_szero; pDest < &_ezero;) { *pDest++ = 0; } /* Set the vector table base address */ pSrc = (uint32_t *) & _sfixed; SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk); if (((uint32_t) pSrc >= IRAM_ADDR) && ((uint32_t) pSrc < IRAM_ADDR + IRAM_SIZE)) { SCB->VTOR |= (1UL) << SCB_VTOR_TBLBASE_Pos; } /* Initialize the C library */ __libc_init_array(); /* Branch to main function */ main(); /* Infinite loop */ while (1); } 

And it worked for my situation. From what I see, this error has been fixed, and the correction has since been canceled, so it is unlikely that you will be fixed in your Atmel Studio.

+2
source

I'm not sure if this is your problem, but if you use SAM-BA to copy the code to SRAM, the SAM-BA boot program uses the first 2048 (0x800) SRAM bytes for the variables and its stack, which is probably why your redistribution section gets a tote (there is an ISR and other code still working when copying the code, and this requires their own SRAM).

All SAM-BA applet examples are copied to 0x20000800 for this reason.

I don’t know how you would put your code in SRAM, besides implementing something similar to SAM-BA, in which case you will also need your own SRAM section for data.

Here is the app builder script for the SAM4S16 part:

 /* ---------------------------------------------------------------------------- * SAM Software Package License * ---------------------------------------------------------------------------- * Copyright (c) 2012, Atmel Corporation * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * * Atmel name may not be used to endorse or promote products derived from * this software without specific prior written permission. * * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ---------------------------------------------------------------------------- */ /*------------------------------------------------------------------------------ * Linker script for running in internal SRAM on the SAM4S16 *----------------------------------------------------------------------------*/ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) /* Memory Spaces Definitions */ MEMORY { romcodesram (W!RX) : ORIGIN = 0x20000000, LENGTH = 0x800 sram (W!RX) : ORIGIN = 0x20000800, LENGTH = 0x0001F800 /* sram, 128K - sizeof(romcodesram) */ } SECTIONS { /* startup code in the .isr_vector */ .text : { . = ALIGN(4); _stext = .; KEEP(*(.isr_vector .isr_vector.*)) *(.mailbox) *(.text .text.*) *(.rodata .rodata.*) *(.ramfunc .ramfunc.*) *(.glue_7) *(.glue_7t) *(.gcc_except_table) *(.rodata .rodata*) *(.gnu.linkonce.r.*) . = ALIGN(4); _etext = .; } > sram /* data */ .data : { . = ALIGN(4); _sidata = .; _sdata = .; *(.data) *(.data.*) . = ALIGN(4); _edata = .; } > sram .bss (NOLOAD) : { _szero = .; *(.bss) . = ALIGN(4); _ezero = .; } >sram /* Stack in SRAM */ _sstack = 0x2001FFF0; } . = ALIGN(4); end = .; 
0
source

Source: https://habr.com/ru/post/1491036/


All Articles