图片无法显示,请右键点击新窗口打开图片

BiscuitOS 内存管理之分页大专题订阅入口

图片无法显示,请右键点击新窗口打开图片

在 Linux 里应用程序分配一段虚拟内存之后,系统不会为其分配物理内存并且建立页表映射,直到进程首次访问虚拟内存时,MMU 检查到物理内存不存在而触发缺页异常,缺页异常处理函数根据虚拟内存的属性为其分配物理内存,并建立建表映射到新的物理内存上,待缺页异常处理完毕之后,进程重新执行发生缺页的指令,此时进程可以正常访问虚拟内存. 以上便是惰性分配虚拟内存的场景吗,在该场景中,缺页异常处理函数是根据虚拟内存属性建立页表,也就是说不同类型的虚拟内存会有不同的页表属性值, 那么本文研究用户进程如何影响页表的内容.

图片无法显示,请右键点击新窗口打开图片

应用程序在分配虚拟内存时,Linux 提供了三个权限标志位,用于设置虚拟区域的权限,分别是:

  • PROT_READ: 该标志告诉系统这块虚拟区域是可读的. 如果尝试读取没有设置 PROT_READ 的虚拟内存,将会触发缺页并收到段错误(SegmentFault)
  • PROT_WRITE: 该标志告诉内核这块虚拟区域是可写的,即进程可以修改这块虚拟内存的内容,任何尝试写入没有 PROT_WRITE 的虚拟内存,同样将触发缺页并收到段错误
  • PROT_EXEC: 该标志告诉内核这块区域是可执行的,即这段虚拟内存区域可以执行代码,如果尝试在没有 PROT_EXEC 的虚拟内存上执行代码,那么同样会触发缺页并收到段错误
  • PROT_SEM: 该标志通常用于允许页面被用于原子操作,这是一个特殊用途的标志,不常见于一般应用程序
  • PROT_NONE: 该标志设置虚拟内存为不可访问。如果设置了此标志,任何试图读取、写入或执行这个内存页面的操作都会产生错误
  • PROT_GROWSDOWN: 这是一个用于 mprotect 的特殊标志,用于指示如果内存区域是一个向下增长的栈,应当将更改扩展到栈的起始部分
  • PROT_GROWSUP: 这是用于 mprotect 的另一个特殊标志,用于指示如果内存区域是一个向上增长的栈或堆,应当将更改扩展到栈或堆的末尾部分

例如在使用 mmap 分配虚拟内存的时候,可以组合使用这些标志,以此构造不同权限的区域,例如 PROT_READ 和 PROT_WRITE 标志可以构造可读可写的虚拟区域,又如 PROT_READ 和 PROT_EXEC 标志可以构造只读代码执行区等.

图片无法显示,请右键点击新窗口打开图片

处理权限标志位之外,Linux 还提供了映射方式标志位,用于设置虚拟内存的映射方式,分别是:

  • MAP_SHARED: 创建的虚拟内存映射允许多个进程共享同一段内存,这意味着当一个进程修改了这块内存区域的内容时,这些更改会反映到所有拥有这个映射的其他进程
  • MAP_PRIVATE: 对映射内存区域的更改不会反映到原始文件中,也不会对其他进程中的相同映射可见。这意味着每个进程拥有该内存区域的一个私有副本. 通常,MAP_PRIVATE 与写时复制(COW)机制结合使用。这意味着,当进程试图写入映射的内存时,操作系统会为该进程创建该内存区域的一个私有副本,以避免影响到其他进程

图片无法显示,请右键点击新窗口打开图片

图片无法显示,请右键点击新窗口打开图片

BiscuitOS 内存管理之分页大专题订阅入口

图片无法显示,请右键点击新窗口打开图片