使用GCC ARM工具链链接任意数据

使用GCC ARM工具链链接任意数据,gcc,arm,ld,cortex-m3,Gcc,Arm,Ld,Cortex M3,我想链接原始二进制数据。我想把它放在一个特定的地址,或者让它链接到我在代码中定义的符号(例如char*mydata)。因为它不是一个obj文件,所以我不能简单地将它链接进去 类似的帖子()建议将objcopy与-bfdarch选项一起使用。objcopy以“架构bfdarch未知”作为响应 还有一个答案建议将对象转换为自定义LD脚本,然后从主LD脚本中包含该脚本。在这一点上,我可能只是使用一个C包含文件(这就是我现在正在做的),所以我不想这样做 我可以使用objcopy来实现这一点,还是有其他方

我想链接原始二进制数据。我想把它放在一个特定的地址,或者让它链接到我在代码中定义的符号(例如char*mydata)。因为它不是一个obj文件,所以我不能简单地将它链接进去

类似的帖子()建议将objcopy与
-bfdarch
选项一起使用。objcopy以“架构bfdarch未知”作为响应

还有一个答案建议将对象转换为自定义LD脚本,然后从主LD脚本中包含该脚本。在这一点上,我可能只是使用一个C包含文件(这就是我现在正在做的),所以我不想这样做


我可以使用objcopy来实现这一点,还是有其他方法

一种快速的方法是将数据放在自己的.c文件(.c而不是.h)中,使其自身成为.o,然后在链接器脚本中,您可以为该.o文件定义特定的内存空间和节项,并将其放在任何需要的地方

MEMORY
{
...
BOB : ORIGIN = 0x123400, length = 0x200
...
}
SECTIONS
{
...
TED : { mydata.o } > BOB
...
}

另一种方法可能是使用

在该文件中,您将获得两个符号
unsigned char your_data[]
unsigned int your_data_len
。第一个是包含数据的巨大数组,第二个是该数组的长度

编译创建的C文件可能需要花费时间,所以如果您使用的是构建系统/Makefile,请正确处理它,避免不必要的重新编译


xxd
应该是Linux发行版的
vim
vim common
)包的一部分。

以下示例对我很有用:

$ dd if=/dev/urandom of=binblob bs=1024k count=1
$ objcopy -I binary -O elf32-little binblob binblob.o
$ file binblob.o
binblob.o: ELF 32-bit LSB relocatable, no machine, version 1 (SYSV), not stripped
$ nm  -S -t d binblob.o
0000000001048576 D _binary_binblob_end
0000000001048576 A _binary_binblob_size
0000000000000000 D _binary_binblob_start
也就是说,无需为二进制数据指定BFD arch(它仅对代码有用/必要)。只要说“输入是二进制的”和“输出是…”,它就会创建文件。由于纯二进制数据不是特定于体系结构的,所以您只需要告诉它输出是32位(
elf32-…
)还是64位(
elf64-…
),以及它是小端/LSB(
…-little
,如在ARM/x86上)还是大端/MSB(
…-big
,如在SPARC/m68k上)

编辑: 关于
objcopy
选项的说明:

  • 使用
    -O…
    选项控制:
    • 位宽度(ELF文件是32位还是64位)
    • endianness(ELF文件是LSB还是MSB)
  • -B…
    选项的使用控制ELF文件将请求的体系结构
您必须指定
-O…
,但
-B…
是可选的。通过一个小例子可以最好地说明这种差异:

$ objcopy -I binary -O elf64-x86-64 foobar foobar.o $ file foobar.o foobar.o: ELF 64-bit LSB relocatable, no machine, version 1 (SYSV), not stripped $ objcopy -I binary -O elf64-x86-64 -B i386 foobar foobar.o $ file foobar.o foobar.o: ELF 64-bit LSB relocatable, AMD x86-64, version 1 (SYSV), not stripped $objcopy-I二进制文件-O elf64-x86-64 foobar foobar.O $file foobar.o o:ELF 64位LSB可重定位,无机器,版本1(SYSV),未剥离 $objcopy-I binary-O elf64-x86-64-B i386 foobar foobar.O $file foobar.o o:ELF 64位LSB可重定位,AMD x86-64,版本1(SYSV),未剥离 也就是说,仅输出格式说明符
elf64-x86-64
不会将生成的二进制文件绑定到特定的体系结构(这就是为什么
文件
没有机器
)。如果
-B i386
这样做,那么使用方法是正确的,在这种情况下,您会被告知这就是
AMD x86-64

这同样适用于ARM
-O elf32 little
-O elf32 littleram-B arm
的区别在于,在前一种情况下,您最终得到的是
ELF 32位LSB可重定位,没有机器,
,而在后一种情况下,它将是
ELF 32位LSB可重定位,arm…

这里也有一些相互依存的关系;您必须使用
-O elf{32 | 64}-
(而不是通用的
elf{32 | 64}-{little | big}
)输出选项才能识别
-B…


请参阅
objcopy--info
以获取binutils可以处理的ELF格式/BFD类型列表。

How'bout
unsigned char data[]={0x12、0x34、0x56、0x78、…}相反?H2CO3,这就是我正在做的。我有一个预构建命令来读取bin文件,并输出一个包含数据数组的H文件(如您所建议的)。这是可行的,但似乎应该有更好的方法;请尝试
arm
。这肯定和使用天然气一样有效,它有一个。还有大量程序,如
hextump
,可以将二进制数组转换为“C”数组。您只需使用
objcopy
。看看我的答案。看起来是个好办法。我会试试这个。对于我使用的工具链版本,输出类型为“elf32 littlearm”。如果您在嵌入式平台上工作,您可能希望数据保留在闪存中,而不是加载到ram中。添加以下内容以修复它:--rename section.data=.rodataarm none eabi objcopy-I binary-O elf32 littleram-B arm--rename section.data=.rodata binblob binblob.O $ objcopy -I binary -O elf64-x86-64 foobar foobar.o $ file foobar.o foobar.o: ELF 64-bit LSB relocatable, no machine, version 1 (SYSV), not stripped $ objcopy -I binary -O elf64-x86-64 -B i386 foobar foobar.o $ file foobar.o foobar.o: ELF 64-bit LSB relocatable, AMD x86-64, version 1 (SYSV), not stripped