当前位置: 首页 > news >正文

MIT6.S081 LAB page tables (2024)

page tables

文章目录

  • page tables
    • Inspect a user-process page table (easy)
    • Speed up system calls (easy)
    • Print a page table (easy)
    • Use superpages (moderate/hard)

HOME MIT 6.S081

Inspect a user-process page table (easy)

题目
在这里插入图片描述

这个好像直接现成实现好了

Speed up system calls (easy)

题目

在这里插入图片描述
大概的含义就是,有些系统调用其实只是想要拿到系统中的信息,所以想到了将这部分数据放在用户可以访问的位置,这样就不需要再进行系统调用,从而加速了系统调用的时间。
思路

因为这是每个进程可能特有的信息,所以应该添加到进程的属性上,修改proc的定义,然后为它在Trapframe下面分配一页(虚拟地址),所以先给这个usyscall分配一个物理页面,然后将这个物理地址与USYSCALL在页表上建立映射。然后在进程销毁的时候,释放掉这个页,并且在页表上释放对这个页的映射。

实现

先分配一个内存页,用于存储usyscall。
在这里插入图片描述
在页表上建立虚拟地址到这个内存页的映射
在这里插入图片描述
释放掉分配到的物理页
在这里插入图片描述
释放掉在页表上映射的内存空间
在这里插入图片描述

Print a page table (easy)

题目

在这里插入图片描述

题目大概说的就是将页表中指向的所有分配了物理地址的部分全都按照这种形式输出出来,具体的效果应该类似于上图的下半部分,一级一级的输出页号,然后pte的值以及指向的物理地址。
实现

首先知道每级页表大小都是4096B,页表项都是8B,所以有4096 / 8 = 512个页表项,所以只要去递归遍历每级页表的所有页表项,如果出现有效的指向下一级就往下递归,需要注意的是,下一级要知道上一级查过来的虚拟地址,所以需要一个baseP来还原每个页表项对应的虚拟地址。
在这里插入图片描述
实验结果
跟所给结果不一样的是打印的时候没有去除前导0,但实际内容相同
在这里插入图片描述

Use superpages (moderate/hard)

题目
在这里插入图片描述
题目的大概意思就是xv6中原来每个页面只支持映射4096B的数据,但是如果一个进程需要很多页的时候页面分配查找需要非常多次,从而会导致效率不高。所以现在让我们修改其中的代码实现超级页(一页2MB)的功能,也就是当需要的空间很大的时候可以一次分配一个超级页。

思路

先分析测试的代码,如下图,superpg_test会先通过sbrk再给进程分配Nbyte的空间(超过一个超级页的大小),然后从SUPERPGROUNDUP(end)的地方(这个其实已经是对后面一个大坑的提示了)开始进入supercheck进行测试,测试的逻辑是读写检查是不是分配到了超级页,如果不是超级页的话页面发生变化pte会发生改变。
在这里插入图片描述
实现

先不管后面fork的测试部分,先完成fork前的测试点。

这里可以注意到超级页的大小刚好是 2 21 B = 2 9 × 2 12 B 2^{21}B = 2^{9} \times 2^{12}B 221B=29×212B,而xv6的多级页表结构如下图。所以超级页分配的时候只需要让分到超级页的虚拟地址的L1指向的pte直接指向物理地址(而不是指向下一级页表)就ok了,这样连续的 2 21 B 2^{21}B 221B的虚拟地址能用相同的pte找到映射的物理地址。
在这里插入图片描述
因此,首先要能分配到一个 2 21 B 2^{21}B 221B大小的连续内存空间。关于内存空闲空间分配的代码在kernel/kalloc.c文件中,我们添加如下代码(左侧绿色条的就是修改或新增的代码):

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就能通过superKalloc来分配一个超级页大小的连续内存空间了。接下来就是看sbrk进入到系统调用做了些什么,发现调用链是kernel/sys_proc.c:sys_sbrk->kernel/proc.c:growproc->kernel/vm.c:uvmalloc 。这部分代码原先的逻辑就是给进程分配更多的PAGE,我们需要改的是检查要是一次请求分配的虚拟地址空间足够大而且是能够作为超级页的虚拟地址始址的时候那就分配一个超级页,代码实现如下图。
在这里插入图片描述
当能分配超级页的时候就调用mapSuperPage将分配的超级页记录到页表上,也就是在二级页表项上增加PTE_SPUER的标记(可以对着上面的多级页表结构理解)。
在这里插入图片描述
在这里插入图片描述
这样我们就在页表上标记了哪个是超级页,还需要修改的是如果读到为PTE_SPUER的页表项后,就不用再读第三级页表了,所以去修改kernel/vm.c:walk
在这里插入图片描述
现在成功将超级页记录到了页表,而且能够读写其中的数据。有始有终,所以还需要修改一下释放的页表的代码(kernel/vm.c:uvmunmap),理解了前面的这个释放应该就不难。

在这里插入图片描述
做到这我们就可以通过fork前面的测试,但是fork后的测试用例还不能通过。这是因为,fork创建的子进程的时候会拷贝原来的进程的数据到新的内存空间,然后创建一个新的页表来做虚拟地址到物理地址的映射(kernel/vm.c:uvmcopy)。问题就出在拷贝到新的内存空间的时候,要改的就是将原来的超级页数据也拷贝到超级页上。所以做如下修改:
在这里插入图片描述
至此就可以成功运行测试用例,看到如下结果
在这里插入图片描述


http://www.mrgr.cn/news/56286.html

相关文章:

  • 随机种子seed设置和知识
  • 大数据-178 Elasticsearch Query - Java API 索引操作 文档操作
  • Termux:Android终端
  • 新的类Rufus应用可带来简单的Windows 11 24H2安装旁路
  • 【UML】一个UML学习的还不错的几个帖子
  • 前端: || 和可选链 ?. 的区别
  • Web保存状态的手段(Session的使用)
  • 11月考期PMP模考题(一)
  • GEE图表:以全球生物多样性的数据集进行直方图表的构建
  • 【算法刷题指南】双指针
  • YOLOv8-seg训练自己的分割数据集
  • Django项目实战-图书管理系统之项目搭建
  • OBOO鸥柏:引领液晶拼接大屏kvm集中控制系统的技术革新
  • 持续优化之路:Envoia许可证管理的轻松进阶
  • URL、URN和URI的区别
  • GJB438C-2021《软件需求规格说明》的一处修订
  • APIJSON 为零代码提供了新的思路
  • Python 应用可观测重磅上线:解决 LLM 应用落地的“最后一公里”问题
  • LeetCode 1750.删除字符串两端相同字符后的最短长度
  • 3.1.1ReactOS系统中搜索给定长度的空间地址区间函数的实现
  • 深度学习:Yolo系列 V1和V2的对比
  • Point2CAD: Reverse Engineering CAD Models from 3D Point Clouds 论文阅读
  • 【C++】用哈希桶模拟实现unordered_set和unordered_map
  • 【大模型】一个简单程序看透 RAG 的核心原理,理解优化 RAG 的关键要点
  • Redission分布式锁详解
  • YOLO目标检测理论详解,YOLOv1理论知识讲解,超w字精读(学习YOLO框架必备),全网最详细教程