PTE

NetBSD の src/sys/arch/i386/include/pte.h の冒頭にあるコメントを適当に訳してみた。ちなみに元の文章には書いてない事もあるので注意しろ>未来の自分。

i386 MMU ハードウェア構造:

i386 MMU は二階層テーブル構造をした MMU で 4GB の仮想メモリをマップする。1 ページサイズは 4096(4K) バイトで、Pentium プロセッサ以降では 4MB のページサイズもサポートしている。
MMU 第一階層のテーブルは「ページディレクトリ(PD)」と呼ばれ、1024 個のページディレクトリエントリ (PDE) を保持している。各 PDE のサイズは 4 バイトなのでページディレクトリは 1 つの 4K ページにちょうど収まる。このページをページディレクトリページ (PDP) と呼ぶ。各 PDE は仮想メモリを 4MB 分マップする。PD は 1024 個の PDE を保持する為、4MB * 1024個で 4GB の仮想メモリをサポートしている事となる。
MMU 第二階層のテーブルはページテーブルと呼ばれる。PDE はページテーブルの物理メモリアドレスを保持している。ただし、4MB ページサイズを使用している場合には、マップしている 4MB ページの物理メモリアドレスを保持している。ページテーブルは 1024 個のページテーブルエントリ (PTE) を保持している。各 PTE のサイズは 4 バイトなのでページテーブルは 1 つの 4K ページに収まる。このページをページテーブルページ (PTP) と呼ぶ。各 PTE は 4K ページ 1 つをマップする。ページテーブルには 1024 個の PTE を保持する為、4K * 1024個で 4MB の仮想メモリをサポートしている事となる。PTE はマップしているページの物理メモリアドレスと関連する情報を保持している(詳細は以下を参照)。

プロセッサは "CR3" という特別なレジスタを持っている。このレジスタは現在の仮想メモリ空間をマッピングしている PDP物理アドレスを指している。

下記に 4K ページサイズ時の変換過程を図示する。

%cr3 register [PA of PDP]
     |
     |
     |   bits <31-22> of VA         bits <21-12> of VA   bits <11-0>
     |   index the PDP (0 - 1023)   index the PTP        are the page offset
     |         |                           |                  |
     |         v                           |                  |
     +--->+----------+                     |                  |
          | PD Page  |   PA of             v                  |
          |          |---PTP-------->+------------+           |
          | 1024 PDE |               | page table |--PTE--+   |
          | entries  |               | (aka PTP)  |       |   |
          +----------+               | 1024 PTE   |       |   |
                                     | entries    |       |   |
                                     +------------+       |   |
                                                          |   |
                                               bits <31-12>   bits <11-0>
                                               p h y s i c a l  a d d r

注記:
PA  = 物理アドレス (Physical Address)
VA  = 仮想アドレス (Virtual Address)
PD  = ページディレクトリ (Page Directory)
PDP = ページディレクトリページ (Page Directory Page)
PDE = ページディレクトリエントリ (Page Directory Entry)
PTP = ページテーブルページ (Page Table Page)

i386 は TLB (Translation lookaside buffer) に PTE をキャッシュしている。マッピングを変更した時に TLB にキャッシュされている変更前のマッピング情報を消去しなければならない。CR3 レジスタへ値を書き込むと TLB にキャッシュされている全マッピング情報が消去される。新しい(i486 以降?)のプロセッサは 1 ページのマッピングのみを消去できる命令(INVLPG)が追加されている。これは 1 ページのマッピングを変更したが、変更したページ以外のマッピング情報は保存したい時に使用できる。

○ページディレクトリエントリ (PDE) 構造 (4K バイトページ使用時)

 31                                    12 11   9 8  7 6 5  4   3   2   1  0 
+----------------------------------------+------+-+--+-+-+---+---+---+---+-+
|      ページテーブルの物理アドレス      |使用可|G|PS|0|A|PCD|PWT|U/S|R/W|P|
+----------------------------------------+------+-+--+-+-+---+---+---+---+-+
                                             |   |  | | |  |   |   |   |  |
