Linux VM虚拟存储器系统(读书笔记)
Linux虚拟存储器系统(读书笔记)
之前学了一段时间JOS的Env,对Linux的进程来说,每个进程有个进程控制块PCB。进程的消亡,就是Linux通过控制PCB进行的。
内核虚拟存储器包含内核中的代码和数据结构。内核虚拟存储器的某些区域被映射到所有进程共享的物理页面。例如,每个进程共享内核的代码和全局数据结构。下面这个图和JOS很像。高位属于kernel地址,低位留给user application。
内核为系统中的每个进程维护一个单独的任务结构(源代码中的task_struct)。任务结构中的元素包含或者指向内核运行该进程所需要的所有信息(例如,PID,指向用户栈的指针、可执行的目标文件的名字以及程序计数器)。
task_struct中的一个条目指向mm_struct,它描述了虚拟存储器中的当前状态。其中pgd指向第一级页表(页全局目录)的基址,而mmap指向一个vm_area_struct(区域结构)的链表,其中每个vm_area_structs都描述了当前虚拟地址空间的一个区域(area)。当内核运行这个进程时,它就将pgd存放在CR3控制寄存器中。
####在JOS中使用lcr3(physics address)来记录地址。
一个具体区域结构包含下面的字段:
vm_start:指向这个区域的起始处。 vm_end:指向这个区域的结束处。 vm_prot:描述这个区域的内包含的所有页的读写许可权限。 vm_flags:描述这个区域内页面是与其他进程共享的,还是这个进程私有的(还描述了其他一些信息)。 vm_next:指向链表中下一个区域结构。 共享页面
共享对象的关键点在于即使对象被映射到了多个共享区域,物理存储器也只需要存放共享对象的一个拷贝。
#####一个共享对象(注意,物理页面不一定是连续的。)
#####私有对象是使用一种叫做写时拷贝(copy-on-write)的巧妙技术被映射到虚拟存储器中的。对于每个映射私有对象的进程,相应私有区域的页表条目都被标记为只读,并且区域结构被标记为私有的写时拷贝。
其中有些函数比较重要.
- mmap函数要求内核创建一个新的虚拟存储器区域是,最好是从地址start开始的一个区域,并将文件描述符fd指定的对象的一个连续的片(chunk)映射到这个新区域。连续的对象片大小为length字节,从距文件开始处偏移量为offset字节的地方开始。start地址仅仅是一个暗示,通常被定义为NULL。
#include #include<sys/mman.h> void *mmap(void *start,size_t length,int prot,int flags,int fd,off_t offset) ; //返回:若成功时则为指向映射区域的指针,若出错则为MAP_FAILED(-1) </code></pre> ######我们可以使用这个函数将磁盘文件拷贝到stdout。首先我们要明确stdout 在write中fd=1 ,stderr fd =2