《Operating System:Three Easy Pieces》阅读笔记<十>——分页(一)(paging-intro)

139 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

分页(一)

segmentation方法是将空余空间分为variable-sized即可变大小的块,也由此带来了fragmentation的问题。我们介绍一种新的基于fixed-sized的方法,称为page(分页) ,即基本思想就是将物理内存分为固定大小的page frames,每一个frame都可以对应一个virtual-memory page。page最大的优点就是灵活,系统能够高效的提供地址空间的抽象,而不用管进程怎么使用这些虚拟内存。page架构的模型如下图所示。

在这种架构下如何将进程的地址空间访问转化为物理内存的访问?操作系统为每一个进程都提供了一个数据结构称为page table,用来存储每一个进程由地址空间到物理地址的address translation。这种情况下,进程发出的每一个虚拟地址都不是单独的地址大小(偏移量),而是包含了至少两部分,即virtual page number (VPN)和offset,offset的概念上一节已经提到过了。我们举例一个大小为64 bytes的address space,每一个page是16 bytes,那么地址空间总共就有4个page,因此这个进程的虚拟地址总长是6 bit,其中2 bit是VPN,意思是属于哪一个page,例如01表示第一个page,4 bit是offset。

操作系统和硬件一起将这个虚拟地址转化为物理地址,如上图所示,物理地址也是由一片片page组成的,由此我们得到VPN后就在page table中找这个属于这个进程的VPN对应的page是物理内存中的哪一个page,具体的说,地址空间01的page由地址转换器映射到PFN为111也就是物理地址的第8个page。

此处如果我们假设地址空间中的4个page都已经分配了,那么page table中就会存储有4个physical address

那么page table存储在哪里呢?对于一个32位、4KB per page的系统来说,光是VPN就有20位,一个X86系统的page table也有32位那么多,因此一个进程的page table就占用空间比较大,所有进程的page table加起来是相当大的。不可能存储在除存储硬件以外的硬件里,因此page table就存储在内存中,有可能在操作系统内存区以外的内存(老系统),也有可能在操作系统内存区中(现代系统)。

2的30次方是1G,因此32位的系统一个进程的地址空间就是4GB,一个64位的系统一个进程的地址空间则大到几乎是无限的

那么page table中存储着什么呢?以一个x86系统的page table为例,32位长度的page table占最多的是PFN,通过PFN可以直接映射到物理内存的某一个page上。此外还有一些用于其它功能的bit位,例如protection bit、present bit、dirty bit、reference bit、accessed bit、read/write bit等。

那么page table到底如何工作呢?一个虚拟地址的VPN被提取出来后,经由专门的page table base register得到属于这一VPN的page table的物理地址,硬件再由物理地址提取page table中的PFN等信息找到实际的物理地址,可以发现,这一过程比segmentation多了一步查找-转换。导致page在实际上是比较慢的,事实上,内存读取速度可能慢两倍甚至更多。要想实现可用的page策略,必须更加仔细的设计硬件和软件。

下图是page table工作流程的伪代码。比较详细的介绍了page table如何将虚拟地址转化为物理地址的整个过程。

最后我们以一个C程序为例,看一看在page架构下,进程实际的内存访问情况。

C程序很简单,循环赋值一个长度为1000的数组,右边是它的二进制码编译而来的机器语言。

实际的内存访问情况如图