armv8最多支持48根地址,4级页表,这样最多支持user space和kernnel space 分别是256TB
其中user space占据低端地址
kernel可以支持48/42/39 根地址
# CONFIG_ARM64_VA_BITS_39 is not set
CONFIG_ARM64_VA_BITS_48=y
最多四级页表
CONFIG_PGTABLE_LEVELS=4
可以支持4k/16k/64k的pages
arm64建立页表的函数为__create_pgd_mapping
static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
unsigned long virt, phys_addr_t size,
pgprot_t prot,
phys_addr_t (*pgtable_alloc)(void),
int flags)
{
unsigned long addr, length, end, next;
pgd_t *pgdp = pgd_offset_raw(pgdir, virt);
/*
* If the virtual and physical address don't have the same offset
* within a page, we cannot map the region as the caller expects.
*/
if (WARN_ON((phys ^ virt) & ~PAGE_MASK))
return;
phys &= PAGE_MASK;
addr = virt & PAGE_MASK;
length = PAGE_ALIGN(size + (virt & ~PAGE_MASK));
end = addr + length;
do {
#每个pgd的长度是PGDIR_SIZE,表示512GB
next = pgd_addr_end(addr, end);
#设置pud
alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc,
flags);
phys += next - addr;
} while (pgdp++, addr = next, addr != end);
这里会建立pgd,每个pgd表示的范围用PGDIR_SIZE 用来表示,在va=48bit,levels等于4的情况下。
PGDITR_SIZE 是512GB,PUD_SIZE等于1G,PMD_SZIE等于2M。PAGE_SIZE等于4K。因为PMD_SIZE等于2M。
所以hugepage 最小size等于2M
其中PTRS_PER_PDG/PUD/PMD/PTE 都等于512.
在映射的时候每个阶段都会按照size 作为步长来优化,例如PGD的步上就是PGDITR_SIZE等于512GB