5

特定の場所で Linux イメージを DRAM にロードしようとしています。DRAM の終了アドレスは 0x80000000 であり、「メモリ デバイスの終了アドレスは 0x80000000 です」というブート ログからわかります。アドレス「0x5000000」にイメージをロードしています。そして、その前に、イメージのさまざまなセクションが「0x80000000」より大きいアドレスにロードされます。

 loading section to address 0xc5000000 from file position 0x1000, size is 0x5ac13e

上記の行の「ファイル位置0x1000から」の意味は何ですか。

読み込まれた最初のセクションは .text セクションです。以下は、セクション ヘッダーの vmlinux イメージ ダンプです。

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

[ 0]                     NULL            00000000 000000 000000 00      0   0  0

 [ 1]   .text            PROGBITS        c5000000 001000 5ac13e 00  AX  0   0 4096

 [ 2]      .notes           NOTE            c55ac140 5ad140 000168 00  AX  0   0  4

 [ 3]    __ex_table        PROGBITS        c55ac2b0 5ad2b0 000fe0 00   A  0   0  4

 [ 4]   .rodata           PROGBITS        c55ae000 5af000 20a930 00   A  0   0 64

 [ 5]   __bug_table       PROGBITS        c57b8930 7b9930 0075fc 00   A  0   0  1

 [ 6]   .pci_fixup        PROGBITS        c57bff2c 7c0f2c 001a90 00   A  0   0  4

 [ 7]    .builtin_fw       PROGBITS        c57c19bc 7c29bc 0000cc 00   A  0   0  4

非常に大きなリストなので、完全には投稿できませんでした。しかし、ここでわかることの 1 つは、.text セクションが DRAM の終了アドレスよりも大きいため、保持されている最初のセクションをロードした後にエラーが発生していないにもかかわらず、イメージが適切にロードされないことです。他のセクションをロードすると、このメッセージの後にハングします。

    program load complete, entry point: 0x5000000, size: 0x92e7fc

私の質問は、これらの異なるセクション アドレスを DRAM アドレスに合わせる方法です。ここで objcopy ユーティリティを使用して、これらの異なるセクションのアドレスを変更できますか。

コンパイル前にこれらのセクション アドレスを設定する方法はありますか?? 2 つ目は、プログラムの読み込みが完了した後にハングアップする理由です。

4

3 に答える 3

6

from file position 0x1000それが言うことを意味します。あなたはそれをダンプに持っています:

[Nr]      Name           Type            Addr     Off    Size   ES Flg Lk Inf Al
...
[ 1]   .text            PROGBITS        c5000000 001000 5ac13e 00  AX  0   0 4096

これ.textは、ファイル内のオフセットでセクションが始まる場所0x1000です。

しかし、ここで確認できることの1つは、.textセクションがDRAMの終了アドレスよりも大きいことです。

いいえ、それは大きくはありません(少なくとも、大きくなるという意味ではありません) 0xc5000000。メモリ内のアドレスにロードされることを期待してコンパイルされます。

したがって、最初のセクションをロードした後もエラーは発生しませんが、他のセクションをロードし続けますが、画像は適切にロードされないはずです。

画像はどこにでもロードできます。ロードするための単なるデータです。

OTOH、loading section to address 0xc5000000それが言うことを意味する場合、RAMがで終了するため、ファイルはどこにもロードされません0x7fffffff

しかし、このメッセージの後、それはハングします。

そして、それは予想されます。マシンコードが位置に依存しないことはめったにないため、ロードされるはずの場所とは異なる場所にロードすると、機能しません。または、ロードされない場合は、何を実行しますか?ごみ。

コンパイル前にこれらのセクションアドレスを設定する方法はありますか?

システムに応じて、以下の2つのオプションのいずれかまたは両方を使用できます。

  • プログラム全体の仮想アドレスからの仮想アドレスと、プログラム全体の0xc5000000物理アドレスからの物理アドレスにマップされるように、ページ変換を設定します。0x5000000
  • コンパイラが使用しているリンカスクリプトを見つけて、最初のセクションアドレスをから0xc5000000に変更します。0x5000000これをグーグルで検索します。コンパイラ/リンカのドキュメントを参照してください。

また、エントリポイントがにあるのは少し奇妙です0x5000000。これが必ずしも間違っているというわけではありません。それはめったにないということだけです。startラベル(または_startそれが何であれ)が実際にセクションの先頭と同じアドレスを受け取ることを確認し.textます。何らかの理由でそうでない場合は、リンカスクリプト、コンパイラ/リンカのコマンドラインオプション、またはローダーに問題があります。

于 2013-03-20T11:27:43.127 に答える
3

ローダーは何をお使いですか?「イメージ」の形とは?U-boot イメージ、生のイメージ、vmlinux ELF ファイル? セクションの存在などから判断すると、最後のものだと思います。ELF ファイルからは、セクションではなく、いわゆるプログラム ヘッダーをロードする必要があります。たとえば、これは OpenRISC linux カーネル プログラム ヘッダーのリストです (を使用して取得readelf -l):

Elf file type is EXEC (Executable file)
Entry point 0xc0000000
There are 2 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x002000 0xc0000000 0x00000000 0x231728 0x232000 RWE 0x2000
  LOAD           0x234000 0xc0232000 0x00232000 0x17c78c 0x18bfcc RWE 0x2000

 Section to Segment mapping:
  Segment Sections...
   00     .text .rodata __ksymtab __ksymtab_gpl __ksymtab_strings __param __modver 
   01     .data __ex_table .head.text .init.text .init.data .bss 

と の違いを参照してくださいVirtAddr(通常の Linux カーネル マッピングによりPhysAddr削除されました)。c当然、ロードには物理アドレスを使用する必要があります。

カーネルがシンボルやセクションなどに仮想アドレスを使用する理由は、ブート中に MMU が初期化される瞬間にすぐに入ることができるため、仮想アドレスが唯一の有効なアドレスになるからです。

そして最後に、それらのアドレスの変更について。確かに、Alexey が指摘したように、リンカー スクリプトが重要です。これらは にありarch/(your arch)/kernel/vmlinux.lds.Sます。しかし、要点は、これはあなたの問題ではなく IMO であり、問​​題はおそらくローダーまたはそのオプションにあるということです。

于 2013-03-26T14:32:54.943 に答える
1

arch/arm/mach-xxx/Makefile.boot を確認してください (アームボードを正しく使用していますか?)

  zreladdr-y        += 0x80008000
params_phys-y       := 0x80000100
initrd_phys-y       := 0x80800000

これは Ti omap3 チップからのものです。

同じものが必要になると思うので

于 2013-03-30T15:24:56.997 に答える