すべてのプロセスには独自の仮想アドレス空間があり、カーネルにも独自の仮想アドレス空間があり、カーネルは一連のプロセスです。つまり、すべてのカーネルプロセスに独自の仮想アドレス空間がありますか?
カーネルには、特別なカーネル プロセスがない場合があります。特別なカーネル スレッドさえ持たない場合もあります。たとえば、MSDOS には何もありませんでしたが、それが原始的な OS でした。持っていたのは、ISR、さまざまなもの (ファイル システム ドライバー、メモリ マネージャーなど) 用の大量の内部コード、およびアプリケーション用のシステム コール API だけでした。
OS は、ユーザー プロセスによって提供される (または、IOW、委任された) 機能の一部を持つことができます。それがマイクロカーネルの考え方です。これらの専用プロセスには、通常のプロセスと比較して追加の特権がある場合があります。
この場合、カーネルはユーザー プロセスによって何らかの方法で呼び出すことができる一連のサブルーチンです (プロセスがなく、すべてに対して 1 つのアドレス空間があったことを除けば、DOS はまさにそれでした)。カーネルは依然としてすべてのユーザーからアクセス可能である必要があり、そのため、カーネルが存在するメモリは、すべてのアドレス空間で (たとえば、ページ変換を介して) 共有されます。すべてのカーネルには、そのような共通/共有部分があります。
32 ビット アーキテクチャ システムでは、すべてのプロセスに 4 GB の仮想アドレス空間があり、カーネル空間のサイズは?
CPU とカーネルの実装に依存します。32 ビット Windows は通常、アドレス空間のユーザー部分とカーネル部分に 2GB を予約します。必要に応じて、これをユーザー用に 3GB、カーネル用に 1GB にオーバーライドできます。
ユーザー空間の 0x00000000-0xffffffff はカーネルによって占有されていますが、それらは異なる空間です。これはどのように実装されていますか?
CPUのMMUに依存します。x86 のページ テーブルを使用すると、プロセス/スレッドの切り替え時に仮想アドレス空間の一部 (これはユーザー部分) のみが物理メモリへのマッピングを変更し、残りの部分はそのまま残るように、仮想アドレス空間全体を編成できます。同じです (これは共有カーネル部分です)。
通常、CPU の観点から見ると、仮想アドレス空間は 1 つだけです。しかし、その部分を個別のユーザー仮想アドレス空間とカーネル仮想アドレス空間と呼ぶのが一般的です。
カーネルが何かを独自のスペースにコピーする必要があるのはなぜですか?
syscall パラメータなど、プロセスからの入力をどのように取得しますか? しかし、最も重要なことは、非同期で入力の長い処理を実行しなければならない場合、つまり入力を取得し、呼び出し元に続行させ、作業が完了したときに呼び出し元に通知する必要がある場合はどうなるでしょうか? 呼び出しプロセスは、カーネルに渡されたばかりのデータ バッファーを自由に変更または割り当て解除できる場合があります。カーネルは、処理中のデータが変化したり消えたりするのを観察することにあまり「満足」しない場合があります。プロセスに複数のスレッドがある場合、同期呼び出しでもこの問題が発生する可能性があります。これは、カーネルがバッファを操作している間に、別のスレッドがバッファを変更できるためです。
データをアドレス空間のカーネル部分にコピーまたは保持する理由は他にもあります。