Linux命令學習手冊-objcopy命令

objcopy [選項]... 輸入文件 [輸出文件] 


[功能] 

將目標文件的一部分或者全部內容拷貝到另外一個目標文件中,或者實現目標文件的格式轉換。 


[描述] 

objcopy工具使用BFD庫讀寫目標文件,它可以將一個目標文件的內容拷貝到另外一個目標文件當中。objcopy通過它的選項來控制其不同的動作,它可以將目標文件拷貝成和原來的文件不一樣的格式。需要注意的是objcopy能夠在兩種格式之間拷貝一個完全鏈接的文件,在兩種格式之間拷貝一個可重定位的目標文件可能不會正常地工作。 

objcopy在做轉換的時候會創建臨時文件,然後將這些臨時文件刪除。objcopy使用BFD來做它所有的轉換工作;它訪問BFD中描述的所有格式,可以不必指定就識別大多數的格式。 

通過指定輸出目標爲srec(例如 -O srec),objcopy可以用來生成S-record文件。 

通過指定輸入目標爲而進制文件(例如-O binary),objcopy可以生成原始格式的二進制文件。當objcopy生成一個原始格式的二進制文件的時候,它會生成輸入的目標文件的基本內存拷貝,然後所有的標號和可重定位信息都會被去掉。內存拷貝開始於最低段的加載地址,拷貝到輸出文件。 

當生成一個S-record或者原始的二進制文件的時候,可以使用-S這個很有用的選項選項來移除一些包含調試信息的節。有時-R可以用來移除一些二進制文件不需要的節。 

注意:objcopy工具不能用來改變文件的大端和小端屬性。 


命令參數: 

infile/outfile 

源文件/目標文件,如果不指定目標文件那麼objcopy將會創建一個臨時文件,並且將其命名爲源文件。 


命令項: 

-I bfdname 

--input-target=bfdname 

指定輸入文件的bfdname,可取值elf32-little,elf32-big等。 


-O bfdname 

--output-target=bfdname 

指定輸出文件的bfdname 


-F bfdname 

--target=bfdname 

指定輸入、輸出文件的bfdname,目標文件格式,只用於在目標和源之間傳輸數據,不轉換。 


-j sectionname 

--only-section=sectionname 

只將由sectionname指定的section拷貝到輸出文件,可以多次指定,並且注意如果使用不當會導致輸出文件不可用。 


-R sectionname 

--remove-section=sectionname 

從輸出文件中去除掉由sectionname指定的section,可以多次指定,並且注意如果使用不當會導致輸出文件不可用。 


-S 

--strip-all 

不從源文件拷貝符號信息和relocation信息。 


-g 

--strip-debug 

不從源文件拷貝調試符號信息和相關的段。對使用-g編譯生成的可執行文件執行之後,生成的結果幾乎和不用-g進行編譯生成可執行文件一樣。 


--strip-unneeded 

去掉所重定位處理不需要的符號。 


-K symbolname 

--keep-symbol=symbolname 

strip的時候,保留由symbolname指定的符號信息。可以指定多次。 


-N symbolname 

--strip-symbol=symbolname 

不拷貝由symbolname指定的符號信息,可以多次指定。 


-G symbolname 

--keep-global-symbol=symbolname 

只保留symbolname爲全局的,讓其他的都是文件局部的變量這樣外部不可見,這個選項可以多次指定。 


-L symbolname 

--localize-symbol=symbolname 

將變量symbolname變成文件局部的變量。可以多次指定。 


-W symbolname 

--weaken-symbol=symbolname 

弱化變量。 


--globalize-symbol=symbolname 

讓變量symbolname變成全局範圍,這樣它可以在定義它的文件外部可見。可以多次指定。 


-w 

--wildcard 

允許對其他命令行項中的symbolnames使用正則表達式。問號(?),星號(*),反斜線(\),和中括號([])操作可以用在標號名稱的任何位置。如果標號的第一個字符是感嘆號(!),那麼表示相反的含義,例如: 

-w -W !foo -W fo* 

