32 位的平台上,线性地址空间为固定的 4GB,并且由于采用了保护机制,Linux内核将这 4GB 分为两部分,线性地址较高的 1GB(0xC0000000 到 0xFFFFFFFF )为共享的内核空间;而较低的 3GB 为每个进程的用户空间。由于每个进程都不能直接访问内核空间,而是通过系统调用间接进入内核,因此所有的进程都共享内核空间。而每个进程都拥有各自的用户空间,各个进程之间不能互相访问彼此的用户空间。
一个进程的用户地址空间主要由两个数据结构来描述。一个是 mm_struct 结构,它对进程的整个用户空间进行描述,简称内存描述符;另一个是 vm_area_struct 结构,它对用户空间中各个区间( 代码区、数据区等 )进行描述。
进程用户空间的描述
内存描述符
每个进程只有一个 mm_struct
结构,在每个进程的 task_struct
结构中,有一个指向该结构的指针。
struct mm_struct {
struct vm_area_struct *mmap; /* list of VMAs */
struct rb_root mm_rb;
pgd_t * pgd; //页目录基址
atomic_t mm_users; //记录正在使用该地址空间的进程数目
atomic_t mm_count; //记录mm_struct 结构体被引用的次数。
//如果当前地址空间只被两个进程共享,那么该值为1,mm_users为2
int map_count; //虚拟内存区的个数
spinlock_t page_table_lock; /* Protects page tables and some counters */
struct rw_semap