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

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

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

在 Linux 里物理是用户空间分配的虚拟内存,还是内核空间分配的虚拟内存,其最终都需要映射到物理内存上,CPU 才能正常访问这些虚拟内存. 系统所有的物理内存都归 Buddy 分配器管理,那么有的物理页会被用户空间虚拟内存映射,同时又被内核的 VMALLOC 区域的虚拟内存映射,更有甚至还被线性映射区和临时映射区同时映射,那么就会出现上图的场景,一个物理页被 4 个虚拟内存同时映射. 在这个场景下每个映射都需要遵守一个规则,那就是 Memory Type 保持一致,简单的说线性映射区首先采用 WB 缓存模式映射到物理页上,那么接下来要映射到该物理页上的映射也要保持 WB 缓存模式,不能出现有的采用 UC,而有的采用 WT. 另外如果一个新的映射建立时,其向采用一种新的缓存模式,那么它需要将原先映射到该物理页的上的映射都修改为新的缓存模式.

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

Linux 内核提供 CPA(Change Page Attribute) 机制 用于动态地更改内存页面的属性,例如将页面从可写更改为只读,或者更改页面的缓存属性. CPA 机制在修改缓存模式的同时,还会同步映射到该物理页上的页表缓存模式,CPA 机制同时对修改页表的虚拟内存执行 FLUSH TLB/CACHE 操作,以此保证修改有效性. CPA 机制的功能总结为:

  • 修改页属性: CPA 允许内核动态地修改单个或一组页面的属性,例如将页面从用户空间更改为内核空间,或更改页面的缓存类型(如从写回缓存更改为不可缓存)
  • 提高效率: 通过 CPA,内核可以优化对物理内存的使用,例如通过更改页面的缓存策略来提高缓存效率或减少缓存污染
  • 增强安全性: CPA 还可以用于安全相关的任务,比如在页面不再需要时将其属性更改为不可访问,以防止未授权的内存访问

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

CPA 机制向内核和内核模块提供了很多可用的接口,这些接口可以便捷的修改虚拟内存映射的页表,具体含义如下:

  • __set_memory_prot: 函数支持将一定长度的虚拟内存页表属性修改为新的值.
  • _set_memory_uc: 函数支持将页表缓存模式修改为 UC(UNCACHE)
  • _set_memory_wc: 函数支持将页表缓存模式修改为 WC(WriteCombining)
  • _set_memory_wt: 函数支持将页表修改为 WT(WriteThrough)
  • _set_memory_wb: 函数支持将页表修改为 WB(Writeback)
  • set_memory_uc: 函数支持将所有映射同步为 UC 之后将页表修改为 UC(UNCACHE)
  • set_memory_wc: 函数支持将所有映射同步为 WC 之后将页表修改为 WC
  • set_memory_wb: 函数支持将所欲映射同步为 WB 之后将页表修改为 WB(Writeback)
  • set_memory_np: 函数支持将页表的 PAGE_PRESENT 标志位清零
  • set_memory_4k: 函数支持将大页映射拆分成小页映射
  • set_memory_nonglobal: 函数支持将页表修改为不全局可见
  • set_memory_global: 函数支持将页表修改为全局可见
  • set_pages_uc: 函数支持将映射物理页的映射都同步为 UC(UNCACHE)
  • set_pages_wb: 函数支持将映射物理页的映射都同步为 WB
  • set_pages_ro: 函数支持将映射物理页的虚拟内存同步为只读
  • set_pages_rw: 函数支持将映射物理页的虚拟内存同步为可读可写

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

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

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