利用objcopy将文件附加到程序中

       当我们编制的程序需要调用图片或者mp3等媒体文件时, 通常是将相应的文件预先存放在指定的目录位置,程序运行时才可以被找到.其实还有一种更方便的办法,那就是将音乐或者图像文件直接插入到程序文件的某个段中. 程序启动时,先将这些文件释放出来,然后主程序就可以使用它了.
       这个方法在<<程序员的自我修养>>里面有阐述,但是它并没有具体说明如何将文件释放出来. 在Openwrt widora平台上试验了多次,终于成功. 分享具体步骤如下:
   1. 用objcopy将一个lake.jpg文件转换成OBJ文件pridata.o:
     1.1 执行 cross-objcopy -I binary -O elf32-tradlittlemips -B mips lake.jpg pridata.o    

    1.2 数据被加入到pridata.o文件的.data段中, 用objdump命令查看生成的pridata.o文件,可以看到有_binary_lake_jpg_start,_binary_lake_jpg_end,_binary_lake_jpg_end 等符号, 分别代表了数据的起始地址,结束地址和长度.
     1.3 这里要注意: 文件应该放在当前目录中, 不然生成的符号名会比较长, 比如 "../data/lake.jpg" 的对应符号名将会是 _binary____data_lake_jpg_xxxx

   2. 将主程序test_elf.c和pridata.o一起生成最终的执行文件test_elf:
    cross-gcc -o test_elf test_elf.c pridata.o

   3. 在目标嵌入式板子中执行test_elf, 程序将恢复该文件为/tmp/lake.jpg.

  4.  源头文件  test_elf.c

/*------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.

Midas Zhou
-------------------------------------------------------------------*/
#include 
#include 

/* Note: All symbol value are parsed as address after ld */
extern char _binary_lake_jpg_start[];
extern char _binary_lake_jpg_end[];
extern const char _binary_lake_jpg_size[];

int main(void)
{
        FILE *fp;
        unsigned long size;

        printf("offset: _binary_lake_jpg_start=%p \n", _binary_lake_jpg_start );
        printf("offset: _binary_lake_jpg_start=%p \n", _binary_lake_jpg_start );
        printf("size=%d, or 0x%x \n", (int)_binary_lake_jpg_size, (int)_binary_lake_jpg_size);

        size=(int)_binary_lake_jpg_size;

        fp=fopen("/tmp/lake.jpg", "w");
        if(fp == NULL ) {
                perror("open file");
                exit(-1);
        }

        fwrite( (char *)_binary_lake_jpg_start, size, 1, fp);

        fclose(fp);

        return 0;
}


 

你可能感兴趣的:(Linux,widora,Openwrt)