linux内存管理之页表
来源:互联网 发布:淘宝联盟佣金怎么算的 编辑:程序博客网 时间:2024/06/05 21:14
什么是页表
页表就是用于将虚拟地址转换为物理地址的转换关系表。访问虚拟地址时,计算机通过页表找到对应的实际物理地址访问。
为何需要多级页表
目前在linux中采用4级页表,ARM32采用2级页表,ARM64采用4级页表。但linux是一个通用性的系统,当ARM32时2级页表也是使用linux的4级页表机制,只是将其它两级页表转换不做任何处理。
那么为什么需要多级页表呢?节省内存空间。二级页表可以在需要的时候才建立。
ARM32页表映射
页表查询
内核内存布局
Linux内核在启动的的时候会打印出内核内存空间的布局图。
ARM32内核的内存布局图如下所示。
页表建立分析
linux中使用map_desc数据结构完整地描述一个内存空间:
struct map_desc { unsigned long virtual; //虚拟地址 unsigned long pfn; //页框号 unsigned long length; unsigned int type;};
建立内核页表的过程
static void __init create_mapping(struct map_desc *md, bool force_pages){ unsigned long addr, length, end; phys_addr_t phys; const struct mem_type *type; pgd_t *pgd; if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx" " at 0x%08lx in user region\n", (long long)__pfn_to_phys((u64)md->pfn), md->virtual); return; } if ((md->type == MT_DEVICE || md->type == MT_ROM) && md->virtual >= PAGE_OFFSET && (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) { printk(KERN_WARNING "BUG: mapping for 0x%08llx" " at 0x%08lx out of vmalloc space\n", (long long)__pfn_to_phys((u64)md->pfn), md->virtual); } type = &mem_types[md->type];//根据mem_types建立页表#ifndef CONFIG_ARM_LPAE /* * Catch 36-bit addresses */ if (md->pfn >= 0x100000) { create_36bit_mapping(md, type); return; }#endif addr = md->virtual & PAGE_MASK; phys = __pfn_to_phys(md->pfn); length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not " "be mapped using pages, ignoring.\n", (long long)__pfn_to_phys(md->pfn), addr); return; } pgd = pgd_offset_k(addr);//计算出pgd end = addr + length; do { unsigned long next = pgd_addr_end(addr, end); alloc_init_pud(pgd, addr, next, phys, type, force_pages); //建立页表 phys += next - addr; addr = next; } while (pgd++, addr != end);}
ARM64页表映射
ARM64一般配置4KB大小页面,48位地址宽度,4级页表映射。
页表查询
内核内存布局
64位Linux已经没有了高端内存这个概念了。因为48位的寻址空间已经足够 大。用户空间和内核空间大小均可达256TB。
页表建立分析
类似于ARM32.不再描述。
内核页表与进程页表存放
内核页表
内核页表存放于init_mm结构体中的pgd中。其值由swapper_pg_dir决定。
swapper_pg_dir对于ARM32与ARM64值的计算方法不一样。
如ARM32时:
.globl swapper_pg_dir .equ swapper_pg_dir, KERNEL_RAM_VADDR - PG_DIR_SIZE
即kernel运行地址的前16k( PG_DIR_SIZE)
进程页表
每个进程都有自己的页表,存放于task_struct结构体中的pgd中。
阅读全文
0 0
- linux内存管理之页表
- 深入理解linux内存管理之 页表管理
- LINUX内存管理之页式管理
- linux内存管理 之 物理内存管理
- 浅析linux内核内存管理之临时内核页表
- 浅析linux内核内存管理之最终内核页表
- linux内存管理之页描述符
- linux 内存管理之kmalloc
- linux内存管理 之 DMA
- Linux内存管理之初始化
- linux内存管理之malloc
- linux内存管理之mmap
- linux内存管理之malloc
- linux内存管理之kmalloc
- linux内存管理之kmem_cache_init
- linux内存管理之vmalloc
- linux内存管理之malloc
- linux内存管理之DMA
- Spark SQL基础笔记及简单案例
- spring batch admin的安装配置基础
- <10/1>集训周记
- Solr搜索引擎(3)索引mysql数据
- 线程池TreadPoolExecutor
- linux内存管理之页表
- 2017开学训练第五周周末总结
- thymeleaf使用详解
- to_date() 与 to_char() 日期和字符串转换
- 使用Keepalived实现双机热备
- 解决Tensorflow使用CPU报错
- java实现网站访问量统计
- Got error -1 from storage engine
- HDU