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建立起映射