The following is assuming 32-bit architecture in Protected mode and Paging enabled (WinXP). Each Page Table can describe 4mb of physical memory (1024 entries pointing to 4k pages = 4k*1024 = 4mb). The Page Directory can describe 1024 Page Tables, meaning 1024 * 4mb = 4gb of virtual address space. This makes sense, since Windows supports 4gb virtual address space for each Process. Windows maps the Page Directory at virtual address 0xC0300000 and begins Page Tables at 0xC0000000. This means 0x300000 bytes are avaiable for Page Tables. Each Page Table is 1024 Dword entries = 1024 * 4 bytes = 0x1000 bytes per table. 0x300000/0x1000 = 0x300 = 768 Page Tables, not 1024 which is actually possible. This accounts for 1gb less of virtual memory. Kernel code uses Large Pages which don't require Page Tables, but on my system I only count 23 large pages = 92mb, not 1gb. Is Windows advertised 4gb address space really only 3gb??
Posted on 2005-02-07 22:42:10 by The Dude of Dudes
My basic question was why does windows put the Page Directory smack-dab in the middle (or last quarter in this case :) ) of the Page Tables. I think I found the reason why. It seems the Page Directory is aliased as a Page Table when referencing addresses 0xC0000000-0xC03FFFFF. To prove this I got the Physical Address of the Page Directory (0xC0300000) by calling MmGetPhysicalAddress and compared it to the Index value in the Page Directory entry at offset 0xC00. They were the same. What this means is the Page Directory points to itself as a Page Table for addresses 0xC0000000-0xC03FFFFF.
Posted on 2005-02-08 19:01:25 by The Dude of Dudes
Windows works in mysterious ways :)

Iirc the default NT model is to split the address space in 2gb for user and 2gb for kernel, with a boot option in some (datacenter?) versions to have 3gb for user and 1gb for kernel...
Posted on 2005-02-08 19:06:44 by f0dder