next up previous contents index
Next: 4.2 Describing a Page Up: 4. Page Table Management Previous: 4. Page Table Management   Contents   Index

4.1 Describing the Page Directory

Each process has its own PGD (Page Global Directory) which is a physical page frame containing an array of pgd_t which is an architecture specific type defined in include/asm/page.h. How the page table is loaded is different for each architecture. On the x86, the process page table is loaded by copying the pointer into the cr3 register which has the side effect of flushing the TLB and in fact is how the function __flush_tlb() is implemented in the architecture dependent code.

Each entry in the PGD table points to a page frame containing an array of Page Middle Directory (PMD) entries of type pmd_t which in turn points to a page frame containing Page Table Entries (PTE) of type pte_t, which in turn points to page frames containing data. In the event the page has been swapped out to memory, the swap entry is stored in the PTE and used by do_swap_page() during page fault to find the swap entry containing the page data.

Any given linear address may be broken up into parts to yield offsets within these three page tables and finally as an offset within the actual page.

Figure 4.1: Linear Address Bit Size Macros
\includegraphics[width=15cm]{graphs/address_size_macros.ps}

To help break up the linear address into its component parts, a number of macros are provided in triplets for each level, a SHIFT, a SIZE and a MASK macro. The SHIFT macros specifies the length in bits that are mapped by each level of the page tables as illustrated in Figure 4.1. The MASK values can be AND'd with a linear address to mask out all the upper bits and is frequently used to determine if a linear address is aligned to a given level within the page table. Finally the SIZE macros reveal how many bytes are address by each entry at each level. The relationship between the SIZE and MASK macros is illustrated in Table 4.2.

Figure 4.2: Linear Address Size and Mask Macros
\includegraphics[width=15cm]{graphs/address_size_macros_partII.ps}

For the calculation of each of the triplets, only SHIFT is important as the other two are calculated based on it. For example, the three macros for page level on the x86 is

  5 #define PAGE_SHIFT      12
  6 #define PAGE_SIZE       (1UL << PAGE_SHIFT)
  7 #define PAGE_MASK       (~(PAGE_SIZE-1))

PAGE_SHIFT is the length in bits of the offset part of the linear address space which is 12 bits on the x86. The size is easily calculated as $2^{PAGE\_SHIFT}$ which is the equivalent of the code above. Finally the mask is calculated as the negation of the bits which make up the PAGE_SIZE - 1. To determine if an address is page aligned, it is simply AND'd with the PAGE_MASK which will yield 0 if it is aligned. To force an address to be page aligned, the PAGE_ALIGN function is used.

PMD_SHIFT is the number of bits in the linear address which are mapped by the second level part of the table. The PMD_SIZE and PMD_MASK are calculated in a similar way to the page level macros.

PGDIR_SHIFT is the number of bits which are mapped by the top, or first level, of the page table. The PGDIR_SIZE and PGDIR_MASK are calculated in the same manner as above.

The last three macros of importance are the PTRS_PER_X which determine the number of entries in each level of the page table. PTRS_PER_PGD is the number of pointers in the PGD, 1024 on an x86 without PAE. PTRS_PER_PMD is for the PMD, 1 on the x86 without PAE and PTRS_PER_PTE is for the lowest level, 1024 on the x86.


next up previous contents index
Next: 4.2 Describing a Page Up: 4. Page Table Management Previous: 4. Page Table Management   Contents   Index
Mel 2003-01-14