1. 内核初始化:

* 内核建立好内核页目录页表数据库,假设物理内存大小为len,则建立了[3G--3G+len]::[0--len]这样的虚地址vaddr和物理地址paddr的线性对应关系;
    * 内核建立一个page数组,page数组和物理页面系列完全是线性对应,page用来管理该物理页面状态,每个物理页面的虚地址保存在page->virtual中;
    * 内核建立好一个free_list,将没有使用的物理页面对应的page放入其中,已经使用的就不用放入了;

2. 内核模块申请内存vaddr = get_free_pages(mask,order):

* 内存管理模块从free_list找到一个page,将page->virtual作为返回值,该返回值就是对应物理页面的虚地址;
    * 将page从free_list中脱离;
    * 模块使用该虚拟地址操作对应的物理内存;

3. 内核模块使用vaddr,例如执行指令mov(eax, vaddr):

* CPU获得vaddr这个虚地址,利用建立好的页目录页表数据库,找到其对应的物理内存地址;
    * 将eax的内容写入vaddr对应的物理内存地址内;

4. 内核模块释放内存free_pages(vaddr,order):

* 依据vaddr找到对应的page;
    * 将该page加入到free_list中;

5. 用户进程申请内存vaddr = malloc(size):

* 内存管理模块从用户进程内存空间(0--3G)中找到一块还没使用的空间vm_area_struct(start--end);
    * 随后将其插入到task->mm->mmap链表中;

6. 用户进程写入vaddr(0-3G),例如执行指令mov(eax, vaddr):

* CPU获得vaddr这个虚地址,该虚地址应该已经由glibc库设置好了,一定在3G一下的某个区域,根据CR3寄存器指向的current->pgd查当前进程的页目录页表数据库,发现该vaddr对应的页目录表项为0,故产生异常;
    * 在异常处理中,发现该vaddr对应的vm_area_struct已经存在,为vaddr对应的页目录表项分配一个页表;
    * 随后从free_list找到一个page,将该page对应的物理页面物理首地址赋给vaddr对应的页表表项,很明显,此时的vaddr和paddr不是线性对应关系了;
    * 将page从free_list中脱离;
    * 异常处理返回;
    * CPU重新执行刚刚发生异常的指令mov(eax, vaddr);
    * CPU获得vaddr这个虚地址,根据CR3寄存器指向的current->pgd,利用建立好的页目录页表数据库,找到其对应的物理内存地址;
    * 将eax的内容写入vaddr对应的物理内存地址内;

7. 用户进程释放内存vaddr,free(vaddr):

* 找到该vaddr所在的vm_area_struct;
    * 找到vm_area_struct:start--end对应的所有页目录页表项,清空对应的所有页表项;
    * 释放这些页表项指向物理页面所对应的page,并将这些page加入到free_list队列中;
    * 有必要还会清空一些页目录表项,并释放这些页目录表项指向的页表;
    * 从task->mm->mmap链中删除该vm_area_struct并释放掉;

综合说明:

* 可用物理内存就是free_list中各page对应的物理内存;
    * 页目录页表数据库的主要目的是为CPU访问物理内存时转换vaddr-->paddr使用,分配以及释放内存时不会用到,但是需要内核内存管理系统在合适时机为CPU建立好该库;
    * 对于用户进程在6中获得的物理页面,有两个页表项对应,一个就是内核页目录页表数据库的某个pte[i ],一个就是当前进程内核页目录页表数据库的某个 pte[j],但是只有一个page和其对应。如果此时调度到其他进程,其他进程申请并访问某个内存,则不会涉及到该物理页面,因为其分配时首先要从 free_list中找一个page,而该物理页面对应的page已经从free_list中脱离出来了,因此不存在该物理页面被其他进程改写操作的情况。内核中通过get_free_pages等方式获取内存时,也不会涉及到该物理页面,原理同前所述。

---------------------------------------------------------------------------------------------------------------------------------------------------

下面是init_mm的初始化,init_mm定义在/arch/arm/kernel/init_task.c: 
struct mm_struct init_mm = INIT_MM(init_mm);

从本回开始的相当一部分内容是和内存管理相关的,凭心而论,操作系统的 
内存管理是很复杂的,牵扯到处理器的硬件细节和软件算法, 
限于篇幅所限制,请大家先仔细读一读arm mmu的部分, 
中文参考资料:linux内核源代码情景对话, 
linux2.4.18原代码分析。

init_mm.start_code = (unsigned long) &_text; 
内核代码段开始 
init_mm.end_code = (unsigned long) &_etext; 
内核代码段结束 
init_mm.end_data = (unsigned long) &_edata; 
内核数据段开始 
init_mm.brk = (unsigned long) &_end; 
内核数据段结束

