首页 > 代码库 > [Linux]进程(十)——进程地址空间

[Linux]进程(十)——进程地址空间

1,进程的虚拟内存:

背景知识
a.out分段以及运行时候内存的结构点击打开链接

linux进程地址空间

linux进程地址空间

\

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. struct mm_struct {   
  2.         struct vm_area_struct  *mmap;               /* list of memory areas */  
  3.         struct rb_root         mm_rb;               /* red-black tree of VMAs */  
  4.         。。。。。。。。。  
  5. }  

mmap和mm_rb两个不同的数据结构描述的对象都是相同的,描述的是该地址空间全部的内存区域(struct vm_area_struct),但是前者以链表形式,后者以红黑树形式,链表优点是可以高效遍历所有元素,而红黑树更适合搜索指定的元素。mm_struct结构体双向链表结构体的首元素是init_mm内存描述符,它代表init进程的地址空间.进程描述符task_struct中有一个mm域,这里边存放的就是该进程使用的内存描述符,通过current->mm便可以指向当前进程的内存描述符

内核线程没有地址空间,所以内核线程中task_struct中该成员为空。在内核调度的时候,如果发现mm_struct区域为空,则会保留前一个进程的地址空间

内存区域由vm_area_struct结构体表示,描述指定地址空间内连续空间上一个独立的内存范围。内核将每个内存区域都作为一个单独的内存对象管理,每个内存对象有一致性属性,比如访问权限等

可以通过/proc/<pid>/maps的输出来查看各个进程地址空间的全部区域,每行的格式输入

开始--结束 访问权限偏移主设备号:次设备号i节点文件

mmap()和do_mmap()函数
内核使用do_mmap()函数来创建一个新的地址空间,如果创建的地址空间和一个已经存在的地址空间相邻并且属性都相同,那么两个区间会合并为一个。do_mmap()函数会将一个地址空间加入到进程的地址空间

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. struct mm_struct {   
  2.         pgd_t                  *pgd;                /* page global directory */  
  3.         。。。。。。。。  
  4.     }  

页表是用来实现虚拟地址到物理地址的转变的,每个进程的内存描述符都有自己的页表,在mm_struct结构体的pgd成员指向。

[Linux]进程(十)——进程地址空间