linux采用了一种同时适用于32位和64位系统的普通分页模型。对于像32位arm系统来说两级页表已经足够,但64位系统需要更多数量的分页级别。2.6.10版本以前,linux采用三级分页的模型,从2.6.11版本开始采用4级分页模型。4种页表如下:

页全局目录(pgd)

页上级目录(pud)

页中间目录(pmd)

页表(pte)

其分页模型如下:

图中没有显示具体位数,主要是每一部分大小与体系结构相关。

对于没有启用物理地址扩展的32位系统使用两级页表,下面主要介绍基于32位的arm系统。

启动了物理地址扩展的32位系统使用三级页表。

64位系统使用三级还是四级分页取决与硬件对线性地址的位划分。

以下分析arm的二级页表:

1、四级页表与二级页表

linux模型是四级页表,而32位的arm是使用二级页表,之间如何对应起来:

pgd = pgd_offset_k(addr) = init_mm.pgd + ((addr)>>PGDIR_SHIFT)

#definepgd_index(addr)     ((addr) >>PGDIR_SHIFT)

#definepgd_offset(mm, addr)    ((mm)->pgd +pgd_index(addr))

#define pgd_offset_k(addr)  pgd_offset(&init_mm, addr)

pud_t *pud = pud_offset(pgd, addr) = pgd

static inlinepud_t * pud_offset(pgd_t * pgd, unsigned long address)

{

return (pud_t *)pgd;

}

pmd_t *pmd = pmd_offset(pud, addr) = pud =pgd

staticinline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)

{

return (pmd_t *)pud;

}

pte_t *pte = start_pte + pte_index(addr);

#definepte_index(addr)     (((addr) >>PAGE_SHIFT) & (PTRS_PER_PTE - 1))

从上面代码可以看出二级页表时,没有pud和pmd只剩下了pgd和pte。

2、页表类型

第一级页表pgd是由虚拟地址的高12bit(bits[31:20])组成,共有4096个表项,每个表项4个字节,因此4096 *4= 16K,这就是上面说的swapper_pg_dir总共为16K的原因,每个表项支持1MB,4096*1MB=4G。每个entry的最低2bit用来区分具体是什么种类的页表项,2bit可以区分4种页表项,具体每种表项的结构如下:

arm体系主要用到了sectionentry和fine page table两种页表类型。前者在linux内核启动的初始化阶段,建立临时页表使用;后者则是正常工作使用(见下一节分析)。

arch/arm/kernel/head.S中__create_page_tables创建了sectionentry类型临时页表,供linux内核初始化执行环境,一个表项可以映射1MB的物理空间,mmu硬件执行虚拟地址转物理地址的过程如下:

对于所有进程kernel部分的页表都是一样的,在内核do_fork的时候,申请pgd空间后,先清0,然后将拷贝init_mm内核部分的页表项到创建进程的页表项;而用户部分每个进程有自己的页表从而达到进程地址空间独立。

3、arm 二级页表

上面建立的临时页表在paging_init中被prepare_page_table清除,然后map_lowmem建立正常工作的二级页表(create_mapping),该函数为物理内存从0到lowmem_limit建立一个一一映射的映射表,就是物理地址和虚拟地址偏差一个固定偏移量PAGE_OFFSET。而有高端内存时,则通过VMALLOC_START~VMALLOC_END线性空间进行动态映射,建立mmu硬件使用的页表,访问完后,将映射清除线性空间释放,达到访问高端内存目的。

一级页表项:4096项16K,二级页表项256项1K,每个表项指向4K 空间(一个page),mmu将虚拟空间转化为物理空间如下:

TLB:存放最近转化后的映射表,可以认为是一个页表的子集,加速查找不必每次都需要MMU进行硬件转化。

4、最新内核优化

上面是arm典型的mmu映射框图,linux在此基础上进行了重要调整(细节看源码):

第一级页表从4096个项变成2048个项,每个项从4个字节变成8个字节,还是16K大小。

第二级页表从1个256项变成2个256项,每项还是4个字节,这样总计256 *2 * 4 = 2KB,放置在page页的下半部,而上部分放置对应的linux内存管理系统使用页表,mmu硬件是不会去使用它,刚好占满4KB,不浪费空间。

