按照 segmentation 来分配连续的内存,由于分配的是长度不定的单元,会造成大量的外部碎片。本章为了解决这个问题,将虚拟地址空间和物理内存分割成了固定大小的单元,虚拟地址空间中的单元称为 virtual page,物理内存中的单元称为 page frame。

  0 +-----------------+
    |                 | page 0 of the address
  16+-----------------+
    |                 | page 1
  32+-----------------+
    |                 | page 2
  48+-----------------+
    |                 | page 3
  64+-----------------+

virtual page 的地址包含两部分,一部分是 virtual page number, 另一部分是 offset。操作系统为每个进程分配一个 page table,用来存储 vpn 到 pfn 的映射,即翻译。由于 vp 和 pf 的大小是相同的,offset 无须翻译即可用来进行计算。

    |← VPN →|←    offset   →|
    +---+---+---+---+---+---+
    | 0 | 1 | 0 | 1 | 0 | 1 | virtual address
    +---+---+---+---+---+---+
      ↓   ↓   |   |   |   |
+-----------+ |   |   |   |
|  Address  | |   |   |   |
|Translation| |   |   |   |
+-----------+ |   |   |   |
  ↓   ↓   ↓   ↓   ↓   ↓   ↓
+---+---+---+---+---+---+---+
| 1 | 1 | 1 | 0 | 1 | 0 | 1 | physical address
+---+---+---+---+---+---+---+
|←   PFN   →|←    offset   →|

相对于 segment table 来说,由于将内存均分成了固定大小的区域,page table 非常的大。所以,对于 page table 来说,不会依赖于硬件的实现,而是将每个进程的 page table 存储在内存中。

page table 的不止存储了 vpn 和 pfn 之间的映射关系,还存储了一些额外的数据。例如 valid bit 来标识对于某个进程来说,一个特定的翻译是不是有效的。

31                                               11      9  8   7   6   5   4   3   2   1   0
+------------------------------------------------+-------+---+---+---+---+---+---+---+---+---+
|                    PFN                         |·······| G |PAT| D | A |PCD|PWT|U/S|R/W| P |
+------------------------------------------------+-------+---+---+---+---+---+---+---+---+---+
  • present bit (P): 标识当前页是在内存中还是在硬盘中。
  • read/write bit (R/W): 标识当前页是否可写。
  • user/supervisor bit (U/S): 标识当前页是否可以由用户进程访问。
  • accessed bit (A): 标识这个页是不是被访问过,以此为依据来进行页替换。
  • dirty bit (D): 标识这个页的数据在到达内存后有没有修改过。

其它的一些字段都是用来管理缓存的。