二级页表的地址映射过程
对于要求连续的内存空间来存放页表的问题,即难以找到大的连续的内存空间来存放页表的问题,可利用将页表进行分页的方法,使每个页面的大小与内存物理块的大小相同,并为他们进行编号,然后离散地将各个页面分别存放在不同的物理块中。同样,也要为离散分配的页表再建立一张外层页表,在每个页表项中记录页表页面的物理块号。
下面以32位逻辑地址空间为例,当页面大小为4k时,应该具有20位的页号(2^32/4k),若采用一级页表,页表项有1M个;若采用两级页表结构时,对页表项再次进行分页,使每页中有1024个页表项,最多有1024个分页。
上图显示了线性地址的格式。
处理器通过查询两级页表来将线性地址的DIR,PAGE和OFFSET字段转换为物理地址。寻址机制使用DIR字段作为页面目录的索引,使用PAGE字段作为页面目录确定的页表的索引,并使用OFFSET字段来寻址由页表确定的页面内的字节。
所以逻辑地址到物理地址的映射中,首先根据逻辑地址中外层的页号找到外层页表的始址,然后由外层页内地址来确定内层页表的始址;再利用内层页表项找到该页在内存中的物理块。由于块内地址=页内地址,所以用物理块号和页内地址即可构成访问的内存地址,也就是将20位物理页面地址和虚拟地址的低12位拼凑在一起,得到最终的32位物理地址。
ps:
对于上机课中提到的内存初始化的问题,C语言代码如下
virtual address [0-4M] => physical address [0-4M]
outter page table 0x1000
第0项指向inner page table
inner page table 0x2000
第0项映射0-4K
第1项映射4K-8K
第2项映射8K-12K
eax = 0|PTE_WRITE|PTE_PRESENT
edi = inner page table base address
for (ecx = 1024; ecx > 0; ecx--) {
[edi] = eax;
edi = edi + 4;
eax = eax + 4096;
}
地址 | outter page table,10位 | inner page table,10位 | offset,12位 |
---|---|---|---|
页表项中存放的内容 | inner page的首地址 | 对应物理块的首地址 |
所以对于上面的程序,循环计算1024次,edi是内部页表的地址,eax计算物理块的地址并将其存放到edi所指向的存储器中,虚拟地址每次加4,物理块地址每次加4k