表示objcopy將要弱化所有以"fo"開頭的標號,但是除了標號"foo"。 


-x 

--discard-all 

不從源文件中拷貝非全局變量。 


-X 

--discard-locals 

不拷貝編譯生成的局部變量(一般以L或者..開頭)。 


-b byte 

--byte=byte 

只保留輸入文件的每個第byte個字節(不會影響頭部數據)。byte的範圍可以是0到interleave-1。這裏,interleave通過-i選項指定,默認爲4。將文件創建成程序rom的時候,這個命令很有用。它經常用於srec輸出目標。 


-i interleave 

--interleave=interleave 

每隔interleave字節拷貝1 byte。通過-b選項指定選擇哪個字節,默認爲4。如果不指定-b那麼objcopy會忽略這個選項。 


--gap-fill val 

在section之間的空隙中填充val, 


--set-start val 

設定新文件的起始地址爲val,並不是所有格式的目標文件都支持設置起始地址。 


--change-start incr 

--adjust-start incr 

通過增加incr量來調整起始地址,並不是所有格式的目標文件都支持設置起始地址。 


--change-address incr 

--adjust-vma incr 

通過增加incr量調整所有sections的VMA(virtual memory address)和LMA(linear memory address),以及起始地址。 


--change-section-address section{=,+,-}val 

--adjust-section-vma section{=,+,-}val 

調整指定section的VMA/LMA地址。 


--set-section-flags section=flag 

指定指定section的flag,flag的取值可以alloc,contents, load, noload, readonly, code, data, rom, share, debug。我們可以設置一個沒有內容的節的flag,但是清除一個有內容的節的flag是沒有意義的--應當把相應的節移除。並不是所有的flags對於所有的目標文件都有意義。 


--add-section sectionname=filename 

在拷貝文件的時候,添加一個名爲sectionname的section,該section的內容爲filename的內容,大小爲文件大小。這個選項只在那些可以支持任意名稱section的文件好用。 


--rename-section oldname=newname[,flags] 

更改section的名 

將一個section的名字從oldname更改爲newname,同時也可以指定更改其flags。這個在執行linker腳本進行重命名的時候,並且輸出文件還是一個目標文件並不成爲可執行的連接文件,這個時候很有優勢。 

這個項在輸入文件是binary的時候很有用,因爲這經常會創建一個名稱爲.data的section,例如,你想創建一個名稱爲.rodata的包含二進制數據的section,這時候,你可以使用如下命令: 

objcopy -I binary -O <output_format> -B <architecture> \ 

--rename-section .data=.rodata,alloc,load,readonly,data,contents \ 

<input_binary_file> <output_object_file> 


--add-gnu-debuglink=path-to-file 

創建一個.gnu_debuglink節,這個節包含一個特定路徑的文件引用,並且把它添加到輸出文件中。 


--only-keep-debug 

對文件進行strip,移走所有不會被--strip-debug移走的section,並且保持調試相關的section原封不動。 

這個項應該和--add-gnu-debuglink選項一起使用,創建一個兩部分的可執行文件。一個是已經被stripped的佔用RAM空間以及發佈的大小很小的二進制文件,另一個是調試信息文件,這個信息只有在調試的時候會用到。建立這樣的兩個文件的步驟如下: 

a.像正常那樣鏈接可執行文件,foo 

b.運行"objcopy --only-keep-debug foo foo.dbg"創建一個包含調試信息的文件 

c.運行"objcopy --strip-debug foo"創建一個去掉調試信息的(strip的)可執行文件 

d.運行"objcopy --add-gnu-debuglink=foo.dbg foo",爲strip的文件添加調試信息鏈接。 

注意這裏擇".dbg"擴展名是任意的,"--only-keep-debug"的步驟也是可選的,你也可以這樣做: 

a.像正常那樣鏈接可執行文件,foo 

b.將"foo"拷貝爲"foo.full" 

c.運行"objcopy --strip-debug foo" 

d.運行"objcopy --add-gnu-debuglink=foo.full foo" 

