1

広く知られているように、32ビットのWindows OSで実行されているプログラムでは、2GBの仮想メモリしか使用できません。また、他の2GBはカーネルスペースとして予約されていることが知られています。しかし、実際にはそのカーネル空間には何がありますか?

カーネル自体に必要な予約は理解できましたが、プロセスのVASにカーネルスペースがあるのはなぜですか?ありがとう。

4

5 に答える 5

9

Windows Internals の本を入手してください。詳細に説明されています。簡単に要約すると、カーネル仮想アドレス (KVA) 空間にあるもの:

1) カーネルと HAL

2) デバイスドライバー

3) カーネル モード ヒープ (エグゼクティブ プールと呼ばれますが、これはいつも面白いと思います)

4) ハンドルを介してユーザー モードにエクスポートされたオブジェクト (プロセス、スレッド、イベント、ミューテックスなどのオブジェクト)

5) システム PTE: 面倒なユーザー モード アプリからあらゆる種類の興味深いものをマップします (例: カーネル モードでの実行時にスレッドが使用する実行スタック)。

6) ファイルシステムキャッシュ

そしてリストは延々と続きます...私が言ったように、Windows Internalsを読んでください。

-スコット

于 2010-08-31T15:30:32.857 に答える
3

カーネル メモリがすべてのプロセスの仮想アドレス空間にマップされる理由は、カーネル モードへのコンテキスト スイッチでプロセス ページ テーブルを変更する必要がないようにするためです。現在の特権レベルが に引き上げられるだけで0、これらのページにすぐにアクセスできるようになります。

ページテーブルは、別のプロセスに切り替える場合にのみ切り替える必要があります。これは高価な操作であるため (たとえば、TLB フラッシュが必要です)、その頻度を最小限に抑えることが効果的です。

さらに、特別なカーネル ページ テーブルを切り替えてカーネル空間に切り替えた場合、ユーザー空間のアドレス空間の一部を選択して置き換える必要があります。これにより、これらのユーザー空間アドレスにカーネルがアクセスできなくなり、バウンス バッファーが必要になるか、これらの領域のデータがカーネルとの間でいつ転送されるかをいじる必要が生じます。

于 2010-09-01T01:16:21.557 に答える
2

私の意見では、2GB 境界について、あまり知られていない事実がもう 1 つあります。通常、多くのアプリケーションは多くのポインター演算を処理します (特に、C、C++ などで作成されたアプリケーション)。これらのアプリケーションでは、ポインターにオフセットを追加したり、ポインターを差し引いたりすることは非常に一般的です。

使用可能な仮想アドレス空間が 2GB の場合、2 つのポインターの減算は常に -2147483647 と +2147483648 の間であることが保証されます (これらは 32 ビット符号付き値の制限です)。

アドレス空間が 3GB の場合、可能な差は 32 ビットの符号付き値で表現できるどの値よりも大きくなります。

アプリケーションが安全であり、まったく無関係なポインターを差し引いていない (そして配列が 2GB 未満である!) ことがわかっている場合は、リンカー フラグ LARGEADDRESSAWARE (または EDITBIN ユーティリティで設定します)。

XP (Vista と W7 についてはよくわかりません) では、「カーネル空間」が 1GB しかないモードで起動でき、仮想アドレス空間の 3GB がアプリケーション用に残されます。アプリケーションが LARGEADDRESSAWARE の場合、3GB をすべて取得します。そうでない場合は、2GB しか取得できません。

64 ビット Windows では、LARGEADDRESSAWARE 32 ビット アプリケーションは 4GB も取得します。これは、Windows が 32 ビット領域に実質的なアドレス空間を必要としないためです (結局のところ、Windows は 64 ビット OS です)。

于 2010-08-31T15:40:11.307 に答える
1

C++ などの高級言語で記述されたプログラムは、最終的に OS API 呼び出し、具体的には Windows OS 用の Windows API に変換されます。CreateFile などの多くの Windows API は、実際にはカーネル モード ドライバーと通信します。プロセス アドレス空間のカーネル空間は、このプロセスにカーネル リソースを割り当てるために使用されます。たとえば、ドライバーの IOCTL 呼び出しには、ユーザー モード API とドライバーの間で渡される入出力バッファーが含まれています。このようなバッファは、プロセス カーネル空間に割り当てられます。

通常、カーネル空間には、このプロセスに代わってカーネル モード コンポーネントによって割り当てられたリソースが含まれます。

于 2010-08-31T15:32:16.667 に答える
1

あなたの質問は、タイトルにある「何」ではなく「なぜ」のようです。

また、あなたの質問は32ビットを前提としています。Windows の 64 ビット バージョンはかなり異なります (たとえば、VAS は 8TB、Itanium システムでは 7TB です)。

「理由」については、プロセスの VAS に含まれていないカーネル関数 (ドライバーなど) からポインターをどのように渡すのでしょうか? これを理解するために読むのに適した本は、Windows Internals です。

于 2010-08-31T15:38:44.490 に答える