Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Embedded LD链接器:目标地址对齐,但不是ROM中的地址_Embedded_Linker - Fatal编程技术网

Embedded LD链接器:目标地址对齐,但不是ROM中的地址

Embedded LD链接器:目标地址对齐,但不是ROM中的地址,embedded,linker,Embedded,Linker,我有一个驻留在flash中的程序,它将从flash运行。在程序的早期,数据段从闪存复制到ram。我使用的链接器脚本如下(简化): 我希望各部分在4字节边界上对齐(体系结构为PowerPC 32位)。一些数据部分包括子单词项。我发现ALIGN指令与RAM中的VMA地址对齐,但没有与LMA对齐。因此,我的复制到ram例程失败,因为这两个区域没有逐字节对应 我的复印程序看起来像 r3 = address in flash of _etext r4 = address in ram of __COPY_

我有一个驻留在flash中的程序,它将从flash运行。在程序的早期,数据段从闪存复制到ram。我使用的链接器脚本如下(简化):

我希望各部分在4字节边界上对齐(体系结构为PowerPC 32位)。一些数据部分包括子单词项。我发现ALIGN指令与RAM中的VMA地址对齐,但没有与LMA对齐。因此,我的复制到ram例程失败,因为这两个区域没有逐字节对应

我的复印程序看起来像

r3 = address in flash of _etext
r4 = address in ram of __COPY_DATA_START__
words to copy = (__END_COPY__ - COPY_DATA_START) / 4

while (words to copy)
  * r4++ = *r3++
当循环到达对齐位时,目标指向一些pad字节,但源数据不包括对齐填充,因此数据过早地放入内存

我可以从映射文件中看出这一点,因为它看起来像(人为的示例)

.rodata 0x00000000 0xb15加载地址0xfff13000
0x00000000提供(复制数据开始)

.sdata 0x00000b18 0x10加载地址0xfff13b15通过使用不同形式的“AT”链接器脚本命令,我获得了一些成功。如果我使用

  _etext = .;
  PROVIDE (etext = .);
  .rodata : AT (_etext)
  { 
... contents of section ...
  }

  .sdata2 : AT (_etext + SIZEOF(.rodata) + SIZEOF(.gcc_except_table))
  { 
... contents of section ...
  } > ram

  .sbss2 : AT (_etext + SIZEOF(.rodata) + SIZEOF(.gcc_except_table) + SIZEOF(.sdata2) )
  { 
... contents of section ...
    . = ALIGN(16);
  } > ram 
然后,它似乎与我预期的一致。
SIZEOF()+SIZEOF()…
字符串在文件末尾变得相当长,但至少可以工作


(其他信息:通常情况下,您不会将rodata部分复制到ram中,因为它是只读的。在我的系统上,闪存无法处理浮点常量所需的访问类型,因此我确实需要将其复制到ram中,即使它不会被修改)。

您似乎没有说明正在使用哪个链接器,但是您的脚本看起来像GNU链接器脚本(所以我假设它是)。要使用GNU链接器脚本对齐节的VMA和LMA,请执行以下操作

.section_name ALIGN( vma_alignment ) : ALIGN( lma_alignment ){
  ...section contents
}
.section_name是要对齐的输出节的名称,可以是任何合法名称。冒号左侧的ALIGN语句影响VMA对齐,冒号右侧的ALIGN语句影响LMA对齐。在您的情况下,您希望vma_校准=lma_校准=4。请参阅GNU链接器参考手册第3.6.1节

因此,您的整个脚本应该如下所示

.text      :
{
  *(.text)
} > FLASH
_etext = .;
PROVIDE (etext = .);

.rodata ALIGN(4)  : ALIGN(4)
{
  PROVIDE(__VMA_COPY_DATA_START__ = ADDR(.rodata)); /*The runtime address of .rodata*/
  PROVIDE(__LMA_COPY_DATA_START__ = LOADADDR(.rodata)); /*The load address of .rodata*/

  *(.rodata) 
} > ram AT>flash

PROVIDE (__SDATA2_START__ = .);
.sdata2   :
{ 
  *(.sdata2)
} > ram AT>flash

PROVIDE (__sbss2_start = . );
.sbss2   : { 
  *(.sbss2) 
  . = ALIGN(4)
} > ram AT>flash
PROVIDE (__sbss2_end = . );
PROVIDE (__SBSS2_END__ = .);

.data    :
{
  *(.data)
  *(.gnu.linkonce.d*)
  CONSTRUCTORS
  *(.eh_frame)
} > ram AT>flash
 /*
 *align address so that (__END_COPY__ -  __VMA_COPY_DATA_START__) / 4 does not round down.
 *If alignment is not done then the copy routine could potentially drop up to 3 bytes at 
 *the end of the .data section if the section does not end on a multiple of 4 bytes.
 */
. = ALIGN(4)
PROVIDE (__END_COPY__ = .);
你的复印程序看起来像

r3 = address in flash of __LMA_COPY_DATA_START__
r4 = address in ram of   __VMA_COPY_DATA_START__
words_to_copy = (__END_COPY__ -  __VMA_COPY_DATA_START__) / 4

while (words_to_copy){
  * r4++ = *r3++
  words_to_copy--
}

这个答案是错误的。结肠后的对齐(x)未设置LMA对齐。我刚刚用binutils 2.25试过了。
.text      :
{
  *(.text)
} > FLASH
_etext = .;
PROVIDE (etext = .);

.rodata ALIGN(4)  : ALIGN(4)
{
  PROVIDE(__VMA_COPY_DATA_START__ = ADDR(.rodata)); /*The runtime address of .rodata*/
  PROVIDE(__LMA_COPY_DATA_START__ = LOADADDR(.rodata)); /*The load address of .rodata*/

  *(.rodata) 
} > ram AT>flash

PROVIDE (__SDATA2_START__ = .);
.sdata2   :
{ 
  *(.sdata2)
} > ram AT>flash

PROVIDE (__sbss2_start = . );
.sbss2   : { 
  *(.sbss2) 
  . = ALIGN(4)
} > ram AT>flash
PROVIDE (__sbss2_end = . );
PROVIDE (__SBSS2_END__ = .);

.data    :
{
  *(.data)
  *(.gnu.linkonce.d*)
  CONSTRUCTORS
  *(.eh_frame)
} > ram AT>flash
 /*
 *align address so that (__END_COPY__ -  __VMA_COPY_DATA_START__) / 4 does not round down.
 *If alignment is not done then the copy routine could potentially drop up to 3 bytes at 
 *the end of the .data section if the section does not end on a multiple of 4 bytes.
 */
. = ALIGN(4)
PROVIDE (__END_COPY__ = .);
r3 = address in flash of __LMA_COPY_DATA_START__
r4 = address in ram of   __VMA_COPY_DATA_START__
words_to_copy = (__END_COPY__ -  __VMA_COPY_DATA_START__) / 4

while (words_to_copy){
  * r4++ = *r3++
  words_to_copy--
}