- 28
- 0
- 约3.54千字
- 约 10页
- 2018-08-17 发布于江苏
- 举报
进程虚拟地址空间(0~3G-1)3
进程虚拟地址空间(0~3G-1) 进程地址空间 vm_flags的取值: VM_READ: 此虚拟内存区域可读 VM_WRITE: 此虚拟内存区域可写 VM_EXEC: 此虚拟内存区域可执行 VM_SHARED: 此虚拟内存区域可共享 VM_IO: 此虚拟内存区域映射设备I/O空间 建立vma和物理地址的映射的工作由remap_pfn_range来完成,原型如下: int remap_pfn_range(struct vm_area_struct *vma, unsigned long virt_addr, unsigned long pfn, unsigned long size, pgprot_t prot); vma 需要建立映射的VMA virt_addr 需要建立映射的VMA的起始地址 pfn 页帧号, 对应虚拟地址应当被映射的物理地址. 这个页帧号简单地是物理地 址右移 PAGE_SHIFT 位 size 需要建立映射的VMA的大小, 以字节. prot 使用在 vma-vm_page_prot 中找到的值. 1.每个进程只有一个mm_struct结构,在每个进程的task_struct结构中,有一个指向该进程的结构。可以说,mm_struct结构是对整个用户空间的描述 2.一个进程的虚拟空间中可能有多个虚拟区间(参见下面对vm_area_struct描述),对这些虚拟区间的组织方式有两种,当虚拟区较少时采用单链表,由mmap指针指向这个链表,当虚拟区间多时采用“红黑树(red_black tree)”结构,由mm_rb指向这颗树 3.因为程序中用到的地址常常具有局部性,因此,最近一次用到的虚拟区间很可能下一次还要用到,因此,把最近用到的虚拟区间结构应当放入高速缓存,这个虚拟区间就由mmap_cache指向。 4.指针pgt指向该进程的页目录(每个进程都有自己的页目录,注意同内核页目录的区别),当调度程序调度一个程序运行时,就将这个地址转成物理地址,并写入控制寄存器(CR3)。 5.虽然每个进程只有一个虚拟地址空间,但这个地址空间可以被别的进程来共享,如,子进程共享父进程的地址空间(也即共享mm_struct结构)。所以,用mm_user和mm_count进行计数。类型atomic_t实际上就是整数,但对这种整数的操作必须是“原子”的。 6.系统中所有的mm_struct结构体都通过自身的mmlist域连接在一个双向链表中,该链表的首元素是init_mm内存描述符,它代表init进程的地址空间 struct mm_struct { struct vm_area_struct * mmap; /* 指向虚拟区域(VMA)链表 */ rb_root_t mm_rb; /*指向red_black树*/ struct vm_area_struct * mmap_cache; /* 指向最近找到的虚拟区间*/ pgd_t * pgd; /*指向进程的页目录*/ atomic_t mm_users; /* 用户空间中的有多少用户*/ atomic_t mm_count; /* 对struct mm_struct有多少引用*/ int map_count; /* 虚拟区间的个数*/ struct list_head mmlist; /*所有活动(active)mm的链表 */ 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; }; 内核使用mm_struct来描述一个进程的虚拟地址空间 struct vm_area_struct: 用来描述一个虚拟内存区域
原创力文档

文档评论(0)