分页机制在段机制之后进行,已完成线性地址——物理地址段转换。段机制把虚拟地址转换为线性地址,分页机制进一步把该线性地址再转换为物理地址。
1线性地知道物理地址的转换
第一步,用32位线性地址的最高10位第31~22位作为页目录项的索引,将它乘以4,与CR3中页目录项在内存的地址,获得相应目录项在内存的地址。(索引代表的是第几个,乘以4得到距离起始地址的地址偏移量)
第二步,从这个地址开始读取32位页目录项,取出其高20位,再给低12位补0,形成的32位就是页表在内存的起始地址。
第三步,用32位线性地址中的第21~12位作为页表中页表项的索引,将它乘以4,与页表的起始地址相加,获得相应页表项在内存的地址。
第三步,从这个地址开始取32位页表项,取出其高20位,再将线性地址的第11~0位放在低12位,形成最终32位的页面物理地
本图更清晰的解释了线性地址如何转换到物理地址。
具有两级页表的线性地址:页目录共有1K个表项,于是,线性地址最高的10位(即22~31位)用来产生第一级的索引。两级表结构的第二级称为页表,每个页表也刚刚好存放在一个4KB的页中,并且每个页表包含1K个表项。第二级页表由线性地址中间的10位(即21~12位)进行索引,最低12位表示页内偏移量。(一个页目录包含1024个页表,一个页表包含1024个页,而2的10次方得1024,所以两个索引都占10位)。
linux中的分页机制为三级分页模式:
一个虚拟地址会被分为五个部分,页全局变量PGD(Page Global Directory),页上级目录PUD (page upper directory),页中间目录PMD(page middle directory),页表PT(page table)以及偏移量offset,其中的页表叫做页表项PTE(page tabe entry)。也就是说一个线性地址中除去偏移量,分别存放了四级目录的索引值,具体的线性地址翻译成物理地址的过程是:首先从进程地址描述符(mm_struct)中读取pgd字段的内容,它就是页全局目录的起始地址:然后页全局目录起始地址加上页全局目录索引获得页上集目录的起始地址;页上级目录的起始地址加上页上级目录的索引获得页中间目录的起始地址;页中间目录的起始地址加上页中间目录的索引获得页表的起始地址;页表起始地址加上索引,可以得到完整的页表项内容;从页表项中取出物理页的地址,加上偏移量可以得到最终的物理地址。