i386 Paging

The basics of Intel i386 paging can be found at http://www.cs.nmsu.edu/~pfeiffer/classes/473/notes/intelvm.html. Here are some more advanced concepts...

Extended Paging

Beginning with the Pentium, the L bit (described in the text as the Page Size bit) is used to allow two different page sizes in Intel processors. If the L bit is 0, paging works just as described previously. If it's a 1, the following changes happen:

  1. The page size is 4M instead of 4K. All the other changes are just direct consequences of this.
  2. Pages are aligned on 4M boundaries instead of 4K boundaries.
  3. The page offset is 22 bits instead of 12 bits.
  4. Only the most significant 10 bits of the directory entry are used in performing the translation, instead of the most significant 20 bits. These point to a 4M page instead of to a page table.

Using 4M pages trades the convenience of having all memory managements the same size for the efficiency of not needing the page tables. In Linux, 4M pages are used for the translations of the kernel; since the kernel is never swapped out, these entries can just be set up once and the kernel removed from consideration by the memory management system.

Physical Address Extension

The maximum size of a process's virtual address space is limited to an architected 32 bits (4 GB). Intel has resisted the temptation to add hacks to their architecture to permit larger address spaces -- hacks which have been added to many past architectures, nearly always to the eventual chagrin of users as pointer arithmetic becomes awkward (this is actually a slight lie, since the i386 has always supported segmentation; arguably, the actual architected virtual space is either 45 or 46 bits, depending on how you want to count the size of the segment selectors). If your process needs more than 4GB, get a 64-bit processor.

However, there is a long history of having virtual and physical address spaces of different sizes. It's more common to see the virtual size larger than the physical size (hence the frequent misconception that the purpose of virtual memory is to make memory look larger than it really is), but server-class machines needing to support many processes have frequently had physical address spaces that are actually larger than the virtual space.

Starting with the Pentium Pro, Intel processors have supported a 36 bit physical address space. While the way this is done is a bit of a hack, it's integrated about as nicely as possible with the previous paging structure. Here's what happens:

  1. The physical address of a page table entry is expanded to 24 bits, so combining a 24 bit physical address with a twelve bit offset results in a 36 bit physical address.
  2. This, unfortunately, also increases the size of a page table entry to 36 bits. In order to keep indexing simple, the page table entry size is actually expanded to 64 bits (eight bytes); since we don't want to change the size of a page table, the number of entries in a table is reduced to 512.
  3. The same logic is applied to the directories, so a directory can now also only have 512 entries.
  4. A little arithmetic shows that we've only consumed 30 bits. So we add another level of paging; this is a little table that only contains four entries.

While there was quite a demand for this mechanism, it's probably safe to assume that most applications requiring more than 32 bits of physical address space will also be happier with more than 32 bits of virtual space, and are probably migrating to 64 bit processors as fast as the old servers can be replaced.

One Last Note

Our text describes Linux as using a three-level paging structure. In the release announcement for kernel 2.6.11-rc1, Linux Torvalds notes that a four-level page table patch was merged; I'm not seeing any sign of it in our kernel, which is 2.6.11.4. Either I'm looking in the wrong place or it was backed out again...


Last modified: Mon Aug 29 09:24:54 MDT 2005