Core i7 + Linux体系下的虚拟内存:

Core i7的处理器封装包括4核、一个4核共享的L3高速缓存、一个DDR3内存控制器。

Linux选择使用4KB的虚页。

对Core i7 + Linux体系,允许页表进行切换,不过只要进程不变,已分配的页相关联的页表全部是驻留在内存中的。有一个CR3控制寄存器,保存指向该进程私有的四级页表的第一级的起始位置。上下文切换时,CR3的值随之改变。

对Linux系统,一个进程的子页表总会是在物理内存中。

PTE具有三个权限位。有确定页面内容只能读还是允许读写的位;有确定该页是否允许用户模式下访问的位;特别提出XD(禁止执行位),这个位是64位系统引入的,目的是进制从某些内存中取出数据并将其作为指令诠释。相当于限制,只能执行只读代码段,降低系统遭受缓冲区溢出的风险。

有两个对内存缺页程序重要的位:A位即引用位,用于辅助页面替换算法的实现。D位即修改位,表明要替换这个页,是否需要把页面原有的内容先重新写入磁盘,因可能这个页面在之前被修改,但磁盘并未同步该修改。

进一步探讨Linux虚拟内存系统:

内核虚拟内存位于用户栈之上。其某些区域被映射到所有进程的共享页面。

Linux也将一组连续的虚拟页面映射到相应的连续物理页面,为内核直接访问物理内存的特定位置提供方便。(自己第一次看并没感觉到有啥深意……)

段/区域:已分配的虚拟内存的连续片。

task_struct:C代码中,记录一个进程上下文的结构体。这个结构体包含内核要运行该进程需要的所有信息。

mm_struct:task_struct的一个字段。描述虚拟内存的状态。

mm_struct里,书中关注了pgd、mmap字段。pgd就是一级页表的基址,改变上下文时赋给CR3。mmap指向一个vm_area_structs的链表。这个链表的每个结点都描述了虚拟内存一个区域的情况,包括:区域的起终点、区域内所有页的读写权限、区域页面是私有的还是和其他进程共享的等。

Linux内核下的缺页异常处理步骤:

1. 判断给定的虚拟地址值本身是否合法。判断方法是把给定值和区域结构链表的每个结点的起止点比较。如果结果不合法,则触发一个段错误,终止进程。

2. 判断对这个地址进行的操作是否合法。如果不合法,触发一个保护异常并终止进程。

3. 如果前两步骤均未终止进程,则内核选择一个牺牲页面。如果该页面之前被修改过,则先写回磁盘。之后换入新的页面,更新页表。缺页处理程序返回,并把控制流交还给引发缺页异常的指令。之后MMU能正常地翻译给定的虚拟地址。