可見,使用--add-gnu-debuglink添加調試信息的可以是完全的可執行文件,不用非得用"--only-keep-debug"創建。 

注意 這個只能用於完全鏈接的文件,對於一個目標文件來說這個功能沒有意義,因爲調試信息可能不完整。另外,gnu_debuglink特性當前一個包含調試信息的文件,不能多個文件用於每個文件一個目標文件。 


-V 

--version 

顯示objcopy的版本號。 


@file 可以將選項集中到一個文件中,然後使用這個@file選項載入。 


[舉例] 

a)後面的測試,我們查看採用的源代碼如下: 

[root@lv-k cppDemo]# cat main.cpp 

#include <iostream> 

using std::cout; 

using std::endl; 

void my_print(); 


int main(int argc, char *argv[]) 

        my_print(); 

        cout<<"hello!"<<endl; 

        return 0; 


void  my_print() 

        cout<<"print!"<<endl; 

b)對以上源代碼進行編譯,生成不含調試信息的可執行文件如下: 

[root@lv-k cppDemo]# g++ main.cpp -o main 


c)生成包含調試信息的可執行文件如下: 

[root@lv-k cppDemo]# g++ -g main.cpp -o main.debug 


d)採用"readelf -S main"查看其段信息如下: 

[root@lv-k cppDemo]# readelf -S main 

There are 29 section headers, starting at offset 0xca0: 


Section Headers: 

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 

  [ 0]                   NULL            00000000 000000 000000 00      0   0  0 

  [ 1] .interp           PROGBITS        08048134 000134 000013 00   A  0   0  1 

  [ 2] .note.ABI-tag     NOTE            08048148 000148 000020 00   A  0   0  4 

  [ 3] .gnu.hash         GNU_HASH        08048168 000168 000030 04   A  4   0  4 

  [ 4] .dynsym           DYNSYM          08048198 000198 0000d0 10   A  5   1  4 

  [ 5] .dynstr           STRTAB          08048268 000268 000183 00   A  0   0  1 

  [ 6] .gnu.version      VERSYM          080483ec 0003ec 00001a 02   A  4   0  2 

  [ 7] .gnu.version_r    VERNEED         08048408 000408 000060 00   A  5   2  4 

  [ 8] .rel.dyn          REL             08048468 000468 000010 08   A  4   0  4 

  [ 9] .rel.plt          REL             08048478 000478 000048 08   A  4  11  4 

  [10] .init             PROGBITS        080484c0 0004c0 000017 00  AX  0   0  4 

  [11] .plt              PROGBITS        080484d8 0004d8 0000a0 04  AX  0   0  4 

  [12] .text             PROGBITS        08048580 000580 000268 00  AX  0   0 16 

  [13] .fini             PROGBITS        080487e8 0007e8 00001c 00  AX  0   0  4 

  [14] .rodata           PROGBITS        08048804 000804 00001a 00   A  0   0  4 

  [15] .eh_frame_hdr     PROGBITS        08048820 000820 000044 00   A  0   0  4 

  [16] .eh_frame         PROGBITS        08048864 000864 00010c 00   A  0   0  4 

  [17] .ctors            PROGBITS        08049970 000970 00000c 00  WA  0   0  4 

  [18] .dtors            PROGBITS        0804997c 00097c 000008 00  WA  0   0  4 

  [19] .jcr              PROGBITS        08049984 000984 000004 00  WA  0   0  4 

  [20] .dynamic          DYNAMIC         08049988 000988 0000e0 08  WA  5   0  4 

  [21] .got              PROGBITS        08049a68 000a68 000004 04  WA  0   0  4 

  [22] .got.plt          PROGBITS        08049a6c 000a6c 000030 04  WA  0   0  4 

  [23] .data             PROGBITS        08049a9c 000a9c 000004 00  WA  0   0  4 

  [24] .bss              NOBITS          08049aa0 000aa0 000098 00  WA  0   0  8 

  [25] .comment          PROGBITS        00000000 000aa0 000114 00      0   0  1 

  [26] .shstrtab         STRTAB          00000000 000bb4 0000e9 00      0   0  1 

  [27] .symtab           SYMTAB          00000000 001128 000510 10     28  53  4 

  [28] .strtab           STRTAB          00000000 001638 0003f4 00      0   0  1 

