1.分页的机制废弃了分段的设计,之前我们在博客中说过分段模式,即每一个进程有自己的段描述符,记录了自己的各个段基址。分页机制实际上废弃了这种设计模式。
2.分页机制实际是把所有的段基址都设置为0,很显然如果关闭分页机制那么线性地址就是物理地址如果开启了就不能是直接的对应关系了。
3.假设我们不知道分页机制怎么做,猜测一下他必须实现的功能有1.隔离不同进程的相同地址值,也就是说同一个线性地址在不同进程中会被映射到不同的物理地址中。2.实现线性地址向物理地址的映射。
4.我们先说一下分页的设计原理。首先我们把线性地址以4kb的大小切分,同样也把物理地址按照4kb的大小进行切分,是不是想到了磁盘分块?是的道理差不多的,我们只需要把线性地址对应的块对应到物理地址就ok了。对应的方式有很多种我们只说一下一级分页和二级分页。
5.一级分页。我们现在内存弄一块连续的空间(页表),多大呢?线性地址有4G(2^32个内存单元),以4KB(2^12)切分能切分为2^20个单元(页表项),每一个单元有32位。我们得到一个线性地址32位,首先拿到高20位作为这段内存的索引,得到一个32位单元,这32位存放着物理地址单元的基地址,有意思的是由于线性地址和物理地址都是以4kb做切分所以,分开的这些单元首地址最低12位肯定都是0,所以我们的最低12位不会存为0而是存一些该页面的属性比如权限神马的。线性地址高20为索引在页表中得到页表项,页表项的前20位再连接上线性地址的后12位得到一个物理地址,这么看线性地址的后12位可以看做偏移地址了。关于该页的其他属性在页表项的后12位存储着。
6.为了让进程编程地址独立,每一个进程都有自己的页表,与3中提及的一样,那么每一个进程的页表基址怎么得到呢,老办法用寄存器呗。
7.一级页表有两个遗憾,1页表在内存分配必须连续,不然怎么索引啊2每一个进程的页表必须都是实实在在占用4M的,必须全部分配完毕,进程才可用奥。
8.为了解决这两个遗憾人们开始用二级分页。一级分页中线性地址被分为两部分高20位索引页表项取得物理地址基地址,低12位物理地址偏移地址。在二级分页中线性地址被分为3部分,高10位,中10位,低20位。具体的名称就不多说了,因为说了反而会觉着混乱。高10位用于在一张2^10大的表中获得一个地址,这个地址又指向一个内存表,这个内存表很明显了也是2^10大小,这个内存表中存放物理地址的高20位,连接上线性地址的低12获得物理地址。你会问了尼玛这一点没有节约啊,妙处在于当一级表被索引的时候,索引到的单元指向的第二张表才会被动态分配。二级表很明显也不用在内存连续分配。
参考 http://blog.163.com/wmk_2000_ren/blog/static/1388461922010228101742134/