Skip to content

feat(pgtbl): 实现统计最近访问页表、独立内核页表

zhangweijie requested to merge mit6.s081_pgtbl into pgtbl

Print a page table:遍历当前进程页表,如果状态是可用,则递归打印

  1. 遍历顶级页表,如果可用,则进入其所指的中级页表,直到最终页表,然后打印pa数据
  2. 需要用到位移(内置宏定义),因为页表中所指的地址是下一级页表的地址,所以需要转换成pagetable_t类型才能正确访问,通过对内核内存地址进行位移操作,获取对应的下标来获取下级页表地址。

Detecting which pages have been accessed:给定地址,统计该地址之后指定范围内已被访问过的页表

  1. 新增页表标记位,用来标记当前页表是否被访问过
  2. 在统计页表是否被访问之后,需要将访问标记位置为0
  3. 需要将内核数据写到用户态的数据之中
  4. 访问,即在walk中将获取到的页表进行标记、分配页表的时候也标记

用户进程独立内核

  1. 用户进程独立内核页表
    1. 因为所有进程共享一个全局内核页表,同时这个页表中的内核栈各自独属于某个用户进程。
    2. 所以当用户进程陷入内核的时候,有一定风险导致访问到非当前用户的内核栈
    3. 实现思路
      1. proc结构体新增一个内核页表结构
      2. 将必要的信息映射到用户内核页表中,如代码段之类,可参考全局页表初始化时所做的操作
      3. 在copyin和copyout的时候,使用用户进程的内核页表
      4. 调度的时候,也需要使用用户当前的内核页表,结束的时候,需要切回全局页表
      5. 进程结束的时候,需要释放页表,但不能释放叶子节点的内存,因为它可能被其他进程或者内核所使用。
  2. 用户进程独立内核页表映射用户数据
    1. 在独立内核页表的基础上,将用户数据也映射在低地址区域
    2. 在原本的映射区间中,0x80000000L之下是设备之类的映射。
    3. 而用户地址是从0开始增长,刚好可以将其映射到独立内核页表中的0-plic的区域之间。
    4. 实现之后的效果,即在内核态读写用户进程数据的时候,不需要借助其页表也能进行读写(使用进程独用的内核页表),此时内核页表已经映射过了,不用遍历用户页表。
    5. 实现思路
      1. 映射用户地址到独立内核页表低地址地方,同时需要给予内核权限。
      2. fork、exec、sbrk等需要操作用户数据的地方,需要更改
      3. 访问操作是可以直接访问用户虚拟地址

Merge request reports

Loading