每个物理页的结构体 page 的 mapping 指向一个内存区域 vma (其最低的两位用来标识内存区域是匿名区 anon_vma 还是文件区 address_space )
匿名区
-
每个进程有一个匿名区 anon_vma,page 的 index 标识这个页在区内的页号
-
不同进程的 anon_vma 之间组织成树,anon_vma->parent 指向父节点,anon_vma->root 指向根节点。
-
一个进程的虚拟内存区按页号范围组织成一颗红黑树,树中节点为 vm_area_struct
-
anon_vma 与 vm_area_struct 是多对多的关系,一个进程对应多个父子进程的虚拟内存区域红黑树,一个虚拟内存区域对应在所有的父子进程中的相同区域,此关系由 anon_vma_chain 来关联:
- 每一个 anon_vma 与 vm_area_struct 之间都有一个 anon_vma_chain 关联结构
- anon_vma_chain.same_vma 关联了一个 vm_area_struct 对应的多个 anon_vma 实例,由双向链表组织,表示一个虚拟内存区所在的每个进程
- anon_vma_chain.rb 关联了一个 anon_vma 对应的多个 vm_area_struct 实例,由红黑树组织,表示一个进程所拥有的所有虚拟内存区域(可以是自己进程的虚拟内存区域也可以是其父进程或子进程的虚拟内存区域)
文件区
- 每个文件系统有一个超级块 super_block 信息,在挂载文件系统时会创建一个他的副本。
- 每个进程的每个文件有一个 inode 节点信息,在打开文件时会生成他的副本。
- 每个进程有一个 address_space 结构,维护一个此进程的文件页区间的红黑树。他与 inode 相对应。
- 当要执行写时复制时,会生成匿名页,脱离文件区,并由 anon_vma_chain 进行关联
- inode 有指向 address_space 和超级块的指针。