mmap指向一个,vm_area_struct的结构,每个vm_area_struct都指向了虚拟地址空间的一个区域。
vm_flags:这块内存是进程私有的,还是与其他进程共享的;
当cpu访问某个虚拟地址时,如果该地址在页表中不存在,则会处罚缺页异常。有三种异常情况:
1. mmu遍历所有的vm_area_struct,发现地址不在所有的空间内,则内存时非法内存,还没有分配使用,系统报段错误;
2. mmu便利所有的vm_area_struct,发现属于text段,则返回该地址给内核,内核读该vm_area_struct的flag,发现时text段,只读的,则报告段错误;
删除当前地址空间所有的vm_area_struct和页表;然后在当前地址空间创建新的vm_area_struct和页表,bss段和stack段映射到匿名文件;data段和text段使用可执行文件中的内容;创建一个共享空间,用来放置空间库。
注意,这些步骤,只是映射,只是修改了当前虚拟地址空间的内核数据结构,并没有做任何的内存拷贝动作。
当cpu开始执行第一条指令的时候,则会陷入异常。走一套完整的异常流程,把第一个页拷贝到内存后,才开始执行。
因此,虚拟内存机制和操作系统是紧密相连的,互相依赖的,操作系统执行新进程是,不需要操作系统自己去将一些内容拷贝到内存,而是完成空间映射,之后直接利用虚拟内存机制,完成各个段的拷贝。
ps:bss段stack段heap段,在execve刚执行的时候,都会被置位zero;但随着程序执行,这些内存不一定位zero。
如果libc.so中,有静态局部变量,这些变量应该在private copy-on-write区域内。