分类: LINUX
2013-07-27 00:56:22
Linux中,arm架构下的虚拟内存管理主要用到了1M段映射和4K小页表映射。其中4K小页表映射为二级映射。按照目前内核代码的设置,从硬件角度看,二级映射第一级有4096个entry,第二级有256个entry,每个entry占用32个bit。也就是虚拟地址的bit[20]至bit[31]用于一级页表偏移,bit[12]至bit[19]用于二级页表偏移。
Linux页表管理也是分级结构,为了和arm硬件相匹配,只使用pgd和pte(pmd等于pgd),那么也就构成了软件上的两级结构。
下面看看硬件二级页表的位信息:
可见小页表映射的二级页表entry中的位基本上都被硬件使用了,且并没有linux中pte_t需要的accessed、dirty等位,这样就和linux的页表管理有些出入;另外linux希望pte页表本身也是一个页面大小(4K),而现在256个entry,也才1K。
因此linux内核在实现上做了些细微的调整,第一级有2048个entry,每个entry为8个byte,对于第一级的每个entry,第二级是两个连续的pte与之对应,同时接下来紧跟着两个软件版本的pte(linux pte),这两个pte不为硬件所使用,但可以在这两个pte中加入linux页面管理所需要的字段信息,满足linux自身页表管理需求。
相应的与一个pgd_t对应的二级页表有512个entry(硬件使用的entry),加上两个linux pte(总共也是512个entry),就构成了一个完整的4K大小的“pte”。一个pgd_t对应两个硬件一级entry,一个pte对应两个连续硬件二级页表。
先看看根据第一节的描述绘制的4K二级映射图(操作系统层面):
与之对应的硬件层面映射关系如下:
Arm巨页映射利用了操作系统层面的映射关系,一个pgd_t(pmd_t)映射256*2*4K = 2M,所不同的是巨页映射中,要求最后映射的4K页面是连续的,也就是每个pte_t指向的页面是连续关系,且要求这样的一个映射能对应1个tlb entry。对于软件层面的要求,硬件如何支持?巨页的目的是减少映射entry数量,降低tlb miss情况,可见基于4K的二级映射实际上不能满足要求。
我们来看看tlb能支持的映射规格:
映射关系 |
映射大小 |
N值 |
超级段 |
16M |
24 |
段 |
1M |
20 |
大页 |
64K |
16 |
小页 |
4K |
12 |
N值指页面大小或者块大小所占用的位数,就是说在tlb进行扫描时,是通过虚拟地址的bits[31:N]来进行匹配的。Arm巨页映射补丁目前选择段进行巨页映射支持。其关键步骤上利用4K页面分配连续物理内存,达到2M,然后使用1M段映射,对分配连续页面进行映射,两个连续的段映射entry即可完成对2M内存的映射,tlb对应使用两个entry。
通过这样的修改,tlb entry的使用将大大减少。
注意,此时虽然硬件上的映射已经上只有一级的段映射,但是linux管理上还是分级的,还是有pgd、pmd、pte等。