linux2.6进程地址空间
内核除了要管理好本身的内存外,还必须管理进程的地址空间-也就是系统中每个用户空间进程所看的的内存,对于每一个进程来讲,他们好像都可以访问整个系统的所有物理内存。
进程地址空间由每个进程中的线性地址区组成,而且更为重要的是内核允许进程使用该空间中的地址,每个进程都有一个32位或者64位的flat地址空间,空间的具体大小取决于具体的体系结构。通常情况下,每个进程都有唯一的地址空间,而且进程中的地址空间之间彼此互不相干,但是进程之间也可以选择共享地址空间,我们称这样的进程为线程,
内存地址是一个给定的值,它要在地址空间范围之类,这个值表示的是一个特定的字节。在地址空间中,我们更加关心的是进程有访问权限的虚拟内存地址区间,memory areas 通过内核,进程可以给自己的地址空间动态的添加和减少内存区域、
进程只能访问有效范围内的内存地址,另外每个地址范围也具有特定的访问属性,如只读或不可执行等属性,如果一个进程范围了不在有效范围内的地址,或以不正确的方式访问了有效地址,那么内核会终止该进程,并返回段错误信息、
内存区域可以包含各种内存对象,比如:
可执行文件代码的内存映射,成为代码段
可执行文件的已初始化的全局变量的内存映像,成为数据段
包含未初始化全局变量,也就是bss段零页的内存映射。
用于进程用户空间栈(不要和进程内核栈混淆,进程的内核栈独立存在并有内核维护)的玲也的内存映射。
每一个诸如c库或者动态链接程序等共享库的代码段。数据段。和bss段也会被载入进程的地址空间,
任何内存映射文件。
任何共享内存段。
任何匿名的内存区域,比如由malloc分配的内存。
进程地址空间中的任何一个有效地址都只能位于唯一的一个区域(内存区域不能相互覆盖)。可以看到,在执行的进程中,每个不同的内存片段都对应于一个独立的内存区域:栈,对象代码,全局变量,被映射的文件等等。
一些基本的数据结构:
内存区域:内存区域由vm_area_struct结构体描述,定义在文件《linux/mm.h》中,内存区域在内核中也被称为虚拟内存区域或者VMA,
vm_area_struct结构体描述了指定地址空间内连续区间上的一个独立内存范围,内核将每个内存区域作为一个单独的内存对象管理,每个内存区域内拥有一支的属性,比如访问权限等,另外,相应的操作也都一致。
三个操作内存区域的函数:
find_vma() 定义在<mm/mmap.c>中,他在指定的地址空间寻找第一个包含addr或首地址大于addr的内存区域,如果没有发现该区域,则返回为空:
struct vm_area _struct *find_vma(struct mm_struct *mm,unsigned long addr )
find_vma_prev(),他返回第一个小于addr的vma
struct vm_area_struct *find_vma_prev(struct mm_struct *mm,unsigned long addr,struct vm_area_struct **pprev)
find_vma_intersection(),函数返回第一个和指定地址区间相交的vma,
static inline struct vm_area_struct *find_vma_intersection(struct mm_struct *mm,unsigned long start_addr,unsigned end_addr)
内存描述符:内核中使用内存描述符结构体来表示进程的地址空间,该结构体包含了和进程地址空间相关的全部信息,内存描述符由mm_struct结构体表示:定义在文件<linux/schde.h>中
下面是内存描述符的结构和
struct mm_struct{
struct vm_area_struct *mmap;
struct rb_root mm_rb;
struct vm_area-struct *mmap_cache;
unsigned long free _area_cache;
pgd_t *pgd;
atomic_t mm_user;
atomic_t mm_count;
int map_count;
struct rw_semaphore mmap_sem;
spinlock_t page_table_lock;
struct list_head mmlist;
unsigned long start_code;
unsigned long end_code;
unsigned long start_data;
unsigned long end_data;
unsigned long start_brk;
unsigned long brk;
unsigned long start_stack;
unsigned long arg_start;
unsiged long arg_end;
unsiged long env_start;
unsigned long env_end;
unsigned long rss;
unsigned long total_vm;
unsigned long locked_vm;
unsigned long def_flags;
unsigned long cpu_vm_mask;
unsigned long swap_address;
unsigned dumpable:1;
int used_hugetlb
mm_context_t context;
int core_waiters;
struct completion *core_startup_done;
struct completion core_done;
rwlock_t ioctx_list_lock;
struct kioctx *ioctx_list
struct kioctx default_kioctx;
};
}
参考文献:linux内核设计与实现