页式存储确实是操作系统中各种考试必考的东西,足见其重要性。对于页式存储,作者在书中给出了一道命题作文,即使用页式存储,让线性地址等于物理地址。在这里涉及到两个问题:1是线性地址还是那样得到的吗?2页表怎么组成。首先是第一个问题,月亮还是那个月亮,线性地址还是那个线性地址,只是我们现在审视线性地址的角度已经发生变化,我们将线性地址分成了三个层次来考察,在页目录中的偏移,在页表中的偏移,在页中的偏移,其实,这32位数值,与我们没有启用分页机制时用到的线性地址完完全全一样,就像是研究人类社会的经济活动,古代大家也是用钱币进行交换,但是那时人们还不是很能发现里面的规律,等到亚当斯密一部分人的出现,人类的经济活动好像就有了规律可循,以至于经济学发展到今天的模样。我们对线性地址进行了细分,是操作系统工作的重要进步,以后我们会不会发现32位里面更多的用处与规律,不得而知,说不定到时候直接没有线性地址了,但是,此时,我们必须要佩服这种机制的存在。
下面是第二个问题,页表怎么组成,应该说现在这个操作系统还不是很完整,我们也不好说,系统页,用户页怎么区分还不是很明了,但是在分页机制的初步,作者让线性地址等于物理地址,这,有利于让我们快速掌握分页这个东西是什么。
好了,怎么实现线性地址等于物理地址呢,这好像是个考研的OS试题,我们来捋捋吧。首先,分页机制最终的目的也是在物理内存中找到程序的数据,我们在OS中学过,如果采用分页机制,那么实际的物理内存也是在逻辑上以一个一个页/框的形式存在,因此,我们知道了,在页表中,每一个表项指向的是物理页/框的基地址,找到这个基地址,!注意这里是很关键的一步!,找到这个基地址,但是这个基地址并不是我们所谓的“基地址:偏移”这种模式中的基地址,因为我们这里得到的地址仅仅实际物理内存页/框的基地址,而如果将这一步得到的基地址误认为是我们想要的基地址的话,线性地址中的后12位,我们是没有用到的。因此,我们真正的基地址应该是在找到物理页之后,再在这个物理页中加上线性地址低12位偏移后的地址,这才是我们“基地址:偏移”中的基地址,那么到这里我们也就明白了,其实所谓的分段机制,分页机制,主要处理的还是基地址的确定,至于”偏移“,那只是我们在处理基地址之后的一个简单的偏移。在这里我想大家肯定都有这样的疑惑:分页机制使得”基地址:偏移“中的基地址处于一个实际物理页的内部了,也就是所谓的基地址并不是从本页的第0个单元开始,那么如果”偏移“过大的话,目标位置岂不是超过了本页/框的范围了吗?是的,这也是我疑惑的地方,具体怎么解释我还不好说,只能说到现在为止还没有发现能够解释的例子,这应该是编译器的问题,编译器会调整其中的偏移关系,不会出现这么大的偏移,甚至会调整页的首地址,我一度认为启动分页机制后,GDT中每个段的基地址都会是4k对齐的,但是反汇编了一下,不对,所以我现在是知道了这个原理,至于具体的实现细节,我相信以后的学习中会有所涉及。好了,继续解决问题。没有启动分页机制的话,是通过选择子找到GDT中的基地址,然后基地址加上偏移地址。马上,知道了,如果要物理地址等于线性地址,那么页表中的内容,应该等于线性地址的高20位,只有这样,那么加上低12位的偏移,启动分页机制前后“基地址:偏移”模式中的“基地址”才能一样。怎么样才能实现这一想法?很简单,因为我们的1024个页表是顺序存放的,并且页目录的第一个表项指向第一个页表,第二个表项指向第二个页表,....,第1024个页目录表项指向第1024个页表,一切都是按照顺序,那么,那么这4GB的物理/线性地址足可以用1024*1024个表项来体现,因此,只要每个表项的首地址从0开始,依次加上4096即可,作者是这么做的。