オペレーティングシステムを実行するときに物理アドレスがどのように割り当てられるかを理解したいと思います。
私の質問は、カーネルがいくつかのメモリを割り当てるとき(kmallocを使用すると仮定)、誰がその仮想メモリ範囲にマップする必要がある物理メモリアドレス範囲を決定するのかということです。
私が知る限り、カーネルは仮想マッピングを物理マッピングに変換するためのページテーブルを作成し、MMUはそれを使用します。ただし、その前に誰かがマッピングする物理ページを割り当て/割り当てる必要があります。これはカーネル自体によって行われますか、またはMMUはカーネルが使用できる特定の物理アドレス範囲を知ることができますか?
カーネル自体が物理アドレスを割り当てる場合、どの物理アドレスが使用され、どれが使用可能かを追跡する方法は?
答え1
オペレーティングシステムを実行するときに物理アドレスがどのように割り当てられるかを理解したいと思います。
物理アドレスは割り当てられておらず、すでに存在します。 RAMです。
私の質問は、カーネルがいくつかのメモリを割り当てるとき(kmallocを使用すると仮定)、誰がその仮想メモリ範囲にマップする必要がある物理メモリアドレス範囲を決定するのかということです。
ターゲット:カーネルメモリマッピングアルゴリズム。だから、カーネル。
ただし、その前に誰かがマッピングする物理ページを割り当て/割り当てる必要があります。
前述のように、物理メモリはカーネルが処理しなければならない現実です。
セグメント化された連続メモリ範囲を形成するためにメモリチップがどのようにマッピングされるかについての質問は、ハードウェアと起動プロセスによって異なります。デスクトップまたはサーバーx86で通常起動時にDRAMコントローラを初期化すると、ファームウェア(またはブートローダ)はDRAMメモリモジュール(「DIMM」)「設定EEPROM」の内容を読み込み、CPUメモリを設定します。コントローラ(またはマザーボード)、ハードウェアの詳細によって異なります)は、メモリアドレスアクセスを読み取りに変換し、それに応じてこれらのチップに書き込みを実行します。組み込みプラットフォームでは、RAM構成をソフトウェアに簡単に適用できます(たとえば、ubootおよびLinuxカーネルはハードウェアを初期化するためにデバイスツリーを使用します)、その後、メモリコントローラはそのように構成されます。
したがって、ここには普遍的な答えはありません。 「ダイナミックメモリの処理方法」は、アーキテクチャが他の重要な事項の1つです。 i386のPAEを覚えておくと、非常に詳細でCPUモデルによって異なります。
この仮想メモリ範囲にマッピングする必要がある物理メモリアドレス範囲を誰が決定しますか?
方法について話しましょう。カーネルは、ハードウェアやファームウェアのインターフェイス、または設定ファイルを介して物理アドレス空間に物理メモリがどれだけあるか、メモリにマッピングされたIOがどこにあるか、すでに使用しているメモリが何であるかを知っているため、アイドル物理メモリデータ構造を追跡できます。 。したがって、kmalloc
特定のサイズで呼び出すときは、サイズ要件に一致する未使用の物理メモリを探しています。
答え2
これはとても簡単です。
- 最初に、CPUは起動プロセスの一部としてMMUをリセットします。
- カーネルは、物理メモリ(RAM)を検出して割り当てることが
kmalloc
できるデータ構造を構築します。カーネルコードが存在するRAMは除外されます。 - カーネルが
/sbin/init
最初にプロセス()を実行することを決定した場合は、必要な内部テーブルとRAMブロックを割り当てて実行可能ファイルにマップします。 - その後、プロセス・アラインメントの一部として「ページ・テーブル」を使用して、各プロセスが位置0から始まるメモリ空間を見ることができるようにMMUを設定し、位置0はそのプロセスに固有である。すべてのプロセスの位置0は有毒です。
SEGV - segment violation
これを使用すると、aが得られます。初期化されていないポインタを検出します。 - CPUが「ハイパーバイザー」モード(ハードウェア状態)の場合、MMUは無効になります。 MMUは、カーネルがプロセスに制御を渡し、「ハイパーバイザー」モードをクリアしたときに適用されます。
- アクティブなMMUはCPU <-> RAMハードウェアパスに自分自身を挿入するため、CPU <-> MMU <-> RAMになります。
- CPUが発行した各アドレスの上位ビットは、CPUが割り込みを介して「管理者」モードに戻るまでページテーブルのビットに置き換えられます。