进程虚拟地址空间
mm_struct
在进程的task_struct结构中包含一个指向mm_struct
结构的指针,mm_strcut用来描述一个进程的虚拟地址空间。
进程的虚拟空间中可能有多个虚拟区块,对这些虚拟区块的组织方式有两种,当虚拟区较少时采用单链表,由mmap指针指向这个链表,
当虚拟区块多时采用“红黑树(red_black tree)”结构。
虚拟地址空间分布
主要包括栈,映射空间,堆,bss,数据段,代码段。
[mmap]是一个链表,每个节点指向进程的一个虚拟内存区块(VMA)。
[start_code, end_code]表示代码段的地址空间范围。
[start_data, end_start]表示数据段的地址空间范围。
[start_brk, brk]分别表示heap段的起始空间和当前的heap指针(brk)。
[start_stack, end_stack]表示stack段的地址空间范围
[mmap_base]表示memory mapping的起始地址。
kernel linux2.6.18
struct mm_struct {
......
struct vm_area_struct * mmap; /* list of VMAs */
unsigned long mmap_base; /* base of mmap area */
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
......
};
VMA—虚拟内存区块
每一个VMA是虚拟地址都是连续分布不会重叠,是虚拟地址空间的一部分。
进程的虚拟内存空间中可以有多个虚拟内存区块(比如共享库,数据段,代码段,stack, heap等)。见图mm_struct_2
vm_area_struct
vm_area_struct用来描述WMA,包括它的起始地址,结束地址,访问权限和行为等。
mmap是一个链表,每个节点指向进程的一个虚拟内存区块(VMA)。
struct vm_area_struct * mmap; /* list of VMAs */
每个vm_area_struct存储着一个虚拟地址区块
struct vm_area_struct {
struct mm_struct * vm_mm; /* 虚拟地址所在的地址空间 */
unsigned long vm_start; /* 在vm_mm中的起始地址 */
unsigned long vm_end; /* 在vm_mm中的结束地址 */
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct *vm_next; /* 指向下一个 vm_area_struct */
pgprot_t vm_page_prot; /* Access permissions of this VMA. */
unsigned long vm_flags; /* Flags, listed below. */
struct vm_operations_struct * vm_ops;
.....
}
vm_operations_struct
vm_area_struct中的vm_operations_struct结构描述操作虚拟内存区块的函数集。
比如,open、close 分别用于虚拟区块的打开、关闭,
而nopage 用于当虚存页面不在物理内存而引起的“缺页异常”时所应该调用的函数,
当 Linux 处理这一缺页异常时(请页机制),就可以为新的虚拟内存区分配实际的物理内存。
struct vm_operations_struct {
void (*open)(struct vm_area_struct * area);
void (*close)(struct vm_area_struct * area);
struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type);
......
};