7

ARM-CortexM3ベースのデバイスのブートスクリプトを作成しています。アセンブラブートスクリプトとCアプリケーションコードをコンパイルしてから、オブジェクトファイルを結合してデバイスに転送すると、すべてが機能します。

ただし、arアーカイブ(libboot.a)を作成し、そのアーカイブをCアプリケーションと組み合わせる場合、問題が発生します。

ブートコードをセクションに配置しました:

    .section    .boot, "ax"
    .global     _start

_start:
    .word       0x10000800  /* Initial stack pointer (FIXME!) */
    .word       start
    .word       nmi_handler
    .word       hard_fault_handler
    ... etc ...

ldこれを最終的なバイナリから削除することがわかりました(「ブート」セクションは使用できません)。これは、認識している依存関係がないため非常に自然ですがld、デバイスが正しく起動しない原因になります。

だから私の質問は:このコードを強制的に含めるための最良の方法は何ですか?

4

5 に答える 5

10

次のようなものを追加してみてください:

KEEP(*(.boot))

ldリンカースクリプトで、セクションを保持するようにリンカーに指示します.boot

ldただし、これがアーカイブからセクションにあるオブジェクトをプルするのに十分かどうかはわかり.bootません。そのオブジェクトのシンボルによってプルされる場合を除いて、オブジェクトをまったく考慮しない可能性があります。これは問題です。_startエントリ ポイントとして指定する ( -e _startld コマンド ラインで使用ENTRY(_start)するか、リンカー スクリプトで使用する) ことが解決策になる場合があります。

于 2010-04-23T05:47:31.987 に答える
4

--no-gc-sectionsオプションをリンカーに渡したいと思います。GNU ld ドキュメントから:

--gc-sections
--no-gc-sections

Enable garbage collection of unused input sections.

`--gc-sections' decides which input sections are used
by examining symbols and relocations. The section
containing the entry symbol and all sections containing symbols
undefined on the command-line will be kept, as will sections
containing symbols referenced by dynamic objects.
Note that when building shared libraries, the linker must
assume that any visible symbol is referenced. Once this initial
set of sections has been determined, the linker recursively marks
as used any section referenced by their relocations.
See `--entry' and `--undefined'.
于 2010-04-21T13:51:52.740 に答える
2

リンカーは、明示的に参照されたシンボルを解決するために必要なオブジェクトのみをアーカイブから抽出します。スタートアップ コードは、リセット ベクターを介して呼び出されるため、明示的に参照されません。

ブート コードが複数のモジュールで構成されている場合は、 ld と-r / --relocatableオプションを使用して部分的にリンクされたオブジェクト ファイルを作成する必要があります。これにより、すべてのシンボルを解決する必要なく、オブジェクトが 1 つのオブジェクトに結合されます (例)。これは、アプリケーション コードとの完全なリンクで使用できます。オブジェクト ファイルが 1 つしかない場合は、いずれにしてもアーカイブを作成する利点はありません (そして、動作しないことがわかっているように)。

伝統的に、GNU C ランタイムの起動は、おそらく同じ理由で、crt0.o (アーカイブではない) というファイルで提供されていることに注意してください。

于 2010-04-21T21:28:49.153 に答える
2

リンク時に使用できます--whole-archiveが、それは大きな象の銃です。manページの主張:

オプションの後にコマンド ラインで指定された各アーカイブについて --whole-archive 、必要なオブジェクト ファイルのアーカイブを検索するのではなく、アーカイブ内のすべてのオブジェクト ファイルをリンクに含めます。

于 2011-04-21T16:45:41.627 に答える
1

ld --whole-archiveオプションを使用して、参照されていないシンボルを取り込むことができます。この ldオプションページには、whole-archive--whole-archive用にこれが あります

コマンドラインで--whole-archiveオプションの後に記載されているアーカイブごとに、アーカイブで必要なオブジェクトファイルを検索するのではなく、アーカイブ内のすべてのオブジェクトファイルをリンクに含めます。これは通常、アーカイブファイルを共有ライブラリに変換するために使用され、すべてのオブジェクトが結果の共有ライブラリに含まれるようにします。このオプションは複数回使用できます。
gccからこのオプションを使用する場合の2つの注意事項:まず、gccはこのオプションを認識しないため、-Wl、-whole-archiveを使用する必要があります。次に、アーカイブのリストの後に-Wl、-no-whole-archiveを使用することを忘れないでください。これは、gccが独自のアーカイブのリストをリンクに追加し、このフラグがそれらにも影響を与えないようにするためです。

スタックオーバーフロー、アーカイブ全体オプションの使用に関するこの質問も参照してください

于 2010-04-23T04:56:37.967 に答える