利用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 <stdio.h>
#include <stdlib.h>

/* 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;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章