如何添加二进制资源

时间:2013-05-31 07:38:37

标签: gcc

我有一个项目需要可执行文件中的一堆图形文件。由于目标上没有文件系统,我只能使用fopen函数。一种方法是将文件内容转换为包含像

这样的变量定义的C源代码
unsigned char file1_content[] = {
   0x01, 0x02, ...
};

即使使用转换器工具,构建此类文件也很麻烦。

在为每个文件指定变量名时,有没有办法将二进制文件添加到rdata部分?我想为此使用链接器脚本但是找不到方法。

2 个答案:

答案 0 :(得分:2)

使用工具并不是特别麻烦,这是经典的解决方案。 Search for "bin2c"找到一些。

您只需在构建过程中包含这些“资产构建”步骤,即从Makefile中调用该工具。这也意味着只有在源数据发生变化时才会运行该工具,这很不错。

至少GNU链接器(LD)似乎能够将文件放在输出文件的各个部分中(参见Section Placement documentation,如下所示:

.data : { afile.o bfile.o cfile.o }

但这听起来很麻烦,需要你考虑一下你的可执行文件中经常有点太低级的部分。此外,它似乎要求输入是目标文件,由于通用二进制资产不是与链接器兼容的目标文件,因此这种问题是循环的。

我建议使用bin2c方法。

答案 1 :(得分:1)

您可以使用链接器选项--format-Wl,将其传递给链接器,例如:

gcc -Wl,--format=binary -Wl,myfile.bin -Wl,--format=default

默认的上次设置格式允许您将链接器切换回标准输入格式。

您可以通过简单的_binary_myfile_bin_start汇编程序符号(适用于myfile.binxxx.yyy它将_binary_xxx_yyy_start_binary_xxx_yyy_end)来源,从来源访问您的二进制资源:

extern uint8_t data[] asm("_binary_myfile_bin_start");

接下来使用data。比自己做objcopy或使用资源黑客更好。

UPD:扩展一个小例子 - main输出自己的目标文件的前四个字节:

#include "stdio.h"
#include "stdint.h"

extern uint8_t data[] asm("_binary_main_o_start");

int
main(void)
{
  fprintf(stdout, "0x%x, 0x%x, 0x%x, 0x%x\n", data[0], data[1], data[2], data[3]);
  return 0;
}

现在编译一个运行:

$ gcc -o main.o -c main.c 
$ gcc -o main main.o -Wl,--format=binary -Wl,main.o -Wl,--format=default
$ ./main 
0x7f, 0x45, 0x4c, 0x46