链接描述文件中自定义 .rawdata 部分的数据完整性问题

问题描述 投票:0回答:1

我正在使用 ARM Cortex-M4 处理器(特别是

STM32F4
微控制器)开发一个嵌入式项目,并且遇到了与链接器脚本中定义的内存部分相关的特殊问题。我正在使用
arm-none-eabi-gcc
工具链进行编译。

我有一个二进制文件,我想将其包含在我的固件中。我在汇编文件中创建了一个自定义部分 (

.rawdata
) 以包含此二进制文件,并且我修改了
linker script
以将此部分放入
Flash
内存中。但是,我在运行时面临 .rawdata 部分中数据完整性的问题。

当我将

.rawdata
部分放置在
.data
部分或我的
.text
中的
linker script
部分时,一切都会按预期工作:数据在内存中正确分配,并且实际数据正确存储。我可以在运行时访问和打印数据,没有任何问题。

但是,当我尝试创建一个独立的

.rawdata
部分(在
.data
之外)或将其放置在
.text
部分内时,数据似乎已分配,但内容不是我所期望的。在运行时,当我打印
.rawdata
部分的内容时,我得到不正确的值(与原始
.bin
内容不匹配)。 有趣的是,当我使用
.elf
检查
arm-none-eabi-objdump
文件时,
.rawdata
部分似乎包含正确的数据。这种差异仅在运行时发生。

链接器脚本片段:

ld
.rawdata :
{
  . = ALIGN(4);
  _mstart = .;
  KEEP(*(.rawdata))
  . = ALIGN(4);
  _mend = .;
} >FLASH

为什么将

.rawdata
部分放置在
.data
部分内可以正常工作,但将其创建为独立部分会导致运行时数据不正确? 对于 ARM Cortex-M4 处理器的链接器脚本中的自定义部分,是否缺少特定的注意事项或配置?

.rawdata
部分的数据在 .data 部分之外定义时,如何确保其数据在运行时保持完整?

任何有关如何解决此问题的见解或建议将不胜感激。预先感谢您的帮助!

如果我检查使用

arm-none-eabi-objdump -h -j .rawdata blink.elf
arm-none-eabi-objdump -s -j .rawdata blink.elf


blink.elf:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  1 .rawdata      0000003c  080001c8  080001c8  000071dc  2**0
                  CONTENTS, READONLY

blink.elf:     file format elf32-littlearm

Contents of section .rawdata:
 80001c8 cdcccc3d cdcc4c3e 9a99993e cdcccc3e  ...=..L>...>...>
 80001d8 0000003f 9a99193f 3333333f cdcc4c3f  ...?...?333?..L?
 80001e8 6666663f 0000803f cdcc8c3f 9a99993f  fff?...?...?...?
 80001f8 6666a63f 3333b33f 0000c03f           ff.?33.?...?    

这是应该加载的正确数据。

但是,如果在运行时我检查使用 USART 打印该内存区域内的内容,我会得到:

data size: 60 bytes
Start address: 0x80001c8
End address: 0x8000204
00000000
00000000
3f501eb4
bfe008ee
3d600962
416277e1
c6ffe8d3
3c201ffe
40c1e8d1
41428902
c6004342
4161df76
c2000560
4161a8f3
c2000560

其中地址与上面相同,但内存中的内容不同。

相反, 如果我将

.rawdata
放在
.text
.data
部分内,我会得到与应有的相同的内存内容。





现在补充一下,我发现使用:

arm-none-eabi-objcopy -O binary blink.elf so.bin
.rawdata
数据消失了,我已经使用
hexdump
进行了检查,实际数据仅在.elf文件中,但不在生成的.bin中。

另外,我注意到

.hex
文件的偏移量存在一些冲突:

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .isr_vector       PROGBITS        08000000 001000 0001c8 00  WA  0   0  4
  [ 2] .rawdata          PROGBITS        080001c8 0071dc 00003c 00      0   0  1
  [ 3] .text             PROGBITS        080001d0 0011d0 0053cc 00  AX  0   0 16
  [ 4] .data             PROGBITS        20000000 007000 0001dc 00  WA  0   0  4
  [ 5] .bss              NOBITS          200001dc 0071dc 00017c 00  WA  0   0  4

您可以看到

.rawdata
.bss
在十六进制文件中的偏移量相同,但是 .bss 被标记为 TYPE NOBITS,因此它不应该占用 .hex 文件中数据的任何空间,我不这样做不知道这是否也会导致问题

gcc linker gnu-assembler linker-scripts binutils
1个回答
0
投票

要解决此问题并创建自定义部分,请在程序集文件中将“aw”标志添加到

.rawdata
部分:

.section .rawdata,"aw"
.incbin "my.bin"

来自 binutils 文档

“aw”标志指定应分配该节 (a) 和 可写(w)。

这确保了该部分在内存中正确分配,并且可以在运行时访问和修改。

如果未指定标志,则默认标志取决于该部分 姓名。如果部分名称无法识别,则默认为 没有上述标志的部分:不会分配它 在内存中,不可写,也不可执行。该部分将包含 数据。

因此,根据文档,该部分不会从

.elf
复制到
.bin
using arm-none-eabi-objcopy -O binary blink.elf so.bin
,也不会
flashed
复制到 MCU 使用的工具,如
openocd

最后,

.rawdata
部分将如下所示,并将在MCU中正确加载数据:
_mstart

 .rawdata : ALIGN(4)
  {
    
    _mstart = .;
        
    KEEP(*(.rawdata))
        
    . = ALIGN(4);
    _mend = .;

  } >FLASH
© www.soinside.com 2019 - 2024. All rights reserved.