每一个任务都有一个mm_struct结构管理任务内存空间,init_mm 
是内核的mm_struct,其中设置成员变量* mmap指向自己, 
意味着内核只有一个内存管理结构,设置* pgd=swapper_pg_dir, 
swapper_pg_dir是内核的页目录,在arm体系结构有16k, 
所以init_mm定义了整个kernel的内存空间,下面我们会碰到内核 
线程,所有的内核线程都使用内核空间,拥有和内核同样的访问 
权限。

Linux内存:内存管理的实质 (转CU上frank_seng 的总结,感谢frank_seng )相关推荐

  1. Spark中内存模型管理

    一.概述 Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文 ...

  2. Spark 内存管理 spark.executor.memory /spark.memory.fraction/spark.memory.offHeap.size【堆外内存/内存管理】 钨丝计划

    spark1.6及之后: 堆内内存: spark.executor.memory 包含 spark.memory.fraction: spark.memory.fraction 包含 spark.me ...

  3. linux按进程分配物理内存,linux下内存管理学习心得(一)

    最近在学习内存管理的时候,发现对linux下的所谓内存如何管理如何分配都不熟悉,通过最近的查阅资料可总结如下,如有不妥之处欢迎大家批评与指正. 总的的来说linux的内存管理其实主要难理解的是以下几个 ...

  4. 剖析linux的内存管理与分配

    文章目录 伙伴算法 **1.伙伴算法原理** **2.物理页的分配** **3. 物理页的释放 ** **总结** Slab分配机制 **1.Slab如何对内存进行管理?** **2.Slab中如何实 ...

  5. Linux堆内存管理深入分析(上)

    Linux堆内存管理深入分析 (上半部) 作者:走位@阿里聚安全   0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏 ...

  6. 转:浅谈Linux的内存管理机制

    一 物理内存和虚拟内存          我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概 ...

  7. linux kernel 内存管理 感想总结(未完待续)

    理解内存管理需要知道的概念 什么是 MMU , MMU的作用? 什么是页帧,页,页表,区,他们之间的关系又是怎样的 ? 什么是页的高速缓存 地址线, 寻址, cpu 和 各级高速缓存的关系, cpu ...

  8. 浅谈Linux的内存管理机制

    一 物理内存和虚拟内存          我们知道,直接从物理内存读写数据要比从硬盘读写数据要快的多,因此,我们希望所有数据的读取和写入都在内存完成,而内存是有限的,这样就引出了物理内存与虚拟内存的概 ...

  9. Linux系统内存管理之伙伴系统分析 - 旭东的博客 - 博客园

    Linux系统内存管理之伙伴系统分析 - 旭东的博客 - 博客园 Linux系统内存管理之伙伴系统分析 今天去面试,一位面试官提到了内存管理的伙伴系统,当时就懵了,因为根本就没有听说过.晚上回来在实验 ...

  10. Linux堆内存管理深入分析

    0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞利用两种.国内关于栈溢出的资料相对较多,这里就不累述了,但是关于堆溢 ...

最新文章

  1. java2实用教程--第二章基本数据类型与数组
  2. JS 中迭代数组的三种方法
  3. 5G NR Operating bands and channel bandwidth
  4. LinkedIn已将可自定义的索引引擎IndexTank开源
  5. python画两条曲线_查找在matplotlib中绘制的两条曲线之间的区域(在区域之间填充)...
  6. (9)How to take a picture of a black hole
  7. VS IIS Express 支持局域网访问
  8. Win32 Thread Information Block
  9. 拓端tecdat|R语言使用灰色关联分析(Grey Relation Analysis,GRA)中国经济社会发展指标
  10. c语言yuv图片cb,YUV格式图像基础
  11. 科来kelai工具的安装与使用-改包回放包工具
  12. 移动硬盘在计算机中不显示数据能恢复,移动硬盘无法访问提示'此卷不包含可识别的文件系统'怎么办?...
  13. OpenStreetMap开放街道图(OSM)
  14. arcgis10之将一个shp属性数据通过某一字段将要素属性关联至另一shp文件中
  15. oppo reno4se和vivos7 哪个好
  16. HTML表单、表格制作个人简历
  17. eslint : 无法加载文件 C:\Users\user\AppData\Roaming\npm\eslint.ps1
  18. Elasticsearch: Query string与Simple query string
  19. 有限元方法求解二维拉普拉斯方程C++实现
  20. 【OpenCV学习笔记】之图像轮廓特征与图像的矩

热门文章

  1. 产品经理的素质能力模型
  2. VMware虚拟机 centos8 解决全屏问题
  3. HDL4SE:软件工程师学习Verilog语言(七)
  4. Internet选项里没有常规选项卡
  5. 金蝶K3案例教程存货核算后台配置
  6. 如何在Linux中克隆一个分区或者硬盘驱动器
  7. Stata:如何生成天马行空的空间权重矩阵?
  8. 刚才对着电脑发呆了很久,天马行空想起在B站看到的两句话,感悟颇多,活出一个真正有灵魂的人吧。分享给大家。
  9. 移动硬盘参数错误要怎么办啊
  10. linux以兆显示文件大小,linux – 以兆字节显示文件夹使用情况的正确方法