Key to Flags: 

  W (write), A (alloc), X (execute), M (merge), S (strings) 

  I (info), L (link order), G (group), x (unknown) 

  O (extra OS processing required) o (OS specific), p (processor specific) 


*將文件轉換成S-record格式: 

[root@lv-k cppDemo]#objcopy -O srec main main.srec 

這裏,如果不指定main.srec那麼會改變原來的文件,轉換通常涉及到text段,也可以轉換.o文件。當然,轉換之後的文件不能直接運行了。在生成s-record過程中,有時需要用選項“-S”,“-R”去除掉binary文件,s-record文件不需要的相應信息。 

輸出的文件內容類似如下: 

[root@lv-k cppDemo]# head main.rec 

S00B00006D61696E2E726563E7 

S315080481342F6C69622F6C642D6C696E75782E736F57 

S308080481442E3200C6 

S31508048148040000001000000001000000474E550016 

S3150804815800000000020000000600000009000000F4 

S3150804816803000000090000000100000005000000E3 

S31508048178012A102100000000090000000B00000075 

S31508048188AC4BE3C021FDF40914980C4379496BB642 

S3150804819800000000000000000000000000000000C5 

S315080481A83701000000000000540000001200000017 

...省略... 

可見srec格式的文件是文本形式的。 


*將文件轉換成rawbinary格式: 

[root@lv-k cppDemo]# objcopy -O binary main main.bin 

這裏同樣,轉換之後的main.bin也是不可直接運行的。比較一下三種格式文件的大小: 

[root@lv-k cppDemo]# ls -l main main.rec main.bin 

-rwxr-xr-x 1 root root 6700 07-07 18:04 main 

-rwxr-xr-x 1 root root 6508 07-19 16:42 main.bin 

-rwxr-xr-x 1 root root 7366 07-19 16:34 main.rec 

將object文件轉換成raw binary格式時,通常將去除掉symbols和relocation信息。 


*生成一個不含重定位以及標號目標文件: 

[root@lv-k cppDemo]# objcopy -S main main.stripall 

這裏,生成的文件,仍然可以運行。查看大小對比如下: 

[root@lv-k cppDemo]# ls -l main.stripall main 

-rwxr-xr-x 1 root root 6700 07-07 18:04 main 

-rwxr-xr-x 1 root root 4296 07-19 17:02 main.stripall 

經過實踐,如果對包含調試信息的可執行文件進行這樣的操作,生成的文件大小一樣。 

可以對比main的信息,查看文件的段信息: 

[root@lv-k cppDemo]#  readelf main.stripall -S 

There are 27 section headers, starting at offset 0xc90: 


