4

私はDで独自のブートローダーとカーネルの作成に取り組んでいますが、つまずきに遭遇しました。

バックグラウンド:

  • 私はすべてを一から書いています。したがって、ブートセクターは組み立て中です。そして、私はGRUBを使用していません。
  • テストにはQemuを使用しています。
  • ブートセクターは、「ディスク」(現在はフラットバイナリファイルであり、最初のセクターはブートローダーで、残りはカーネルコード)から仮想アドレス0xC0000000にカーネルを読み取りkmain()、私のエントリポイントであるを呼び出します。カーネル。
  • カーネルにPEファイル形式を使用しています。(Elfを使用するように言わないでください。私の選択はPEです。)

問題

PEファイルをロードできるようにすることはカーネルの仕事の一部です。では、最初にカーネル自体をメモリにロードして、実際に正しく実行できるようにするにはどうすればよいでしょうか。

(1)512バイトに収まらない、(2)アセンブリで行うのが面倒なので、ブートセクタからこれを行うことはできません。もちろん、カーネル自体でもそれを行うことはできません。では、これをどのように行う必要がありますか?

4

1 に答える 1

10

GRUBはどのようにそれを行いますか?

GRUB では、512 バイトのブート セクターはカーネルをロードしません。代わりに、512 バイトよりもはるかに大きい残りのブートローダーをロードします。カーネルをロードするのは、この第 2 段階のブートローダーです。同様のことを行う必要があります。

この第 2 段階をロードするためのコードは、完全なカーネルをロードするためのコードよりもはるかに単純です。基本的には、いくつかのセクタを固定メモリ アドレスに直接ロードし (メモリ不足で、この時点ではまだリアル モードになっています)、次の場所にジャンプします。固定メモリアドレス。

この第 2 段階は、ほとんどが C で記述できます。C 関数にジャンプして残りを実行する前に、アセンブリで少しセットアップするだけで済みます (プロテクト モードへの移行、スタックのセットアップ、およびその他の低レベル プロセッサに関するいくつかのビット)。セットアップの。

Linux カーネルは、過去にこのようなことを行いました。生のカーネルを直接フロッピー ディスクにコピーできます。最初の 512 バイトはフロッピー ディスクのブート セクタで、次のいくつかのセクタ (まだリアル モード) をロー メモリの固定アドレスにロードしました。これらの次のいくつかのセクターには、残りのカーネルを固定メモリ アドレスにロードし、実際のエントリ ポイントにジャンプするコード (まだアセンブリ中) がありました。現在、IIRC ではこのコードのほとんどが取り除かれ、Linux カーネルは外部のブートローダーに依存するようになりました。

于 2011-06-19T22:53:55.217 に答える