将变量放在特定地址会生成大型二进制文件

时间:2016-01-07 23:08:16

标签: c gcc memory linker arm

我必须将数组放在内存中的特定地址。我正在使用GCC。

我声明变量如下:

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

在链接器脚本中我得到了:

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

以后:

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

它当然是嵌入式系统(ARM)的代码。通常我的程序需要22 KB,这个修改需要384 MB(!)。

我不明白为什么。如果我删除__attribute__,则需要再次使用22 KB。 我错过了什么?


使用的代码:

#inculde (...)

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

int main(void){
  buffer = 10;
}

完整的链接描述文件(默认情况下,不是我写的,部分缩短了:

/* 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) }
}

1 个答案:

答案 0 :(得分:0)

我假设您的输出文件是纯二进制格式,而不是ELF,因此您没有ELF引导程序。在这种情况下,将初始化数据放在高地址显然会创建一个大的输出文件。这是因为在二进制格式中,您没有任何提供特定地址的机制,因此文件以1:1的方式映射到内存中。这意味着直到您的自定义初始化变量的整个地址空间需要包含在输出文件中。 这与.data部分的情况相同,这就是为什么.data部分在启动时从Flash显式复制到RAM区域。

P.S。您可以找到有用的my article(此处对此问题进行了描述)。