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; pSrc = &_etext; pDest = &_srelocate; if (pSrc != pDest) { for (; pDest < &_erelocate;) { *pDest++ = *pSrc++; } } for (pDest = &_szero; pDest < &_ezero;) { *pDest++ = 0; } 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; } __libc_init_array(); main(); 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 { rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00040000 ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00006000 } STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x800 ;