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

时间:2013-06-23 22:34:50

标签: gcc arm ld cortex-m3

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

类似的帖子(Include binary file with GNU ld linker script)建议将objcopy与-B bfdarch选项一起使用。 objcopy以“archictecture bfdarch unknown”作为回应。

另一个答案建议将对象转换为自定义LD脚本,然后将其包含在主LD脚本中。此时,我可能只是使用C包含文件(这就是我现在正在做的事情),所以我宁愿不这样做。

我可以使用objcopy来完成此任务,还是有其他方法?

3 个答案:

答案 0 :(得分:10)

以下示例适用于我:

$ 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({{ 1}},如在ARM / x86上)或big endian / MSB(...-little,例如在SPARC / m68k上)。

修改 澄清...-big的选项:

  • 使用objcopy选项控件:
    • 位宽(ELF文件是32位还是64位)
    • endianness(ELF文件是LSB还是MSB)
  • 使用-O ...选项控制ELF文件将请求的架构

指定-B ...,但-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

即。只是输出格式说明符-B ...不会将生成的二进制文件绑定到特定的体系结构(这就是为elf64-x86-64file)的原因。 no machine这样做的用法 - 在这种情况下,您被告知现在是-B i386

同样适用于ARM; AMD x86-64-O elf32-little相比,在前一种情况下,您最终获得-O elf32-littlearm -B arm,而在后者中,它将是ELF 32-bit LSB relocatable, no machine, ...

这里也存在一些相互依赖关系;您必须使用ELF 32-bit LSB relocatable, ARM...(而非通用-O elf{32|64}-<arch>)输出选项才能识别elf{32|64}-{little|big}

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

答案 1 :(得分:5)

另一种方法可能是使用xxd

xxd -i your_data your_data.c

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

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

xxd应该是Linux发行版的vimvim-common)程序包的一部分。

答案 2 :(得分:1)

快速执行此操作的方法是将数据放在自己的.c文件(.c而不是.h)中,使其成为.o本身,然后在链接描述文件中,您可以定义特定的内存空间,该.o文件的部分条目,并将其放在任何你想要的地方。

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