如何管理超大虚拟地址空间?
方法一:多级页表
关键:避免一直将所有页表都保存在内存,尤其不应该将不需要的页表还保存在内存中。
假设虚拟地址是32-bit的,即整个虚拟地址空间的大小为2^32 B=2^10 *2^10 *4KB;每个虚拟页的大小均是4KB,则共有2^20个虚拟页;
32-bit的虚拟地址分为三个部分:
- 10-bit的PT1字段
- 10-bit的PT2字段
- 12-bit的偏移字段
现有一个12M的进程:4M的.txt段+4M的.data段+4M的stack段,在.data段的顶部和.stack段的底部之间有一个巨大的洞是未被使用的。
有两级页表
- 1级页表共有1024(2^10)条记录,因为PT1字段有10-bit;每条记录都指向一个4M大的虚拟地址空间
- 2级页表共有1024个,每个占据的大小是4KB,每条记录包含物理页帧号
那么,记录0指向.txt段,记录1指向.data段,记录1023指向.stack段。
值得注意的是对于这个进程的虚拟地址空间来说,实际上只需要四个页表:1级页表,0到4M-1的二级页表,4M到8M-1的二级页表,顶部4M的栈对应的二级页表;在1级页表中,将其余的1021条记录的Present/absent位均设置为0,即如果这些记录被访问,即会报页面错误。
使用二级页表后的地址转换过程:
- 当MMU接收到一个虚拟地址的输入时,首先提取高10-bit的PT1字段,使用这个字段作为索引,到一级页表中查找对应的记录。如果1级页表中存在这样的记录,则执行步骤2
- 提取紧邻的10-bit的PT2字段,作为索引,到二级页表中查询相应的记录,如果存在,则执行步骤3;如果不存在或者Present/absent位是0,则执行步骤4
- 找到对应的物理页帧号,与Offset字段值一起拼接为实际的物理地址,返回即可
- 执行页面错误的操作步骤,然后执行步骤1