Section Headers: 

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 

  [ 0]                   NULL            00000000 000000 000000 00      0   0  0 

  [ 1] .interp           PROGBITS        08048134 000134 000013 00   A  0   0  1 

  [ 2] .note.ABI-tag     NOTE            08048148 000148 000020 00   A  0   0  4 

  [ 3] .gnu.hash         GNU_HASH        08048168 000168 000030 04   A  4   0  4 

  [ 4] .dynsym           DYNSYM          08048198 000198 0000d0 10   A  5   1  4 

  [ 5] .dynstr           STRTAB          08048268 000268 000183 00   A  0   0  1 

  [ 6] .gnu.version      VERSYM          080483ec 0003ec 00001a 02   A  4   0  2 

  [ 7] .gnu.version_r    VERNEED         08048408 000408 000060 00   A  5   2  4 

  [ 8] .rel.dyn          REL             08048468 000468 000010 08   A  4   0  4 

  [ 9] .rel.plt          REL             08048478 000478 000048 08   A  4  11  4 

  [10] .init             PROGBITS        080484c0 0004c0 000017 00  AX  0   0  4 

  [11] .plt              PROGBITS        080484d8 0004d8 0000a0 04  AX  0   0  4 

  [12] .text             PROGBITS        08048580 000580 000268 00  AX  0   0 16 

  [13] .fini             PROGBITS        080487e8 0007e8 00001c 00  AX  0   0  4 

  [14] .rodata           PROGBITS        08048804 000804 00001a 00   A  0   0  4 

  [15] .eh_frame_hdr     PROGBITS        08048820 000820 000044 00   A  0   0  4 

  [16] .eh_frame         PROGBITS        08048864 000864 00010c 00   A  0   0  4 

  [17] .ctors            PROGBITS        08049970 000970 00000c 00  WA  0   0  4 

  [18] .dtors            PROGBITS        0804997c 00097c 000008 00  WA  0   0  4 

  [19] .jcr              PROGBITS        08049984 000984 000004 00  WA  0   0  4 

  [20] .dynamic          DYNAMIC         08049988 000988 0000e0 08  WA  5   0  4 

  [21] .got              PROGBITS        08049a68 000a68 000004 04  WA  0   0  4 

  [22] .got.plt          PROGBITS        08049a6c 000a6c 000030 04  WA  0   0  4 

  [23] .data             PROGBITS        08049a9c 000a9c 000004 00  WA  0   0  4 

  [24] .bss              NOBITS          08049aa0 000aa0 000098 00  WA  0   0  8 

  [25] .comment          PROGBITS        00000000 000aa0 000114 00      0   0  1 

  [26] .shstrtab         STRTAB          00000000 000bb4 0000d9 00      0   0  1 

Key to Flags: 

  W (write), A (alloc), X (execute), M (merge), S (strings) 

  I (info), L (link order), G (group), x (unknown) 

  O (extra OS processing required) o (OS specific), p (processor specific) 

由此可見去掉的兩個信息分別是: 

  [27] .symtab           SYMTAB          00000000 001128 000510 10     28  53  4 

  [28] .strtab           STRTAB          00000000 001638 0003f4 00      0   0  1 


*去掉指定名稱的節: 

[root@lv-k cppDemo]# objcopy -R .comment main main.remove 

這裏,去掉之後,可執行文件也是可以運行的。通過"readelf -S main.remove"可知,其中的.comment節已經沒有了。和此“相反”的操作是通過-j將指定的節拷貝到目標文件。 


*添加一個自定義的節到可執行文件並將一個文件內容添加到其中: 

[root@lv-k cppDemo]# objcopy --add-section mysection=hello_text main main.add 

這樣,將會創建一個mysection的節並把hello_text的內容添加到其中。通過readelf -S main.add可以看到會多了一個"mysection"節。這個選項只在那些可以支持任意名稱section的文件好用。添加到在我的centeros中編譯的可執行文件中,可執行文件仍然可以運行。 


*將指定的段拷貝出來: 

[root@lv-k cppDemo]# objcopy -j mysection main.add section_hello 

輸入之後,輸出如下: 

[root@lv-k cppDemo]# objcopy -j mysection main.add section_hello 

BFD: main.add: warning: Empty loadable segment detected, is this intentional ? 


BFD: main.add: warning: Empty loadable segment detected, is this intentional ? 


這樣會將main.add中剛纔添加的mysection拷貝出來,拷貝出來的內容存放在section_hello文件中。這個命令將指定的section拷貝到輸出文件,可以多次指定,並且注意如果使用不當會導致輸出文件不可用。通過file命令查看,發現生成的文件仍然是elf文件,不只有該段的內容。使用"readelf -S section_hello"查看文件內容,如下: 

There are 5 section headers, starting at offset 0x144: 


Section Headers: 

