进程地址空间
Linux采用虚拟化内存技术,系统中所有的进程之间以虚拟方式共享内存。通过虚拟化技术一个进程看起来可以拥有整个物理内存,拥有比物理内存大的地址空间,
1. 地址空间
进程地址空间指进程可寻址的虚拟内存组成的虚拟地址空间。每个进程都有一个32位或64位的Flat 地址空间,flat指地址空间范围是一个独立连续的空间。
内存地址是一个给定的值,它要在地址空间范围内,一个进程的可寻址空间为4G(32位机器),但是进程只能访问有效的内存区域内的内存地址,一个进程的地址空间被分成了各种内存区域,如代码段、数据段、堆栈段等。
Region-based memory management
2. 内存描述符
内核使用内存描述符表示进程的地址空间,由结构体mm_struct表示,定义在linux/mm_types.h
|
|
进程描述符task_struct中的mm域存放了该进程的内存描述符,利用current->mm我们可以得到当前进程的内存描述符。fork()函数利用copy_mm()复制父进程的内存描述符,将current->mm域赋予子进程,子进程的mm_struct通过allocate_mm()分配;clone()函数设置CLONE_VM共享地址空间,此时不需要调用allocate_mm()。
内核线程的mm域为空,因为它没有用户上下文。
3. 虚拟内存区域
vm_area_struct结构体描述了内存区域,定义在linux/mm_types.h,它描述了指定地址空间内连续区间上的一个独立内存范围。
|
|
- VMA标志
VMA包含在vm_flags内,表明了一个内存区域的行为和信息,反映的是内核处理页面的行为准则,定义在linux/mm.h。 - VMA操作
vm_area_struct中的vm_ops指针指向了与指定内存区域相关的操作函数表,内核使用这些方法操作VMA。这些操作函数由vm_operations_struct表示,定义在linux/mm.h。
可以使用/proc文件系统和pmap工具查看给定进程的内存空间和其包含的内存区域。
4. mmap和do_mmap:创建地址空间
内核使用do_mmap()函数创建一个新的线性地址空间,如果do_mmap()的参数无效,它返回一个负值,否则它会在虚拟内存中分配一个合适的新内存区域,如果可能,会将新区域与邻近区域合并。
如果要删除地址空间,相应的函数为mummap()和do_mummap()。
5. 页表
应用程序操作的是映射在物理内存之上的虚拟内存,处理器直接操作的是物理内存。页表就是组织虚拟地址转换为物理地址的结构。
为了加速页表搜索,实现了translate lookaside buffer, TLB,TLB缓存了虚拟地址到物理地址的映射。