linux内核源码——内存管理:段页式内存及swap

os的内存管理大概可以分成两块:1.段页式管理(虚存)2.swap in 和 swap out

段页式管理

段式管理的图像:运行时重定位

多级页表的管理图像

 块表加速

 

 

用户(程序员)希望用段,物理内存希望用页来进行管理

所以引入虚存的概念:

  段面向用户,用户眼里的地址是0-4G,页面向物理内存,存储时,将段切割成一页一页存在物理内存里,

  同时,pcb内有虚拟页->物理页的映射表,物理页寻址时再按照多级页表那样寻址即可

 

 以系统调用fork为例来分析段页式内存管理的过程:

 假设每个进程都在虚存里被分配到64M的内存,且互不重叠,通过简化,每个代码段,数据段都是一个段

 现在已经有了进程0和进程1,新建的是进程1的子进程2

 在fork调用的copy_process函数里调用了一个函数copy_mem

 nr就是当前进程个数,这里先把进程2的虚存的基地址给确定下来

接下去是函数copy_page_table,将父进程的页表复制给子进程( 子进程复制父进程内存资源 )

 接下去分析函数具体实现

第一句话:from_dir指向父进程虚存页目录

第二句话:to_dir指向子进程虚存页目录

第三句话:size为父进程拥有的虚存页目录条数

进入循环:遍历父进程的所有页表,在子进程新建出来

  枚举每条页目录,子进程都通过每条页目录新建一个页表

  from_page_table指向父进程的一个页表 

  to_page_table指向子进程的一个新建页表

 这句话修改子进程该页表的权限:注意此时 *to_dir & 0xFFFFF000 才和 to_page_table所指向的的那一页相同,*to_dir的前20位是页目录+页编号,后面几位已经是对应页的权限了

然后要将from_page_table指向的所有页都复制给to_page_table

 循环:

  第一句:this_page指向from_page_table存的那一页

  第二,三,四句:将该页权限改为只读,同时父子进程都更新这个只读页

    第四,五句:将this_page对应的页号++即可,表示多了个指向这页的进程

 

如果子进程要修改某页的内容,因为其实只读的,所以子进程直接复制该页内容到新的一页,在新的一页上进行修改

swap in

由14号缺页中断引入

page.s中处理缺页中断edx存了缺少的那页虚存

 address就是缺少的那页虚存地址,page是被加载进来的那页物理地址

把虚存页address和物理页page对应起来

 page_table最后指向address虚页页表,最后一句把address的在中间十位(即页表)抠出来,和page建立起映射

原文地址:https://www.cnblogs.com/zsben991126/p/12069937.html