[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al 

[ 0]                   NULL            00000000 000000 000000 00      0   0  0 

[ 1] mysection         PROGBITS        00000000 0000f4 000028 00      0   0  1 

[ 2] .shstrtab         STRTAB          00000000 00011c 000025 00      0   0  1 

[ 3] .symtab           SYMTAB          00000000 00020c 000020 10      4   2  4 

[ 4] .strtab           STRTAB          00000000 00022c 000001 00      0   0  1 

Key to Flags: 

W (write), A (alloc), X (execute), M (merge), S (strings) 

I (info), L (link order), G (group), x (unknown) 

O (extra OS processing required) o (OS specific), p (processor specific) 

readelf: Error: no .dynamic section in the dynamic segment 


**分離可執行文件以及調試信息並將兩者關聯 

這裏,main.debug是包含調試信息的可執行文件(使用"gcc -g"編譯生成),爲了減小文件大小,並且同樣可以進行調試,將可執行文件分成兩個部分:將其中的調試信息提取出來之後保存成一個文件,再生成去掉調試信息的大小減少了的可執行文件,最後通過鏈接的形式將兩個文件關聯。 

過程如下: 

1)生成調試信息文件: 

[root@lv-k cppDemo]# objcopy --only-keep-debug main.debug main.debuginfo 

這樣,會將調試信息提取,保存到文件main.debuginfo中。執行之後比較文件大小如下: 

[root@lv-k cppDemo]# ls -l main.debuginfo main main.debug 

-rwxr-xr-x 1 root root  6700 07-07 18:04 main 

-rwxr-xr-x 1 root root 38932 07-07 18:04 main.debug 

-rwxr-xr-x 1 root root 38628 07-21 09:47 main.debuginfo 

這裏,main是沒有使用-g命令生成的可執行文件只是爲了比較。 


2)生成不含調試信息的可執行文件: 

[root@lv-k cppDemo]# objcopy --strip-debug main.debug main.stripdebug 

這樣,就將原來可執行文件中的調試信息去掉,結果可執行的不含調試信息的可執行文件。生成之後,大小如下: 

[root@lv-k cppDemo]# ls -l main main.debug main.stripdebug 

-rwxr-xr-x 1 root root  6700 07-07 18:04 main 

-rwxr-xr-x 1 root root 38932 07-07 18:04 main.debug 

-rwxr-xr-x 1 root root  6632 07-21 09:49 main.stripdebug 


3)爲不含調試信息的可執行文件添加調試信息: 

[root@lv-k cppDemo]# objcopy --add-gnu-debuglink=main.debuginfo main.stripdebug 

這樣,就爲main.stripdebug文件添加了調試信息,現在可以運行"gdb main.stripdebug"進行調試了。運行完畢之後,main.stripdebug文件中會多了一個"[26] .gnu_debuglink    PROGBITS        00000000 000bb4 000014 00      0   0  1"節。運行這個命令之後,文件大小信息對比如下: 

[root@lv-k cppDemo]# ls -l main main.debug main.debuginfo main.stripdebug 

-rwxr-xr-x 1 root root  6700 07-07 18:04 main 

-rwxr-xr-x 1 root root 38932 07-07 18:04 main.debug 

-rwxr-xr-x 1 root root 38628 07-21 09:47 main.debuginfo 

-rwxr-xr-x 1 root root  6720 07-21 09:51 main.stripdebug 

注意,實踐發現:a)使用上面的命令之後,main.debuginfo以及源代碼main.cpp兩個文件必須在同一個目錄上面才能使用gdb進行調試,否則會在調試的時候出現找不到文件的問題。當然,就是使用-g的選項編譯之後,也得讓源文件放在正確的路徑下面才能夠在調試的時候載入文件。b)對於原來沒有使用-g生成的可執行文件,也可以使用這個方法爲它添加調試信息讓它(原來沒有用-g生成的並且添加調試信息之後的可執行文件)可以調試。 

** 


[其它] 

1,關於可執行文件格式

不同的嵌入式環境中,其組織可執行文件的格式也不相同,主要以下幾種:ELF文件格式、S-record文件格式、HEX文件格式、bin文件格式。 


1)BIN文件格式 

原始的二進制格式,內部沒地址標記,直接照二進制格式下載,並且照絕對地址燒寫到Flash中就可以啓動了,而如果下載運行,則下載到編譯時的地址即可。 


2)ELF文件格式(Executable and linking format) 

