Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Placing variables at specific address generates large binary file

I have to place array at specific address in memory. I'm using GCC.

I declare variable like this:

uint8_t __attribute__((section (".mySection"))) buffer[1234];

And in linker script I've got:

MEMORY
{
FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 145K
MYSEC (x)       : ORIGIN = 0x20025000, LENGTH = 155K
}

and later:

.mySection :
{
  *(.mySection);
} > MYSEC 

It's of course code for embedded system (ARM). Normally my program takes 22 KB, with this modification it takes 384 MB (!).

I don't understand why. If I remove __attribute__ it takes 22 KB again. What am I missing?


Code used:

#inculde (...)

uint8_t __attribute__((section (".mySection"))) buffer = 5;

int main(void){
  buffer = 10;
}

Full linker script (default, not written by me, parts are shortened:

/* Entry Point */
ENTRY(Reset_Handler)

/* Highest address of the user mode stack */
_estack = 0x20050000;    /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x400; /* required amount of stack */

/* Specify the memory areas */
MEMORY
{
FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 145K
MYSEC (x)       : ORIGIN = 0x20025000, LENGTH = 155K
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    (...)
  } >FLASH

  /* The program code and other data goes into FLASH */
  .text :
  {
    (...)
  } >FLASH

  /* Constant data goes into FLASH */
  .rodata :
  {
    (...)
  } >FLASH

  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
  .ARM : {
    (...)
  } >FLASH

  .preinit_array     :
  {
    (...)
  } >FLASH
  .init_array :
  {
    (...)
  } >FLASH
  .fini_array :
  {
    (...)
  } >FLASH

  /* used by the startup to initialize data */
  _sidata = LOADADDR(.data);

  /* Initialized data sections goes into RAM, load LMA copy after code */
  .data : 
  {
    (...)
  } >RAM AT> FLASH



  .mySection :
  {
    *(.mySection);
  } > MYSEC 


  /* Uninitialized data section */
  . = ALIGN(4);
  .bss :
  {
    (...)
  } >RAM

  /* User_heap_stack section, used to check that there is enough RAM left */
  ._user_heap_stack :
  {
    (...)
  } >RAM

  /* Remove information from the standard libraries */
  /DISCARD/ :
  {
    (...)
  }

  .ARM.attributes 0 : { *(.ARM.attributes) }
}
like image 620
zupazt3 Avatar asked Feb 26 '26 13:02

zupazt3


1 Answers

I assume your output file is a pure binary format, not an ELF so you don't have ELF bootloader. In that case, placing initialized data at high address obviously will create a big output file. This is because in the binary format you don't have any mechanism to provide specific address, so the file is mapped 1:1 into memory. It means the whole address space up to your custom initialized variable needs to be included in the output file. This is the same situation as with .data section and this is why the .data section is explicitly copied from Flash into RAM area at the startup.

p.s. You can find my article helpful (this issue is described there).

like image 112
mkmk88 Avatar answered Feb 28 '26 03:02

mkmk88



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!