- 论坛徽章:
- 4
|
ARM在内存管理上,和x86的区别主要是页表构造不同。
kernel里的注释已经说的比较清楚了,解释arch/arm/include/asm/pgtable.h里的注释如下:
从硬件上说,ARM期望使用二级页表结构:
1) 第一级有4096个目录项
2) 第二级的每个表中,有256个目录项
每个目录项均为32bit。
第二级中,每个目录项指向了4096大小的page。这样,系统共 :pgd的4096项 * pte的256项 * 每页的4096大小 = 4G地址空间。
ARM的问题是,第二级每个目录项的32bit中,绝大部分已经为硬件所使用,并且没有accessed与dirty位。
accessed位为内存回收的依据,确定每个页在LRU链中位置;
dirty位作为内存回写的依据,脏页面应回写至文件或交换区。
因此,linux在构造页表时,制造了一个假象:
1) 硬件PGD还是4096项,每项4字节;但是linux按照PGD共2048项,每项8字节来计算,计算得来的每项中实际都含有两个pgd项。
2) 硬件PTE还是256项,每项4字节;但是linux每次分配pte表时,都分配4K大小的页,页的前2048字节折合512个pte项,即折合两个硬件的pte表;页的后2048字节留作它用,折合为虚拟的512个pte项,即折合两个虚拟的pte表,与前半页对应。
这样,2)中前半页折合出来的两个硬件pte表,正好填入1)中的2个pgd项中。
而且:
2)中前半页折合出来的两个硬件pte表中,每项都包含一些页的属性bit,如是否present,是否可写....这些属性均为ARM硬件支持的属性,命名为PTE_xxx
2)中后半页折合出来的两个虚拟pte表中,每项都包含一些页的属性bit,如是否accessed,是否dirty....这些属性均为ARM硬件不能支持的属性,命名为L_PTE_xxx
这样,就能模拟出来诸如accessed,dirty.....这样硬件还不支持的属性。
比如说模拟dirty:我们可以另页属性为不可写,一个写操作将引发页保护异常,进入到页异常的处理程序handle_pte_fault()后,linux将把虚拟pte项中置上L_PTE_dirty标志,同时将硬件pte项修改为可写;kswapd在操作LRU的时候,将清除掉虚拟pte项中的L_PTE_dirty位,同时也清除掉硬件pte项中的可写属性
比如说模拟access:我们可以清掉硬件pte中的present位,另映射不存在,一个读写操作将引发缺页异常,进入到页异常的处理程序handle_pte_fault()后,linux将把虚拟pte项中置上L_PTE_accessed标志,同时将置位硬件pte项的present位;kswapd在操作LRU的时候,将清除掉虚拟pte项中的L_PTE_access位,同时也清除掉硬件pte项中的present属性
注释中最后还提到,这么搞的话,应注意刷TLB,以另对硬件pte项的修改可见。 |
|