I've found that image:
and cannot find a reason why there is page directory ? I think that it could save time, if the process (or processes), especially the
CR3 register, points straight to the page table.
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It only takes a minute to sign up.Sign up to join this community
The MMU makes an arbitrary mapping of 32bits virtual addresses to 32bits physical addresses, with 4kB granularity.
The 4GB address range is divided into 1 million 4kB pages.
You could use a single array with 1 million page table entries, occupying 4MB (with 32 bits per PTE). You can use also "nested" page tables, which allows to reduce the memory footprint of the mapping tables, by marking some first level entries as unallocated.
Imagine when the first 386 computers were sold with 4MB RAM. Where would you put a flat page table ? Now, 64bits computers would need impossibly large page tables if these tables were not multilevel tables (4 levels on x64_64, IIRC)
An additional refinement is that page tables are per-application. Each application can freely use the whole virtual address range and the OS can decide which pages are exclusive, and which are shared (for example, a dynamic library code could be accessible from several programs). So, parts of the level 2 pages tables can be shared between applications, while the first level is separate for each task.
Traversing several tables takes time, the CPU keeps in "TLBs" (Translation Lookaside Buffers) last accessed page translations, and, sometimes, some intermediate page table entries are also cached, so that if a software uses contiguous memory, fewer accesses to RAM are usually needed.
As Wouter van Ooijen's comment hints, using a flat page table would use significantly more memory in the common case of dense allocation of physical memory to a small portion of the virtual address space. With a flat page table each process (address space) would use 4 MiB just for the page table. By using a page directory, a process with three address regions (text, data/heap, stack) that each fit within a 4 MiB chunk each would only require four pages (16 KiB) of page table space (one for the directory and one for each address region).
This arrangement can also facilitate sharing page tables. If the page directory entry masks permissions, it would even be possible have different permissions for the different processes while sharing the lowest level page table (e.g., one directory entry could mark the page table as allowing reads and writes while another directory pointing to the same page table might disallow writes).
(It would also be possible to provide different kinds of (region) metadata in the directory entry than the kinds of (page) metadata in the page table entry.)
In addition, multiple directory entries could point to the same page table. This could be used to allocate huge regions of zero page.
Using a directory has the side effect of providing a natural way to support huge pages by indicating that the page directory entry is actually a page table entry. (These huge page page table entries would then have ten extra bits that could be used to extend the physical address size or to provide metadata.)
Also note that just as page table entries can be cached (in the TLB), so page directory entries can be cached. Having the level of indirection is not free, but under common use patterns caching is reasonably effective.