カーネル マッピングは、ユーザー プロセス用ではなく、主にカーネル用に存在します。 CPU の観点からは、線形アドレスとしてマップされていない物理メモリ アドレスは存在しない可能性があります。しかし、CPU はカーネルを呼び出すことができる必要があります:割り込みを処理するため、例外を処理するため... ユーザー プロセスがシステム コールを発行するときにカーネルを呼び出すこともできる必要があります (これにはさまざまな方法があります)。発生するので、詳細には触れません)。すべてではないにしても、ほとんどのアーキテクチャでは、これはページ テーブルを切り替える機会なしで発生します。たとえば SYSENTER
を参照してください。 .したがって、少なくとも、カーネルへのエントリ ポイントは、常に現在のアドレス空間にマップする必要があります。
カーネルの割り当て 動的ですが、アドレス空間はそうではありません。 32 ビット x86 では、図に示されている 3/1 GiB 分割など、さまざまな分割を使用できます。 64 ビット x86 では、アドレス空間の上半分がカーネル用に予約されています (カーネル ドキュメントのメモリ マップを参照してください)。その分割は移動できません。 (ライブラリはユーザー空間にロードされることに注意してください。カーネル モジュールはカーネル空間にロードされますが、これも割り当てのみを変更し、アドレス空間の分割は変更しません。)
ユーザー モードでは、すべてのプロセスで共有されるカーネルの単一のマッピングがあります。カーネル側のページ マッピングが変更されると、その変更はすべての場所に反映されます。
KPTI が有効な場合、カーネルには独自のプライベート マッピングがあり、ユーザー空間コードの実行時には公開されません。そのため、KPTI には 2 つのマッピングがあり、カーネル プライベート マッピングへの変更はユーザー空間には表示されません (これが KPTI の要点です)。
カーネル メモリ マップは、常にすべてのカーネルをマップします (KPTI を実行するときのカーネル モードで)。ただし、必ずしも 1 対 1 であるとは限りません。少なくとも 2 回マッピングされています。