3

私はおもちゃのオペレーティング システムとブートローダーに取り組んでいます。カーネルを C で記述し、ブートローダーから直接ジャンプできるようにバイナリに変換しようとしています (つまり、ELF などをロードしていません)。

適切なオリジンを使用してリンカー ファイルをセットアップし (アドレス 0xC0000000 にカーネルをロードしています)、objdumpそれが正しく使用されていることを確認しました。ただし、私が望んでいたように、エントリポイントを開始 (0xC0000000) に配置していません。ENTRYそれはディレクティブの目的ではないと思います。

kernel_main私の問題は、特定の関数をアドレス 0xC0000000に配置したいということです。コンパイルとリンクに gcc を使用してこれを達成する方法はありますか?

私のリンカーファイルの関連部分は次のようになります。

ENTRY(kernel_main)

SECTIONS
{
   /* Origin */
   . = 0xC0000000;

   .text BLOCK(4K) : ALIGN(4K)
   {
       *(.text)
   }
   /* etc. */
}
4

2 に答える 2

4

ENTRYリンカ コマンドは、プログラムをロードするときにローダーがジャンプするシンボルをリンカに指示します。独自のオペレーティング システムを作成している場合、ローダーがないため、実際には使用されません。

代わりに、ご存知のように、プログラムは単純に最初のコード アドレスから開始します。

コードの特別なセグメントを最初に配置するには、それを特別なコード セグメントに配置し、リストの最初に配置します。

.text BLOCK(4K) : ALIGN(4K)
{
    *(.text.boot) *(.text)
}

リスト内のセグメントは、指定された順序で配置されます。

于 2013-06-29T17:39:18.563 に答える
3

このENTRYディレクティブは、エントリポイントをサポートする出力形式でのみ役立ちます。バイナリ出力を使用しているため、これは機能しません。あなたができることは、別のソースファイルに小さなスタブを書くことです(つまりentry.centry.asmまたは何でも)。次に、ldスクリプトで、*(.text)行の前にentry.o(.text). ldこれは、特定のオブジェクト ファイルからシンボルをロードするように指示します (*はすべてのオブジェクト ファイルを示します)。したがって、新しいldスクリプトは次のようになります: ENTRY(kernel_main)

SECTIONS
{
   /* Origin */
  . = 0xC0000000;

   .text BLOCK(4K) : ALIGN(4K)
   {
       entry.o(.text)
       *(.text)
   }
   /* etc. */
}

entry.o関数が 1 つだけ (カーネルの main を呼び出すだけ) 含まれている限り、これは機能するはずです。

于 2013-06-29T17:37:54.147 に答える