接上,页是地址空间的计量单位,并不是专属物理地址或线性地址,只要是4KB的地址空间都可以称为一页,所以线性地址的一页也要对应物理地址的一页。一页大小为4KB,这样一来,4GB地址空间被划分成4GB/4KB=1M个页,也就是4GB空间中可以容纳1048576个页,页表中自然也要有1048576个页表项,这就是我们要说的一级页表。一级页表如图:
这是一级页表模型,由于页大小是4KB,所以页表项中的物理地址都是4k的整数倍,故用16进制表示的地址,低3位都是0。就拿第3个页表项来说,其值为0x3000,表示该页对应的物理地址是0x3000。
可能,您心里一直有个疑问:页表如何使用呢?也就是如何将线性地址转换成物理地址呢?
还是用图5-10帮助理解,滑块正落到在32位地址的第12位。右边11~0位用来表示页的大小,也就是这12位可以做为页内寻址。左边31~12位用来表示页的数量,同样这20位也用来索引一个页(索引范围0~0xfffff),表示第几个页,对吧。
其实也可以这样理解:任意一个地址最终会落到某一个物理页中。32位地址空间共有1M(1048756)个物理页,首先要做的是定位到某个具体物理页,然后给出物理页内的偏移量就可以访问到任意1字节的内存啦。所以,用20位二进制就可以表示全部物理页啦。标准页都是4KB,12位二进制便可以表达4KB之内的任意地址。
在32位保护模式下任何地址都是用32位二进制表示,包括虚拟地址也是。经以上分析,虚拟地址的高20位可用来定位一个物理页,低12位可用来在该物理页内寻址。这是如何实现的呢?物理地址是写在页表的页表项中,段部件输出的只是线性地址,所以问题就变成了:怎样用线性地址找到页表中对应的页表项。
在此之前,大家要知道两件事:
- 分页机制打开前要将页表地址加载到控制寄存器cr3中,这是启用分页机制的先决条件之一,在介绍二级页表时会细说。所以,在打开分页机制前加载到寄存器cr3中的是页表的物理地址,页表中页表项的地址自然也是物理地址了。
- 虽然内存分页机制的作用是将虚拟地址转换成物理地址,但其转换过程相当于在关闭分页机制下进行,过程中所涉及到的页表及页表项的寻址,它们的地址都被cpu当做最终的物理地址(本来也是物理地址)直接送上地址总线,不会被分页机制再次转换(否则会递归转换下去)。
刚才说过啦,如何通过线性地址找到其对应的页表项才是转换的关键。既然页表是位于内存中,所以只要提供页表项的物理地址便能够访问到页表项。页表本身属于线性表结构,相当于页表项数组,访问其中任意页表项成员,只要知道该表页项的索引(下标)就够了。
分析过后,地址转换过程原理如下:
一个页表项对应一个页,所以,用线性地址的高20位做为页表项的索引,每个页表项要占用4字节大小,所以这高20位的索引乘以4后才是该页表项相对于页表物理地址的字节偏移量。用cr3寄存器中的页表物理地址加上此偏移量便是该页表项的物理地址,从该页表项中得到映射的物理页地址,然后用线性地址的低12位与该物理页地址相加,所得的地址之和便是最终要访问的物理地址。
曾经有同学对地址转换过程感到迷惑,误以为启用分页后,页表项地址也是虚拟地址,还需要被转换,转换过程无限递归下去,这显然是不对的。
以上所说的转换步骤多少都有点麻烦,既然地址转换算法已经是固定的了,何不使其在硬件一级自动完成呢。有道理,所以cpu中集成了专门用来干这项工作的硬件模块,我们把该模块称为页部件。当程序中给出一个线性地址时,页部件分析线性地址,按照以上算法,自动在页表中检索到物理地址。
总结一下页部件的工作:用线性地址的高20位在页表中索引页表项,用线性地址的低12位与页表项中的物理地址相加,所求的和便是最终线性地址对应的物理地址。
咱们还是通过例子来理解转换过程吧。拿mov ax,[0x1234]来说,其地址转换完整过程如图:
假设咱们是在平坦模型下工作,不管段选择子值是多少,其所指向的段基址都是0,指令mov ax,[0x1234]中的0x1234称为有效地址,它做为“段基址:段内偏移地址”中的段内偏移地址。这样段基址为0,段内偏移地址为0x1234,经过段部件处理后,输出的线性地址是0x1234。由于咱们是演示分页机制,必须假定系统已经打开了分页机制,所以线性地址0x1234被送入了页部件。页部件分析0x1234的高20位,用16进制表示高20位是0x00001。将此项做为页表项索引,再将该索引乘以4后加上cr3寄存器中页表的物理地址,这样便得到索引所指代的页表项的物理地址,从该物理地址处(页表项中)读取所映射的物理页地址:0x9000。线性地址的低12位是0x234,它做为物理页的页内偏移地址与物理页地址0x9000相加,和为0x9234,这就是线性地址0x1234最终转换成的物理地址。
一级页表说了这么多,完全是为了讲述页表原理,这样就能更好的理解下面要讲的二级页表,它们在原理上一脉相承。因为目前现代操作系统一般都是用二级页表,咱们的系统也采用二级页表,下一节咱们再见啦。