2011-10-18 11 views
0

私はGormanの仮想メモリ管理の本に従っています。カーネルページテーブルの初期化方法は?

ブートストラップとファイナライズの2つの段階に分かれているといわれるカーネルテーブルページの初期化についてのセクションがあります。

ここで、ブートストラップ段階について説明します。

アセンブラ関数startup_32()は、 arch/i386/kernel/head.Sのページングユニットを有効にします。 vmlinuzのすべての通常のカーネルコードは、ベースアドレスがPAGE_OFFSET + 1MiBの でコンパイルされていますが、実際には最初のメガバイト(0x00100000)のメモリには からロードされます。最初のメガバイトは、一部のデバイスでBIOSとの通信用に で使用され、スキップされます。 このファイルのブートストラップ は、ページングユニットが有効になるまで、 の任意のアドレスから__PAGE_OFFSETを減算することによって、1MiBをベースアドレスとして扱います。したがって、ページング単位が になる前に、8MiBの 物理メモリを仮想アドレスPAGE_OFFSETに変換するページテーブルマッピングを確立する必要があります。

  1. はなぜ__PAGE_OFFESTを引くしたいですか?どのような目的のために?

  2. なぜページングユニットが有効になる前に減算する必要があるのですか?カーネル仮想アドレスを物理メモリアドレスにマッピングするために常に減算を使用していますか?

  3. なぜ8MBですか?

おかげで、

答えて

3

アドレスX(__PAGE_OFFSET + 1メガバイト)で実行するようにコンパイルされたが、アドレスY(1メガバイト)にロードされ、内部の全てのアドレスならx86のコードは、一般的位置に依存しないのでそれが動作するには、YX(__PAGE_OFFSET + 1MB - 1MB = __PAGE_OFFSET)だけ減らす必要があります。

たとえば、__PAGE_OFFSET + 1MBというカーネルの先頭から1バイトのメモリを読み込む命令がある場合、そのアドレスは__PAGE_OFFSETだけ小さくなり、実際の読み込み位置は1MBになります。 。

最終的にページ変換が有効になると、__PAGE_OFFSETは、__PAGE_OFFSETより小さい物理アドレスの範囲に物理アドレスの範囲をマッピングすることで、ページ変換メカニズムによって効果的に差し引かれます(つまり、物理=ページテーブルごとに仮想-__ PAGE_OFFSET)。

追加のカーネル再配置が含まれていない限り、8 MBはカーネル全体をマッピングするのに十分なマッピング範囲のサイズにすぎません。

+0

ありがとうアレックス、本当に役立ちます – sliter

関連する問題