linux 内核 - 进程地址空间的数据结构

1. 在linux内核中, task_struct 表示一个进程的实例

cpp 复制代码
struct task_struct{
 [...]
 struct mm_struct *mm, *active_mm;
 [...]
}

2. mm_struct 表示进程的内存映射

cpp 复制代码
struct mm_struct {
 struct vm_area_struct *mmap;
 unsigned long mmap_base;
 unsigned long task_size;
 unsigned long highest_vm_end;
 pgd_t * pgd;
 atomic_t mm_users;
 atomic_t mm_count;
 atomic_long_t nr_ptes;
#if CONFIG_PGTABLE_LEVELS > 2
 atomic_long_t nr_pmds;
#endif
 int map_count;
 spinlock_t page_table_lock;
 unsigned long total_vm;
 unsigned long locked_vm;
 unsigned long pinned_vm;
 unsigned long data_vm;
 unsigned long exec_vm;
 unsigned long stack_vm;
 unsigned long start_code, end_code, start_data, end_data;
 unsigned long start_brk, brk, start_stack;
 unsigned long arg_start, arg_end, env_start, env_end;
 /* ref to file /proc/<pid>/exe symlink points to */
 struct file __rcu *exe_file;
};

其中 pdg 表示进程的一级页表,

start_stack 表示用户栈起始地址,

mmap_base表示映射区域的起始地址(动态库.so, mmap系统调用映射的文件),

start_brk 表示堆起始地址,

brk 表示堆结束的地址,

start_data 表示数据段起始地址,

end_data 表示数据段结束地址,

end_code 表示代码段结束地址

3. task_struct 和 mm_struct 的关系如图:

4. 虚拟内存区域:

如前所述,mm_struct 里面有一个 mmap 成员,它表示进程内存映射的一个区域(VMA),VMA(Virtual Memory Area)即虚拟内存区域。 在Linux中,每个正在运行的进程都会有多个VMA,如代码段,数据段,堆栈段,文件映射区域等。

cpp 复制代码
struct vm_area_struct {
 unsigned long vm_start; 
 unsigned long vm_end;
 struct vm_area_struct *vm_next, *vm_prev;
 struct mm_struct *vm_mm;
 pgprot_t vm_page_prot;
 unsigned long vm_flags;
 unsigned long vm_pgoff;
 struct file * vm_file;
 [...]
}

5. task_struct, mm_struct, vm_area_struct 关系图