Executable and linking format(ELF)文件是Linux系統 下的一種常用、可移植目標文件(object file)格式,它有三種主要類型: 

可重定位文件(Relocatable File):包含適合於與其他目標文件鏈接來創建可執行文件或者共享目標文件的代碼和數據。 

可執行文件(Executable File):包含適合於執行的一個程序,此文件規定了exec() 如何創建一個程序的進程映像。 

共享目標文件(Shared Object File):包含可在兩種上下文中鏈接的代碼和數據。首先鏈接編輯器可以將它和其它可重定位文件和共享目標文件一起處理,生成另外一個目標文件。其次,動態鏈接器(Dynamic Linker)可能將它與某個可執行文件以及其它共享目標一起組合,創建進程映像。 


3)S-Record文件格式 

S-Record文件遵循Motorola制定的格式規範,是一種標準的、可打印格式的文件。 S-Record文件是通過對鏈接器生成的目標程序或 數據進行編碼生成的,適用於在計算機平臺間傳送,也可以在編輯後用於交叉平臺間的傳送。S-Record文件編碼簡單,可以通過IDE下載,但無法在線實時調試。S-Record文件是由多條記錄組成的,每條記錄都是由5個字段組成的ASCII字符串。 


4)HEX文件格式 

Intel HEX文件是記錄文本行的ASCII文本文件,在Intel HEX文件中,每一行是一個HEX記錄,由十六進制數組成的機器碼或者數據常量。Intel HEX文件經常被用於將程序或數據傳輸 存儲到ROM、EPROM。大多數編程器和模擬器使用Intel HEX文件。 


5)可執行文件格式的差別 

a)HEX文件是包括地址信息的,而BIN文件格式只包括了數據本身,在燒寫或下載HEX文件的時候,一般都不需要用戶指定地址,因爲HEX文件內部的信息已經包括了地址。而燒寫BIN文件的時候,用戶是一定需要指定地址信息的。 

b)BIN文件格式 對二進制文件而言,其實沒有”格式”。文件只是包括了純粹的二進制數據。 

c)HEX文件格式 HEX文件都是由記錄(RECORD)組成的。在HEX文件裏面,每一行代表一個記錄。記錄類型包括:記錄數據域,文件結束域,擴展線性地址的記錄,擴展 段地址的記錄。在上面的後2種記錄,都是用來提供地址信息的。每次碰到這2個記錄的時候,都可以根據記錄計算出一個“基”地址。對於後面的數據記錄,計算 地址的時候,都是以這些“基”地址爲基礎的。 

d)AXF是Arm特有的文件格式,它除了包含bin文件外,還額外包括了許多其他調試信息。在下載到目標板的時候,燒入ROM還是bin文件,額外的調試信息會被去掉 


一般來說,可以由elf文件轉化爲其它兩種文件,hex也可以直接轉換爲bin文件,但是bin要轉 化爲hex文件必須要給定一個基地址。而hex和bin不能轉化爲elf文件,因爲elf的信息量要大。另外還有一種ads的調試文件axf,它可以用以 下命令fromelf -nodebug xx.axf -bin xx.bin轉化爲bin文件。 


2,將圖像編譯到可執行文件內(不知道有什麼作用) 

Q: 如何將一個二進制文件,比如圖片,詞典一類的東西做爲.o文件,直接鏈接到可執行文件內部呢? 

A: 

$ objcopy -I binary -O elf32-i386 -B i386 14_95_13.jpg image.o 

$ gcc image.o tt.o -o tt 

$ nm tt | grep 14_95 

0805d6c7 D _binary_14_95_13_jpg_end 

00014213 A _binary_14_95_13_jpg_size 

080494b4 D _binary_14_95_13_jpg_start 


參考: 

http://www.cnblogs.com/amethyst623/articles/1946499.html 

http://linux.chinaunix.net/techdoc/develop/2007/10/29/970892.shtml 

http://blog.csdn.net/gogofly_lee/article/details/2636257 


轉自:http://blog.chinaunix.net/uid-9525959-id-2001841.html

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