GCC裸金属连接器问题-Cortex M3
在我的项目链接过程中,我遇到了一个问题。我使用制造商提供的GCC链接器脚本 在这里,我对代码部分的定义如下:GCC裸金属连接器问题-Cortex M3,gcc,cortex-m3,Gcc,Cortex M3,在我的项目链接过程中,我遇到了一个问题。我使用制造商提供的GCC链接器脚本 在这里,我对代码部分的定义如下: MEMORY { // .. deleted other sections CODE (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000 /* 116 page(s) */ // .. deleted other sections } 因此,代码段的开头位于0xB000,长度为0x74000。长度为116 x 4096字节
MEMORY
{
// .. deleted other sections
CODE (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000 /* 116 page(s) */
// .. deleted other sections
}
因此,代码段的开头位于0xB000,长度为0x74000。长度为116 x 4096字节=>475136字节代码大小
我的二进制生成具有以下大小:
text data bss dec hex filename
432372 0 112048 522420 7f8b4 project.elf
因此,它应该链接OK,因为使用的大小432372(文本+数据)远小于可用空间475136
只要二进制代码大小<~422kBytes,它就可以链接,一旦它变大,链接器就会告诉我代码段溢出,无法链接
有人能解释一下为什么不行吗?我看不出链接告诉我我的代码太大的原因,因为它不是
链接器脚本
MEMORY
{
// ... removed sections here .. irelevant for discussion ...
CODE (rx ) : ORIGIN = 0x0000B000, LENGTH = 0x00074000 /* 116 page(s) */
// ... removed sections here .. irelevant for discussion ...
RAM (xrw) : ORIGIN = 0x20000040, LENGTH = 20000
MEMORY_B1 (rx ) : ORIGIN = 0x60000000, LENGTH = 0K
}
/* The '__stack' definition is required by crt0, do not remove it */
__stack = ORIGIN(RAM) + LENGTH(RAM);
_estack = __stack;
__Main_Stack_Size = 2048 ;
PROVIDE ( _Main_Stack_Size = __Main_Stack_Size ) ;
__Main_Stack_Limit = __stack - __Main_Stack_Size ;
/*"PROVIDE" allows to easily override these values from an object file or the command line. */
PROVIDE ( _Main_Stack_Limit = __Main_Stack_Limit ) ;
/*
* There will be a link error if there is not this amount of
* RAM free at the end.
*/
_Minimum_Stack_Size = 2048 ;
/*
* Default heap definitions.
* The heap start immediately after the last statically allocated
* .sbss/.noinit section, and extends up to the main stack limit.
*/
/*PROVIDE ( _Heap_Begin = _end_noinit ) ; */
/*PROVIDE ( _Heap_Limit = _end_noinit ) ; */
_Min_Heap_Size = 0x100; /* required amount of heap (256 bytes) */
_Min_Stack_Size = 0x400; /* required amount of stack (1kByte) */
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.vectors))
__Vectors_End = .;
__Vectors_Size = __Vectors_End - __Vectors;
__end__ = .;
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > CODE
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > CODE
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > CODE
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > CODE
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > CODE
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN (4);
*(.ram)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__HeapBase = .;
__end__ = .;
end = __end__;
_end = __end__;
KEEP(*(.heap*))
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
KEEP(*(.stack*))
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
/* Check if CODE usage exceeds CODE size */
ASSERT( LENGTH(CODE) >= (__etext + SIZEOF(.data)), "CODE memory overflowed !")
}
在最后几行,我断言代码大小:
/* Check if CODE usage exceeds CODE size */
ASSERT( LENGTH(CODE) >= (__etext + SIZEOF(.data)), "CODE memory overflowed !")
__etext应该是文本(代码)使用的实际大小。数据应该为零
有人能解释一下为什么不行吗
只需查看链接器脚本:
code(rx):原点=0x0000B000,长度=0x00074000/*116页)*/
0x74000十六进制为475136 十进制,或464KB
__etext应该是文本(代码)使用的实际大小。数据应该为零
不是根据链接器脚本。在发布的脚本中,uu etext是代码段的结束地址。或者只是代码段的大小加上它的起始地址(非零)
换句话说,您的最后一个ASSERT()编码错误,过早地释放0xB000字节。和0x74000-0xB000=0x69000(或430080 十进制)
有人能解释一下为什么不行吗
只需查看链接器脚本:
code(rx):原点=0x0000B000,长度=0x00074000/*116页)*/
0x74000十六进制为475136 十进制,或464KB
__etext应该是文本(代码)使用的实际大小。数据应该为零
不是根据链接器脚本。在发布的脚本中,uu etext是代码段的结束地址。或者只是代码段的大小加上它的起始地址(非零)
换句话说,您的最后一个ASSERT()编码错误,过早地释放0xB000字节。和0x74000-0xB000=0x69000(或430080 小数)。如果显示的不够多,二进制文件中的.bss是如何显示的?正在使用的整个链接器脚本是什么样子的?当你把它缩小到能说明问题的范围时会发生什么?@old_timer(A).bss是零初始化的ram部分。因此,我有闪存区域(文本+数据)和ram部分(bss+数据)。数据是由ram初始化的值。(B) 你需要什么样的证明?正如我所说,问题发生在我添加新代码时,因此代码大小增加了约422kBytes,然后链接器“表示”代码部分不适合flash部分并中止链接。(C) 链接器脚本,请参阅上面编辑的帖子当我写评论时,你的链接器脚本没有数据,也没有bss定义,只有代码,但问题超出了前面提到的范围。如果您有工具/链接器脚本问题,您可以将其设置为10或100字节的部分,并对问题中可见的所有示例代码/数据进行相同的演示。如果您的演示不够,那么二进制文件中如何有.bss?正在使用的整个链接器脚本是什么样子的?当你把它缩小到能说明问题的范围时会发生什么?@old_timer(A).bss是零初始化的ram部分。因此,我有闪存区域(文本+数据)和ram部分(bss+数据)。数据是由ram初始化的值。(B) 你需要什么样的证明?正如我所说,问题发生在我添加新代码时,因此代码大小增加了约422kBytes,然后链接器“表示”代码部分不适合flash部分并中止链接。(C) 链接器脚本,请参阅上面编辑的帖子当我写评论时,你的链接器脚本没有数据,也没有bss定义,只有代码,但问题超出了前面提到的范围。如果您有工具/链接器脚本问题,可以将其设置为10或100字节的部分,并对问题中可见的所有示例代码/数据进行相同的演示。