リニアアドレス→物理アドレスの変換方式
セグメントディスクリプタのリニアアドレスの算出式を疑似コードで表現すると、
QWORD segment_desc segment_desc := *(QWORD *)((gdtr AND 0xFFFFFFFF0000) + (segment_reg AND 0xFFF8))
上で求めたセグメントディスクリプタの値(segment_desc)から、飛び地で格納されたベース値を連結して、セグメントのベースアドレスのリニアアドレスを求めます。そのベースアドレスにオフセット値を加算して、論理アドレス上の目的のリニアアドレスを算出します。
32bitのリニアアドレスは、上位10bit・中10bit・下位12bitで以下の意味があります。
31 22 21 12 11 0 +--------------+----------+------------+ | ディレクトリ | テーブル | オフセット | +--------------+----------+------------+
CR3レジスタと、ページディレクトリ、ページテーブル、オフセット値の組み合わせで、リニアアドレスを段階的に物理アドレスに変換します。
- CR3レジスタに、ページディレクトリ(PD)のベースアドレスが格納される。
- リニアアドレスの上位10bitが、PD内のエントリのインデックス値を示す。
- PDは、4byteのPDE(構造体)を1024個格納した配列。
- 2^10=1024であるため、上位10bitで「0〜1023」の数、つまり任意のPDEのインデックス番号が表現可能である。
- CR3レジスタの値と、アドレス上位10bit(PDEのインデックス番号)の組み合わせで、任意のPDEを示す。
- PDEの下位12bitをマスクすると、ページテーブル(PT)のベースアドレスが取得できる。
- PTのベースアドレスと中10bit(PTEのインデックス番号)の組み合わせで、任意のPTEを示す。
- PTEの下位12bitをマスクすると、ページフレームのベースアドレスが取得できる。
- ページフレームのベースアドレスにオフセット(リニアアドレスの下位12bit)を加算することで、物理アドレスが示される。