http://www.wowotech.net/memory_management/mm-init-1.html文章来源
假设48 bit的虚拟地址配置,4k的page size,这时候需要4级映射,地址被分成9(level 0 or PGD) + 9(level 1 or PUD) + 9(level 2 or PMD) + 9(level 3 or PTE) + 12(page offset),假设我们分配4个page分别保存Level 0到level 3的translation table,那么可以建立的最大的地址映射范围是512(level 3中有512个entry) X 4k = 2M。2M这个size当然不理想,无法容纳kernel image的地址区域,怎么办?使用section mapping,让PMD执行block descriptor,这样使用3个page就可以mapping 512 X 2M = 1G的地址空间范围。当然,这种方法有一点副作用就是:PAGE_OFFSET必须2M对齐。对于16K或者64K的page size,使用section mapping就有点不合适了,因为这时候对齐的要求太高了,对于16K page size,需要32M对齐,对于64K page size,需要512M对齐。不过,这也没有什么,毕竟这时候page size也变大了,不使用section mapping也能覆盖很大区域。例如,对于16K page size,一个16K page size中可以保存2K个entry,因此能够覆盖2K X 16K = 32M的地址范围。对于64K page size,一个64K page size中可以保存8K个entry,因此能够覆盖8K X 64K = 512M的地址范围。32M和512M基本是可以满足需求的。最后的结论:swapper进程(内核空间)需要预留页表的size是和page table level相关,如果使用了section mapping,那么需要预留PGTABLE_LEVELS - 1个page。如果不使用section mapping,那么需要预留PGTABLE_LEVELS 个page
此段的个人理解:
对于64位系统而言,一个entry是64位:
1个page 4k,那么可以保存512个entry(4*1024/8 = 512),一个entry可以指向一个4k的page,那么映射的范围为:512*4k = 2M
一个entry是64位,1个page 16k,16*1024/8 = 2k,那么可以保存2k个entry,需要11位虚拟地址来索引2k个entry
1个page 64k,那么可以保存8k个entry,64*1024/8 = 8k
另外:
1个page 4k,那么可以保存512个entry(4*1024/8 = 512),各个translation table的level为9,2^9 = 512,即虚拟地址中,就可以
用9位来索引512个entry了
16k 16384 14位
16384/8 = 2048 = 2k个entry 需要虚拟地址的11位来索引2k个entry
48 64k 16位页内偏移 每个entry 8个byte,共有8k个entry, 索引 8k entry 需要13个bit
页表基地址 pgd/pud pmd pt offset level = 3
16 6 13 13 16
48 4k 12位页内偏移 每个entry 8个byte,共有512个entry, 索引 512个 entry 需要9个bit
页表基地址 pgd pud pmd pt offset level = 4
16 9 9 9 9 12
48 16k 14位页内偏移 每个entry 8个byte,共有2048个entry, 索引 2048 个 entry 需要11个bit
页表基地址 pgd pud pmd pt offset level = 4
16 1 11 11 11 14
47 16k 14位页内偏移 每个entry 8个byte,共有2048个entry, 索引 2048 个 entry 需要11个bit
页表基地址 pgd /pud pmd pt offset level = 3
16 11 11 11 14
47 4k 12位页内偏移 每个entry 8个byte,共有 512 个entry, 索引 512 个 entry 需要 9 个bit
页表基地址 pgd /pud pmd pt offset level = 3
16 9 9 9 12