5

Linux カーネルの HIGHMEM について私が読んだほとんどすべての本や記事では、3:1 分割を使用している間、1GB のすべてがカーネルでマッピングに使用できるわけではないと述べています。通常は 896MB 程度で、残りはカーネル データ構造、メモリ マップ、ページ テーブルなどに使用されます。

私の質問は、これらのデータ構造とは正確には何ですか? ページテーブルは通常、ページテーブルアドレスレジスタを介してアクセスされますよね? また、ページテーブルのベースアドレスは、通常、物理アドレスとして格納されます。では、なぜテーブル全体に仮想アドレス空間を予約する必要があるのでしょうか?

同様に、カーネルコード自体がスペースを占有しているという記事を読みました。それは仮想アドレス空間と何の関係がありますか? コードを格納するために消費されるのは物理メモリではありませんか?

そして最後に、これらのデータ構造はなぜ 128MB のスペースを確保しなければならないのでしょうか? カーネルの他の通常のデータ構造のように、必要に応じて 1GB のアドレス空間全体から使用できないのはなぜですか?

LDD3、Professional Linux Kernel Architecture、stack-overflow のいくつかの投稿 ( Why Linux Kernel ZONE_NORMAL is limited to 896 MB?など) と古い LWN articleを調べましたが、同じものに関する特定の情報は見つかりませんでした。

4

2 に答える 2

4

ページ テーブルに関しては、ページ テーブル自体が仮想アドレス空間にマップされていなくても、MMU が気にしないのは事実です。アドレス変換の目的であれば、それで問題ありません。しかし、カーネルがページ テーブルを変更する必要がある場合は、それらを仮想アドレス空間にマップする必要があります。カーネルはページ テーブル自体を変更する必要があるため、「ジャスト イン タイム」でそれらをマップすることはできません。それ。これはニワトリが先か卵が先かという問題です。つまり、ページ テーブルは常にマップされたままにしておく必要があります。

カーネル コードにも同様の問題があります。コードを実行するには、仮想アドレス空間にマップする必要があります。ページ テーブルの変更を行うコード自体が存在しない場合、同様の鶏が先か卵が先かという問題が発生します。これを考えると、カーネル モード スタックや、潜在的にページ フォールトを発生させたくないコードによるカーネル データ構造へのアクセスと共に、カーネル コード全体を常にマップしたままにしておく方が簡単です。このようなデータ構造の大きな例の 1 つは、struct page各物理メモリ ページを表す構造体の配列です。

于 2012-07-23T04:22:34.943 に答える
1

128MB の予約は、常に使用する特定のデータ構造用ではありません。
これは、さまざまなユーザーが使用する可能性のある仮想メモリです。通常、すべてが使用されるわけではありません。

物理メモリと仮想メモリについて: すべての割り当てには、物理​​ページ、仮想ページ、および 2 つを接続するマッピングの 3 つが必要です。Linux は物理アドレスを直接使用することはほとんどなく、常に仮想アドレス変換を渡します。
ほとんどのカーネル メモリ割り当て (lowmem と呼ばれます) の場合、この変換は非常に単純です。仮想アドレスから定数を差し引いて、物理アドレスを取得します。それでも、仮想アドレスが使用されます。

Linux のメモリ管理は、仮想メモリ空​​間 (4GB) が物理メモリよりもはるかに大きいときに作成されました。最大のマシンでもそうです。このような場合、仮想アドレスの浪費は問題になりません。今日、物理メモリが大きい場合、これは非効率性と問題につながります。

vmalloc仮想アドレス範囲は、 のすべての呼び出し元によって使用されますvmalloc。次に例を示します
。 1. カーネル ドライバをロードします (modprobeまたはを使用insmod)。
2. カーネル モジュールはしばしば で割り当てますvmalloc。代替関数kmallocは以前は 128K に制限されていましたが、サイズを 2 の累乗に切り上げるため、vmalloc多くの場合、大規模な割り当てに好まれます。

于 2012-07-19T13:41:07.073 に答える