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

标签 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) }
}

最佳答案

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

附注你可以找到my article有帮助(这里描述了这个问题)。

关于c - 将变量放在特定地址会生成大型二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34666848/

相关文章:

gcc - 静态链接 GLIBC 和专有软件许可

c - 减去 2 size_t 的类型是什么?

c - 新手看不出代码为什么出错,但知道哪里出错

c - 如何使用 gtk3 在 linux 上的 c 中的窗口之间切换

c++ - 指向结构的指针如何工作?

C、free() 上的内存损坏(快速)错误

C 理解指针数组的问题

c - C 中的位移位

c - 使用 GCC C 在 AIX 上处理空指针

gcc - Linux内核转储堆栈中的 ".clone"是什么意思?