前回は,プロセスが利用するメモリーをLinuxがどのように管理するかを説明しました。Linuxでは,ページングという仕組みに基づいた仮想記憶機構を利用して,プロセスごとに実際のメモリー空間とは別の仮想メモリー空間を準備します。この仮想メモリー空間は,プロセス・スケジューラによって実行が切り替わるたびに切り替えられます。このような仕組みを採ることで,複数のプロセスで競合を起こさず,できるだけ効率的にメモリーを使えます。

 ところで,メモリーを利用するのはプロセスだけではありません。カーネル自身もメモリーを使いますが,その利用方法はプロセスの場合とは異なっています。また,物理メモリー・アドレスと仮想メモリー・アドレスの変換を行うのはプロセッサ(MMU)の仕事ですが,実際にその変換表(ページ・テーブル)を用意するのはカーネルの役割です。空き物理ページのうちどのページを割り当てるのか判断するのもカーネルです。

 そこで今回は,カーネルを中心にしてメモリー管理の仕組みを紹介します。

プロセスのメモリー空間の1Gバイトはカーネルが利用

 IA-32プロセッサは,32ビットのメモリー・アドレスを持ちますので,4Gバイトのメモリー空間を利用できます。これは,仮想メモリー空間でも物理メモリー空間でも同じです。そのため,仮想記憶を有効にしている場合は,4Gバイトの物理メモリーを搭載していなくても,4Gバイトの仮想メモリー空間をすべて利用できます。

 Linuxでは,プロセスごとに仮想メモリー空間を割り当てますので,各プロセスでは4Gバイトのメモリー空間を利用できるはずです。しかし実際にプロセスが(ユーザー・モードで)利用できるのは,先頭から3Gバイト(0x00000000~0xbfffffff)に制限されます。これは,残りの1Gバイト(0xc0000000~0xffffffff)をカーネルが(カーネル・モードで)利用するためです。

 プロセスが利用する先頭から3Gバイトの領域をプロセス仮想空間と呼び,残りの1Gバイトの領域をカーネル仮想空間と呼びます(図1)。これらは同じ仮想メモリー空間に存在しますが,別の仮想空間と考えても良いほど,用途や働きが異なります。

図1●プロセス仮想空間とカーネル仮想空間
図1●プロセス仮想空間とカーネル仮想空間
4Gバイトの仮想メモリー空間のうち,上位1Gバイトはカーネルが利用するカーネル仮想空間になっています。

 この両者は同一の仮想メモリー空間にマッピングされていますが,カーネル仮想空間はプロセッサの保護機構で保護されていて,ユーザー・モードで動作する通常のプロセスからはアクセスできません。カーネルが利用するメモリー領域にアクセスすると,メモリー保護違反が発生してエラーとなってしまいます。システム・コールの実行などで,カーネル・モードに移行したときに初めてこれらの領域にアクセスできます。

 また,プロセスが異なると仮想メモリー空間も異なりますが,カーネル仮想空間の部分については全プロセスで共用し,同一の内容になる点も大きな違いです。あるプロセスの処理によりカーネル仮想空間に変更が生じた場合,その変更は(途中でカーネルに変更されない限り)他の全プロセスに波及します。

 なぜ,このようにしているのでしょうか。メモリー空間を分離するという仮想メモリーの考え方からすると,カーネルにも専用の仮想メモリー空間を割り当てて,プロセスが仮想メモリー空間全体を利用できるようにした方が良いように思えます。

この先は会員の登録が必要です。有料会員(月額プラン)は初月無料!

日経 xTECHには有料記事(有料会員向けまたは定期購読者向け)、無料記事(登録会員向け)、フリー記事(誰でも閲覧可能)があります。有料記事でも、登録会員向け配信期間は登録会員への登録が必要な場合があります。有料会員と登録会員に関するFAQはこちら