分页机制

 分页

操作系统管理内存的一种方式。他是将内存划分成一个一个页面,然后通过页表进行逻辑地址到物理地址的映射从而访问具体的物理地址。分页更好的对内存的划分与访问,但是也增加了系统的开销。例如页表本身占据一定的内存以及访问实际的物理内存时还需先访问页表。一般来说每个进程会分配到一个页表。最后对页表的设计需要谨慎。

页表结构

以上是一个cpu生成的一个逻辑地址空间,他需要通过页表将其映射成具体的物理地址空间。其中页索引是指向具体的页表条目。页表是存在与内存之中的一个一维数组。假设是32位系统,那么地址也是32位的。而假设页索引只用20位,那么他是如何指向内存中的页表条目的呢?(可以将地址的高12位全0加上低20位即可,当然他不可能是从内存0开始的,会有一个基址寄存器加上他的地址作为实际的地址。说白了就是在该页表中的偏移量)。还有一点要注意的是也为这张页表必须分布在连续的内存位置

假设一个计算机是32位(即cpu一次可以处理32位),那么地址空间范围是 0 ~ 2^32 。该系统采用的是分页的机制,且每个页面的大小为4k(2^12),那么可以产生 2^20(2^32/2^12) 个页。我们只需要使用20bit既可以定位到一个页的位置,因为页的地址都是2^12的倍数,即后12位一定全为0。而页偏移12可以定位到一个页面内的具体位置。

我们简单计算一下一个32位系统对于整个内存需要产生的页表大小,首先一个页表条目的大小位4B(即使32位),总的页表大小则为4B*2^20,也就是4MB的内存。这样对于每个进程都需要4MB来存页表,显然这是一种浪费。接下来我们就要介绍二级页表了,看是否能够解决这个问题。

二级页表

我们仍然假设系统是32位的,每个页面是4k。我们将页划分为10位页目录,作为页目录中的偏移量,页目录中的条目指向页表的首地址。10位的页表作为页表(内存中的页表)的偏移量。最后通过页表的条目中的20位和逻辑地址的偏移量进行相加得到最终的物理地址。其中上图最左边还有一个CR3寄存器,他是指向页目录(内存中的一个页表)的首地址的。还有一定值得注意的是内存中的页目录和页表的条目都是4B(32bit)。这里一直困扰着我,为什么不是10bit呢?后来一想,发现页表是在内存中的,而页目录中的条目要想指向页表的地址必须要32位才能够确定。(这里我说一下为什么我会想是10位呢?因为我们最初的设计二级页表的目的是为了减少页表在内存中的存储空间,而页表中的很多条目高10位可能是相同的,然后我们可以将高10位拿出来存在另外一个表中,其中的条目指向条目是低10位的表(这样的表有很多)。这样将公共部分提出来的方法就可以减少内存的使用了。但是事实并非如此。)

到这里我们会发现页表的内存并没减少,反而增加了(因为内存中的页表条目为4B)。增加的部分就是页目录所占的空间。这又是我产生了新的困惑,于是翻阅文章,才知道。这里页目录虽然增加了内存,但是分散了二级页表的在内存中的位置,即二级页表可以在内存中分散的分布,不必要像前面说的只有一张页表时必须要一个连续的4MB内存。还有就是页目录条目中有一个存在位,当该位为0时表示对应的二级页表在内存中不存在,如果对其访问可能产生异常。还有一个位表示对应的二级页表是在磁盘上还是在内存中,如果在磁盘上,而对其的访问操作系统便会从磁盘上将其换到内存中。当然还有很多位分别表示可执行,只读,读写。。。这里让我感到神奇的是,这里32位既能表示内存中二级页表的地址,又能用其中的几个位表示其他信息。到这里我们发现虽然页目录必须存在内存当中,但是二级页表并不需要全部存在内存之中,而且分散的分布在内存的各个位置。这就实现了我们开始的目的节省内存的需要。

总结一下:这里从一张页表到两张,可以将内存的中页表分散的分布,而且也节省了页表所占的内存空间。

猜你喜欢

转载自blog.csdn.net/weixin_41237676/article/details/100974132