スワップパーティションには、構造化ファイルシステムが含まれていません。カーネルは、スワップ領域としてマークされたパーティションにメモリページを格納しているため、これを必要としません。スワップ領域には複数のメモリページが存在する可能性があるため、プロセスがページのメモリへのロードを要求したときに、カーネルはどのようにして各ページを見つけますか。 Devuan OSのスワップパーティションのヘッダーを見て、さらに説明しましょう。
#define SWAP_UUID_LENGTH 16
#define SWAP_LABEL_LENGTH 16
struct swap_header_v1_2 {
char bootbits[1024]; /* Space for disklabel etc. */
unsigned int version;
unsigned int last_page;
unsigned int nr_badpages;
unsigned char uuid[SWAP_UUID_LENGTH];
char volume_name[SWAP_LABEL_LENGTH];
unsigned int padding[117];
unsigned int badpages[1];
};
したがって、パーティションに対してmkswap
コマンドが実行されると、それがそのパーティション、つまりスワップヘッダーに配置されます。
ここで、プロセスAのメモリページがスワップされ、スワップ領域に1つのメモリページがあるシナリオを考えてみましょう。もちろん、スワップ領域には多くのメモリページが存在する可能性があります。ここで、プロセスAは、スワップされたメモリページにアクセスする必要があります。プロセスAはカーネルに通知しますが、スワップされたメモリページをいただけますか?カーネルは言う:確かに私の親愛なる友人。そこでカーネルは、スワップパーティションでプロセスAのメモリページを探しに行きます。スワップパーティションは(ファイルシステムではなく)高度な構造ではないため、カーネルは、スワップパーティション内のプロセスAの特定のメモリページを見つける方法をどのように知るのでしょうか。
おそらく、カーネルはスワップされたページのセクターアドレスをどこかに格納しているので、プロセスがメモリページを要求すると、カーネルはスワップパーティションのどこを探すかを認識し、パーティションからメモリページを読み取り、メモリにロードします。
スワップは特定の起動時にのみ有効であるため、すべての追跡情報がメモリに保持されます。ページのインとスワッピングはカーネルによって完全に処理され、プロセスに対して透過的です。基本的に、メモリはページに分割され、ページテーブルで追跡されます。これらは、各CPUアーキテクチャによって定義された構造です。ページがスワップアウトされると、カーネルはそのページを無効としてマークします。したがって、次に何かがページにアクセスしようとすると、CPUに障害が発生し、カーネル内のハンドラーが呼び出されます。ページのコンテンツを復元するのは、このハンドラーの責任です。
Linuxには、各スワップデバイスまたはファイルを記述するswap_info
構造体があります。その構造内で、swap_map
はメモリページをスワップデバイスまたはファイル内のブロックにマップします。ページがスワップアウトされると、カーネルはswap_info
インデックスとswap_map
オフセットを対応するページテーブルエントリに格納します。これにより、必要に応じてディスク上のページを見つけることができます。 (サポートされているすべてのアーキテクチャは、ページテーブルにこれに十分なスペースを提供しますが、制限があります—例:利用可能なスペースは、Linuxがx86で最大64GiBのスワップを管理できることを意味します。)
これらすべての詳細については、Mel GormanUnderstanding the Linux Virtual Memory Managerの 「スワップ管理」の章 を参照してください。