分页的关键在于它处理“块”内存。
它是一个映射,一个函数,将虚拟地址转换为物理地址,但不是基于地址的地址。相反,连续虚拟地址的“块”被一起翻译成另一个连续“块”,现在是物理地址。
您可以将其视为对“块”内存的“翻译”或“洗牌”。
“块”的正确术语是页面。
如果尝试进行示例映射,您会看到每个页面都包含一组地址,这些地址都具有特殊性:它们的低位 在从虚拟到物理传递时不会改变。相反,高位是任意的。
地址值的这种二分法定义了偏移量和页/帧号。
偏移量是地址值中不经过任何转换的部分。
在一个 4KiB 的页面中,有 4096 个地址,每个地址都有自己的偏移量,因此偏移量的大小为 log2(4096) = log2(212) = 12 * log2(2) = 12 位。
简而言之,页面大小决定了偏移量大小。
有必要将内存分成页面而不是单词或字节,或者在另一种观点中,有必要将地址分组以转换为页面。
如果没有页面,用于翻译的元数据,用行话来说就是各个级别的页表,会比被翻译的要占用更多的内存!
由于它们的定义方式,偏移量相对于它们的页面/帧:第 8 帧中的偏移量 1024(十六进制 400h)表示地址 8000h + 400h = 8400h;如果页面映射到第 12 帧,则偏移量 1024 在帧开始之后仍然是 1024 字节,0c000h + 400h = 0c400h。
作为一个地址,偏移量通常表示一个字节,在架构中字节不可寻址的事件。但是,这不是标准约定,要知道偏移量是表示一个字还是一个字节(例如,如果帧 0 的偏移量 10 是字节 40 还是字节 10),请查看架构手册。第一部分通常专门用于建立一个贯穿全书的术语。
分页发生在 CPU 访问内存之前,您可以将其视为高级进程。访问内存/总线的单元大多不知道它,因此 CPU 读取指令告诉它读取的数据(一个字、一个字节等)。
人们谈论移动页面是因为页面是可以表征的最小单位。
您可以将页面标记为不存在,但不能标记单词。您可以将页面设为只读,但不能设为单词。
如果你需要映射,比如说 16 个字节,你仍然需要映射整个页面,因为 16 个字节是不可表征的。所以我们不妨读一整页。
当发生页面错误时,意味着访问的页面在页表中的任何级别都不存在。
这可能意味着很多事情,从简单地切换当前位(页面仍然存在)到页面已保存到磁盘并在内存中归零的事实。
由于映射函数是 total,这意味着每个值都是有效值,因此 CPU 需要一种方法来知道值何时无效。
Present 位执行此操作:告诉 CPU 不得执行转换,而必须引发异常。
操作系统使用此异常来通知何时需要页面,它不需要将映射重新分配到另一个页面或将内存归零。
当人们说页面被删除时,他们的意思是它已从映射中删除,所有现代操作系统也会将该页面归零,以防止信息泄露给其他进程。
因此,如果一个物理帧没有被映射,并不意味着另一个进程中的另一个页面正在映射它,它只是意味着该地址范围不能被访问。
如上所述,操作系统这样做有很多原因,包括保护。