MIT 6.S081 操作系统课程系列3 Page tables

MIT 6.S081 操作系统课程系列3 Page tables


https://pdos.csail.mit.edu/6.828/2020/labs/pgtbl.html
https://pdos.csail.mit.edu/6.828/2020/xv6/book-riscv-rev1.pdf
本次实验需要读xv6手册第3章。看相关kernel代码。
理解页表的原理并实现一些相关功能。


页表的作用是通过地址映射,使得每个进程看上去拥有自己独立的地址空间和内存,但实际是所有进程共用一套物理内存和地址。

分页硬件


kernel地址空间


创建地址空间


物理地址的分配

见kalloc.c。上次lab已经看懂了它的原理,这里跳过。


进程地址空间


sbrk


exec流程


做题1.打印页表


做题2.每个进程独有的kernel页表

实现:

默认代码里只有唯一一个kernel页表(vm.c的kernel_pagetable),现在要求做成每个进程自己维护一个kernel页表,进程运行时切换到自己的kernel页表。

  1. proc结构体添加一个kernel页表
  2. 目前allocproc函数里会创建用户页表,很自然可以把创建kernel页表加到此处。
  3. 做一个make_kernel_page_table函数。里面创建一个空页表作为每个进程的kernel页表。
  4. make_kernel_page_table里把进程的kstack的映射安装到新页表(kstack默认在procinit里初始化过,所以只安装映射即可)
  5. make_kernel_page_table里参考kvminit把映射安装到进程自己的kernel页表。
  6. freeproc里free自己的kernel页表。
  7. scheduler里swith之前要切换到进程的kernel页表。参考kvminithart。

Debug:

p->sz问题
执行一个命令后shell无反应

做题3.简化copyin/copyinstr

其他问题点

总结

细节其实非常多,运气不好或者理解不够深就得花很多时间看代码和调试。
通过这次实验。研究了大量页表、内存分配和进程相关的底层代码。对内存操作有了很多新的认识。

上次更新 2021-01-28