缺页异常处理

缺页异常(page fault)是操作系统实现延迟内存分配的重要技术手段。当处理器发生缺页异常时,它会将发生错误的虚拟地址存储于 FAR_ELx 寄存器中,并触发相应的异常处理流程。ChCore 对该异常的处理最终实现在 kernel/arch/aarch64/irq/pgfault.c 中的 do_page_fault 函数。本次实验暂时不涉及前面的异常初步处理及转发相关内容,我们仅需要关注操作系统是如何处缺页异常的。

练习题8

完成 kernel/arch/aarch64/irq/pgfault.c 中的 do_page_fault 函数中的 LAB 2 TODO 5 部分,将缺页异常转发给 handle_trans_fault 函数。

在 ChCore 中,一个进程的虚拟地址空间由多段“虚拟地址区域”(VMR,又称 VMA)组成,一段 VMR 记录了这段虚拟地址对应的“物理内存对象”(PMO),而 PMO 中则记录了物理地址相关信息。因此,想要处理缺页异常,首先需要找到当前进程发生页错误的虚拟地址所处的 VMR,进而才能得知其对应的物理地址,从而在页表中完成映射。

练习题9

完成 kernel/mm/vmspace.c 中的 find_vmr_for_va 函数中的 LAB 2 TODO 6 部分,找到一个虚拟地址找在其虚拟地址空间中的 VMR。

hint

  • 一个虚拟地址空间所包含的 VMR 通过 rb_tree 的数据结构保存在 vmspace 结构体的 vmr_tree 字段
  • 可以使用 kernel/include/common/rbtree.h 中定义的 rb_searchrb_entry 等函数或宏来对 rb_tree 进行搜索或操作

缺页处理主要针对 PMO_SHMPMO_ANONYM 类型的 PMO,这两种 PMO 的物理页是在访问时按需分配的。缺页处理逻辑为首先尝试检查 PMO 中当前 fault 地址对应的物理页是否存在(通过 get_page_from_pmo 函数尝试获取 PMO 中 offset 对应的物理页)。若对应物理页未分配,则需要分配一个新的物理页,再将页记录到 PMO 中,并增加页表映射。若对应物理页已分配,则只需要修改页表映射即可。

练习题10

完成 kernel/mm/pgfault_handler.c 中的 handle_trans_fault 函数中的 LAB 2 TODO 7 部分(函数内共有 3 处填空,不要遗漏),实现 PMO_SHMPMO_ANONYM 的按需物理页分配。你可以阅读代码注释,调用你之前见到过的相关函数来实现功能。

挑战题 11

我们在map_range_in_pgtbl_commonunmap_range_in_pgtbl 函数中预留了没有被使用过的参数rss 用来来统计map映射中实际的物理内存使用量1, 你需要修改相关的代码来通过Compute physical memory测试,不实现该挑战题并不影响其他部分功能的实现及测试。如果你想检测是否通过此部分测试,需要修改kernel/config.cmakeCHCORE_KERNEL_PM_USAGE_TEST为ON


challenge

为了防止你通过尝试在打印scores.json里的内容来逃避检查,我们在每一次评分前都会修改elf序列号段的信息并让其chcore在评分点进行打出,当且仅当评分程序捕捉到序列号输出之后,我们才会对检查进行打分,如果没有通过序列号验证,你的评分将为0分。

success

以上为Lab2 Part3。 正确完成上述练习题后,运行 make qemu 后 ChCore 应当能正常进入 Shell;运行 make grade,你应当能够得到 100 分。如果你无法通过测试,请考虑到也有可能是你前面两个部分的实现存在漏洞。

Last change: 2024-11-16, commit: 3c786f6