整个内存空间的MMU 配置
static void __init map_mem(void)
{struct memblock_region *reg;
/* map all the memory banks */
for_each_memblock(memory, reg) {
phys_addr_t start = reg->base;
phys_addr_t end = start + reg->size;
if (start >= end)
break;
create_mapping(start, __phys_to_virt(start), end - start);
}
memblock.memblock_type 通过设备树传给内核,传给内核的也是起始地址和长度
create_mapping,接受虚拟地址,物理地址和长度,创建mmu 页表映射
create_mapping-----alloc_init_pud-------alloc_init_pmd-----alloc_init_pte
在这里pud 和pgd 相等
主要操作为
1.alloc_init_pmd
2.alloc_init_pte:在这里没有调用
ARMv8架构可以支持48位虚拟地址,并配置成4级页表(4K页),或者3级页表(64K页)。而本Linux系统只使用39位虚拟地址(512G内核,512G用户),配置成3级页表(4K页)或者2级页表(64K页)用户空间的地址63:39位都置零,内核空间地址63:39都置一
对于4K 的页表 pgd=pud,512 个条目,4K 空间大小,表示全部的512G 的内存。
pmd:512 个条目,4K 空间大小,表示512 个2M 的内存
pte:512 个条目,4K 空间大小,表示512 个4K 的页
page offset:4K 空间表示页内偏移
举例子:
swapper_pg_dir:0x7d000(高32 位为0xffffffc0)
物理地址为0,虚拟地址为0xffffffc000000000,39 位有效地址为0x8000000000
offset=0x8000000000>>30,表示第几个1G,得出的结果为第256G 开始的地址,0x100,每个条目用8个字节表示,所以
pgd:0x7d800,
pud:0x7d800,
pmd 所在的页表空间起始地址 为0x7e00,在head.s 中,根据gdir 划分了4K 的空间放pmd
如果设备树传入的内存大小为512M,那么,pmd 需要将这512M 按照2M 一个条目,总共256 个条目放在pmd 页表空间
ARMv8(aarch64)页表建立过程详细分析
Linux内存管理--基本概念
【深入理解Linux内核】【分页】相关函数或宏
内存映射的初始化