9-11: システム・プログラマが使用可能 --------+   |  | | |  |   |   |   |  |
   8: グローバル・ページ (無視される) -----------+  | | |  |   |   |   |  |
   7: ページ・サイズ (0 = 4K バイトページ) ---------+ | |  |   |   |   |  |
   6: 予約 (0) ---------------------------------------+ |  |   |   |   |  |
   5: アクセス -----------------------------------------+  |   |   |   |  |
   4: キャッシュ無効 --------------------------------------+   |   |   |  |
   3: ライトスルー --------------------------------------------+   |   |  |
   2: ユーザ/スーパバイザ (0 = スーパバイザ) ---------------------+   |  |
   1: 読み取り/書き込み (0 = 読み取りのみ) ---------------------------+  |
   0: ページ存在 ---------------------------------------------------------+

○ページテーブルエントリ (PTE) 構造 (4K バイトページ使用時)

 31                                    12 11   9 8 7 6 5  4   3   2   1  0 
+----------------------------------------+------+-+-+-+-+---+---+---+---+-+
|    マップしているページ物理アドレス    |使用可|G|0|D|A|PCD|PWT|U/S|R/W|P|
+----------------------------------------+------+-+-+-+-+---+---+---+---+-+
                                             |   | | | |  |   |   |   |  |
 9-11: システム・プログラマが使用可能 -------+   | | | |  |   |   |   |  |
    8: グローバル・ページ -----------------------+ | | |  |   |   |   |  |
    7: 予約 (0) -----------------------------------+ | |  |   |   |   |  |
    6: ダーティ -------------------------------------+ |  |   |   |   |  |
    5: アクセス ---------------------------------------+  |   |   |   |  |
    4: キャッシュ無効 ------------------------------------+   |   |   |  |
    3: ライトスルー ------------------------------------------+   |   |  |
    2: ユーザ/スーパバイザ (0 = スーパバイザ) -------------------+   |  |
    1: 読み取り/書き込み (0 = 読み取りのみ) -------------------------+  |
    0: ページ存在 -------------------------------------------------------+

○ページディレクトリエントリ (PDE) 構造 (4M バイトページ使用時)

 31                        22 21       12 11   9 8  7 6 5  4   3   2   1  0 
+----------------------------+-----------+------+-+--+-+-+---+---+---+---+-+
|ページテーブルの物理アドレス|  予約済み |使用可|G|PS|D|A|PCD|PWT|U/S|R/W|P|
+----------------------------+-----------+------+-+--+-+-+---+---+---+---+-+
                                             |   |  | | |  |   |   |   |  |
9-11: システム・プログラマが使用可能 --------+   |  | | |  |   |   |   |  |
   8: グローバル・ページ ------------------------+  | | |  |   |   |   |  |
   7: ページ・サイズ (1 = 4M バイトページ) ---------+ | |  |   |   |   |  |
   6: ダーティ ---------------------------------------+ |  |   |   |   |  |
   5: アクセス -----------------------------------------+  |   |   |   |  |
   4: キャッシュ無効 --------------------------------------+   |   |   |  |
   3: ライトスルー --------------------------------------------+   |   |  |
   2: ユーザ/スーパバイザ (0 = スーパバイザ) ---------------------+   |  |
   1: 読み取り/書き込み (0 = 読み取りのみ) ---------------------------+  |
   0: ページ存在 ---------------------------------------------------------+

注記:

  • i386 プロセッサではスーパバイザモードの時 R/W ビットは無視される(これはプロセッサのバグだ!)
  • PS ビットは新しいプロセッサ(Pentium 以降?)でのみサポートされる
  • G ビットが立った PTE は global となり、CR3 レジスタ書き込み時の全キャッシュマッピング消去時に削除されなくなる。キャッシュされたマッピングを削除したい場合には 1 ページのキャッシュ削除命令を使用する。これはカーネルに使用されている TLB エントリをコンテキストスイッチ時の TLB キャッシュ消去から守る為に使用される。カーネルは全プロセスで同じアドレスにマッピングされているので、プロセスのコンテキストスイッチ時に TLB キャッシュから消去する必要が無い為である。
  • ちなみに G ビットは PentiumPro 以降のプロセッサでサポートされている