Linux内核虚拟内存之页表管理相关推荐

  1. Linux 内核的文件 Cache 管理机制介绍

    1 前言 自从诞生以来,Linux 就被不断完善和普及,目前它已经成为主流通用操作系统之一,使用得非常广泛,它与 Windows.UNIX 一起占据了操作系统领域几乎所有的市场份额.特别是在高性能计算 ...

  2. linux 进程管理 ppt,Linux内核结构与进程管理.ppt

    Linux内核结构与进程管理.ppt Linux 内核结构与进程管理,Linux系统结构Linux kernel 开放源代码的linux操作系统内核,目前版本为2.6,Linux内核组成1. 进程调度 ...

  3. linux内核工程导论,Linux内核工程导论——内存管理(3)

    Linux内核工程导论--内存管理(三) 用户端内核内存参数调整 /proc/sys/vm/ (需要根据内核版本调整) 交换相关 swap_token_timeout Thisfile contain ...

  4. Linux内核学习008——进程管理(四)

    Linux内核学习007--进程管理(四) 进程家族树 Unix系统的进程之间存在一个明显的继承关系,所有的进程都是PID为1的init进程的后代.内核在系统启动的最后阶段启动init进程,然后ini ...

  5. Linux内核机制总结内存管理之页表缓存(十九)

    文章目录 1 页表缓存 1.1 TLB表项格式 1.2 TLB管理 1.3 地址空间标识符 1.4 虚拟机标识符 重要:本系列文章内容摘自<Linux内核深度解析>基于ARM64架构的Li ...

  6. epub 深入linux内核架构_深入分析Linux内核源代码6-Linux 内存管理(2)

    每天十五分钟,熟读一个技术点,水滴石穿,一切只为渴望更优秀的你! ----零声学院 6.3 内存的分配和回收 在内存初始化完成以后,内存中就常驻有内核映像(内核代码和数据).以后,随着用 户程序的执行 ...

  7. 详细讲解Linux内核源码内存管理(值得收藏)

    Linux的内存管理是一个非常复杂的过程,主要分成两个大的部分:内核的内存管理和进程虚拟内存.内核的内存管理是Linux内存管理的核心,所以我们先对内核的内存管理进行简介. 一.物理内存模型 物理内存 ...

  8. Linux内核中的内存管理(图例解析)

    一 ,内核管理内存的方式 (1)内核把物理页作为内存管理的基本单位,内存管理单元通常以页为单位进行处理,所以,从虚拟内存角度来看,页就是最小单位. 大多数32位系统支持4kb的页,64位系统支持8kb ...

  9. Linux内核机制总结内存管理之页回收(二十三)

    文章目录 1 页回收 1.1 数据结构 1.1.1 LRU链表 1.1.2 反向映射 1.2 发起回收 1.3 计算扫描的页数 1.4 收缩活动页链表 1.5 回收不活动页 1.6 页交换 1.7 回 ...

  10. Linux内核机制总结内存管理之每处理器内存分配器(十七)

    文章目录 1 每处理器内存分配器 1.1 编程接口 1.1.1 静态每处理器变量 1.1.2 动态每处理器变量 1.1.3 访问每处理器变量 1.2 技术原理 1.2.1 确定块的参数 1.2.2 创 ...

最新文章

  1. Geoserver在Linux上的安装(图文教程)
  2. k8s组件说明:kubelet 和 kube proxy
  3. 塑壳断路器用考虑启动电流么_塑壳式断路器知识
  4. new子类会先运行父类的构造函数
  5. java map 输入 查询 修改_map的查询和修改方法
  6. 远控免杀专题7 ---shellter免杀
  7. 最终章 | TensorFlow战Kaggle“手写识别达成99%准确率
  8. Python中数组,列表,元组的区别、定义、功能
  9. 2018.09.07阿里巴巴笔试题
  10. android:Read-only file system解决
  11. 推荐一款非常好用的文本替换工具“Replace Pioneer”
  12. java文件传输加密_java程序对于文件的加密和解密
  13. 好玩的C语言大全,好玩的c语言程序!
  14. 史上最全!!收藏了!3D建模软件大全
  15. wireshark抓包并复原图像
  16. file_get_contents() 报错failed to open stream: HTTP request failed! HTTP/1.1 505 HTTP Version Not Supp
  17. Longhorn云原生文件存储
  18. php 领红包程序,用PHP实现的抢红包小程序
  19. 第一周:和平之城中的鸟类识别(案例研究)
  20. 【1.9w字】彻底搞懂HTTP知识的面试题,建议精读收藏

热门文章

  1. (1.2)mysql 索引概念
  2. 关于STM32定时器使用的一个注意事项(以此为前车之鉴,重要!)
  3. datacolumn 表达式 除数为0
  4. vulkan android 三星,vulkan android
  5. php foreach 多出一个_PHP如何实现统计数据合并
  6. C#中取得汉语拼音首字母
  7. 20171001~08总结
  8. 李瑾博士:信誉的建立是否“不计成本”?
  9. 8253/8255/8259相关知识
  10. 用phpQuery像jquery一样解析html代码