1GBページでのページングでは,4KBページでのページングとは違い,ページディレクトリやページテーブルを使用せず,PDPT (Page-Directory-Pointer-Table) が物理アドレスを格納します.この物理アドレスは,1GB単位である必要があります.
丁度今,仮想アドレス0xFFFF_FFFF_8000_0000を,物理アドレス0x10_1000へマッピングをしようと,以下のように間違ったコードを書きました.
lea edx, [KERNEL_PDPT_LMA] /* EDX <- PDPTの物理アドレス */ lea eax, [KERNEL_LMA] /* EAX <- 0x10_0000 */ or eax, 0x83 /* 1G, writable and present */ mov [edx + 510 * 8], eax mov dword ptr [edx + 510 * 8 + 4], 0 add eax, 1024 * 1024 * 1024 /* 1GB */ mov [edx + 511 * 8], eax mov dword ptr [edx + 511 * 8 + 4], 0
QEMUで実行し,デバッグモニタで確認すると,以下のような誤ったマッピングが表示されてしまいました.
(qemu) info tlb (前略) ffffffff80000000: 0000000000000000 --P-----W (後略)
これは,物理アドレス0x10_0000が,1GB単位のアドレスではなかったためです.
ところで,IntelのSDMのVolume3,Figure4-11を確認すると,1GBページを使用する場合,PDPTの第13ビットから第29ビットが,Reservedになっていることがわかります.これらのビットは0でなければならないのです.