Elfがbinに変換されるとbinファイルが大きくなる問題

2251 ワード

先の記事『位置無関係コード(PIC)の思考』では、elfファイルをbinファイルに変換する過程で、出力セグメントとセグメントの間に隙間があれば、objcopyは0でセグメントとセグメントの間の隙間を埋め、objcopyのオプションであるgap-fill=valでチャージする内容をvalとして作成することもでき、これはelfファイルよりbinファイルが大きいという問題を引き起こし、多くの組み込み機器では受け入れられない.組み込み機器は通常、プログラムをbin焼に変換してFLASHに書くため、スペースを節約することを目的としているが、結果は確かにスペースを大幅に浪費している.
まず簡単な例でこの問題を説明します.
    1. boot.sファイル、シミュレーションbootloader、コードは以下の通りです.
  .extern _entry
  .globl _start
  .text
  _start:                                                                                         
      jmp _entry
~                 
   2. main.sファイル、シミュレーションアプリケーションまたはosミラー、コードは以下の通りです.
  .text
  .globl _entry
  _entry:
      mov $1, %eax                                                                                
  

3.リンクスクリプトファイル(boot.lds):
OUTPUT_ARCH(i386)
  ENTRY(_start)
  
  SECTIONS
  {
      . = 0x0; 
  
      . = ALIGN(4);
      .boot 0x0 :      ;bootloader   ROM     ,      
      {
          boot.o(.text)
      }
  
      . = ALIGN(4);                                                                               
      .text 0x10000   :    ;     os     RAM , bootloader ROM    RAM 
      {
          _tstart = .;
  
          *(.text)
     }
  
      . = ALIGN(4);
      .data : {*(.data)}
      _bss_start = .;
      .bss : {*(.bss)}
  }

次にリンクの上の2つをコンパイルする.sファイルを生成しbinファイルを生成するには、次の手順に従います.
gcc -c -g boot.s
gcc -c -g main.s
ld boot.o main.o -o bootelf -Tboot.lds -Map boot.map --gap-fill=0xff   /*    0,  ff    */
objcopy -O binary bootelf bootbin.bin 

その中で-map boot.mapはシンボルテーブルを生成し、いくつかの情報を表示しやすくします.次に、生成された各ファイルのサイズの断面図を示します.
図からbootbinが見えます.binのサイズはbootelfよりはるかに大きく、次にファイルのサイズを計算します.
1.まずbootbinを見てみましょう.binファイルの内容:hexdump bootbin.bin
0 x 10~0 x 100000の間に0 xffが充填されているからbinファイルが大きくなり、その大きさはちょうど0 x 100000+5バイトであり、mapファイルから算出できることがわかる.
問題の根源を明らかにし、解決策を分析する.
1.ldsファイルの書き方の問題
このように書くと、どのコードがROMで実行されているのか、どのコードがRAMで実行されているのかを明らかにすることができるが、追加のREGIONを追加することによって実現され、「位置無関係コード(PIC)の考え方」ではldsファイルの書き方、すなわちROMで実行されているコードもRAMアドレス空間に置く、なぜ、前にも述べたように.
2.objcopy充填の問題
objcopyはmapファイルやelfファイル帳の情報でbinファイルを再スペルすることができますが、この問題objcopyには専門的な選択肢がないようで、自分でスクリプトでbinファイルのスペルを実現する必要があります