进程地址空间
进程地址空间就是允许进程使用的全部线性地址,用mm_struct内存描述符表示
- 内核线程使用前一个进程的内存描述符,mm字段为NULL,active_mm为前一个进程的active_mm;普通进程的mm和active_mm相同
- 几个重要字段:
- pgd:指向页目录
- 堆的起始和最后地址
- 用户态堆栈起始地址
- 代码段起始和最后地址
- 数据的首尾地址
- 段错误:
- 访问了不在有效范围内的内存区域
- 以不正确的方式访问了有效地址
- Linux不区别对待线程和进程,线程对于Linux来说仅仅是共享特定资源的进程,比如地址空间mm_struct
线性区(虚存区VMA)
vm_area_struct线性区描述符表示一个线性地址区间,进程地址空间里有多个线性区
- 用链表和红黑树组织
- 链表,在mm_struct中用mmap字段表示,通常在遍历整个线性区集合时来使用
- 红黑树,在mm_struct中用mm_rb表示,用来搜索含有指定地址的线性区
- 每个线性区都由一组连续的页组成,相关权限都会复制到对应的页表项
- 每个VMA对其相关的mm_struct都是唯一的,即共享mm_struct就共享里面的所有VMA,否则尽管两个VMA指向同一个东西,也不能只用一个VMA
- 和file对象有关联
mmap
mmap底层调用do_mmap,创建一个新的线性地址区间。指定参数可以进行内存映射
内存映射
一个虚存区可以和磁盘文件的一部分或者块设备文件相关联,对线性区中页内某个字节的的访问可以转换为对文件的中相应字节的操作
- 共享型:在线性区页上的写操作回修改磁盘上的文件,同时也对所有映射同一文件的进程可见
- 页通常都在页高速缓存
- 私有型:这种映射只为了读操作,效率更高;当进行写操作时内核会停止映射
- 页没有被写都包含在页高速缓存
- 被写后,利用写时复制机制,但使用的是普通页,不再是磁盘上的有效数据
- 内存映射创建之后并不会把页框分配给它,而是会推迟到缺页的时候
- 和read、write的区别
- 映射的话,进程的地址空间的虚存区和页高速缓存直接进行绑定
- read和write的话,要从页高速缓存拷贝到进程的地址空间的虚存区
缺页异常处理程序
- 缺页的两种情况:
- 编程错误
- 引用属于进程地址空间但还尚未分配物理页框的页
- 总体方案