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

(undone) MIT6.S081 2023 学习笔记 (Day11: LAB10 mmap)

url: https://pdos.csail.mit.edu/6.1810/2023/labs/mmap.html


mmap和munmap系统调用允许UNIX程序对其地址空间进行精细控制。它们可用于进程间共享内存、将文件映射到进程地址空间,并作为用户级页面错误处理方案的一部分,例如课程中讨论的垃圾回收算法。在本实验中,您将向xv6添加mmap和munmap功能,重点关注内存映射文件。

The manual page (run man 2 mmap) shows this declaration for mmap:

void *mmap(void *addr, size_t len, int prot, int flags,int fd, off_t offset);

mmap 可以通过多种方式调用,但本实验仅需要实现与文件内存映射相关的部分功能。您可以假设 addr 始终为零,这意味着内核应自行决定文件的映射虚拟地址。mmap 会返回该地址,如果失败则返回 0xffffffffffffffff。len 是要映射的字节数,它可能与文件长度不同。prot 表示内存是否应映射为可读、可写和/或可执行;您可以假设 prot 是 PROT_READ 或 PROT_WRITE 或两者兼具。flags 可以是 MAP_SHARED(表示对映射内存的修改应写回文件)或 MAP_PRIVATE(表示不应写回文件),无需实现其他标志位。fd 是要映射的文件的打开文件描述符。您可以假设 offset 为零(即文件中的映射起始位置)。

即使映射相同 MAP_SHARED 文件的进程不共享物理页,也是允许的。

munmap 的手册页(运行 man 2 munmap)显示其声明如下:

int munmap(void *addr, size_t len);

munmap 应移除指定地址范围内的内存映射。如果进程修改了该内存区域且映射方式为 MAP_SHARED,则需先将修改内容写回文件。munmap 可能仅解除部分 mmap 映射区域,但可以假设其操作范围仅限于:从起始位置解除、从末尾解除,或解除整个区域(而不会在区域中间“打洞”解除部分映射)。

你需要实现足够的 mmap 和 munmap 功能,以确保 mmaptest 测试程序能够正常运行。如果 mmaptest 没有用到某个 mmap 的特性,你就不需要实现该特性。

When you’re done, you should see this output:

$ mmaptest
mmap_test starting
test mmap f
test mmap f: OK
test mmap private
test mmap private: OK
test mmap read-only
test mmap read-only: OK
test mmap read/write
test mmap read/write: OK
test mmap dirty
test mmap dirty: OK
test not-mapped unmap
test not-mapped unmap: OK
test mmap two files
test mmap two files: OK
mmap_test: ALL OK
fork_test starting
fork_test OK
mmaptest: all tests succeeded
$ usertests -q
usertests starting
...
ALL TESTS PASSED
$ 

以下是一些提示:

  • 首先,将 _mmaptest 添加到 UPROGS 中,并添加 mmap 和 munmap 系统调用,以便编译 user/mmaptest.c。目前,只需从 mmap 和 munmap 返回错误。我们在 kernel/fcntl.h 中为您定义了 PROT_READ 等。运行 mmaptest,它将在第一个 mmap 调用失败。
  • 在页面错误处理时懒加载页表。也就是说,mmap 不应分配物理内存或读取文件。相反,在 usertrap 中(或由 usertrap 调用的页面错误处理代码中)执行此操作,就像写时复制实验一样。懒加载的原因是为了确保对大文件的 mmap 快速,并且对大于物理内存的文件的 mmap 成为可能。
  • 跟踪每个进程 mmap 映射的内容。定义一个与“应用程序的虚拟内存”讲座中描述的 VMA(虚拟内存区域)相对应的结构。这应该记录由 mmap 创建的虚拟内存范围的地址、长度、权限、文件等。由于 xv6 内核中没有内核内存分配器,因此可以声明一个固定大小的 VMA 数组,并根据需要从中分配。大小为 16 应该足够。
  • 实现 mmap:在进程的地址空间中找到一个未使用的区域来映射文件,并将一个 VMA 添加到进程的映射区域表中。VMA 应该包含一个指向被映射文件的 struct file 的指针;mmap 应该增加文件的引用计数,以便在文件关闭时结构不会消失(提示:参见 filedup)。运行 mmaptest:第一个 mmap 应该成功,但是对 mmap-ed 内存的第一次访问将导致页面错误并杀死 mmaptest。
  • 添加代码以使 mmap-ed 区域的页面错误分配一个物理页面的内存,将相关文件的 4096 字节读取到该页面,并将其映射到用户地址空间。使用 readi 读取文件,该文件需要一个偏移参数来读取文件(但是您将不得不锁定/解锁传递给 readi 的 inode)。不要忘记正确设置页面的权限。运行 mmaptest;它应该到达第一个 munmap。
  • 实现 munmap:找到地址范围的 VMA 并取消映射指定的页面(提示:使用 uvmunmap)。如果 munmap 删除了之前 mmap 的所有页面,则应该减少相应 struct file 的引用计数。如果取消映射的页面已被修改并且文件被映射为 MAP_SHARED,则应将页面写回文件。查看 filewrite 以获取灵感。
  • 理想情况下,您的实现只会写回程序实际修改的 MAP_SHARED 页面。RISC-V PTE 中的脏位(D)指示页面是否已被写入。但是,mmaptest 不会检查未修改的页面是否没有被写回;因此,您可以不查看 D 位就写回页面。
  • 修改 exit 以取消映射进程的映射区域,就像调用了 munmap 一样。运行 mmaptest;mmap_test 应该通过,但可能不是 fork_test。
  • 修改 fork 以确保子进程具有与父进程相同的映射区域。不要忘记增加 VMA 的 struct file 的引用计数。在子进程的页面错误处理程序中,分配一个新的物理页面而不是与父进程共享页面是可以的。后者会更酷,但需要更多的实现工作。运行 mmaptest;它应该通过 mmap_test 和 fork_test。

运行 usertests -q 以确保一切仍然正常工作。

TODO: here


http://www.xdnf.cn/news/3946.html

相关文章:

  • Redis数据结构ZipList,QuickList,SkipList
  • 《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》封面颜色空间一图的选图历程
  • 电磁气动 V 型球阀:颗粒状矿浆与煤黑水介质处理的革命性解决方案-耀圣
  • GAF-CNN-SSA-LSSVM故障诊断/分类预测,附带模型研究报告(Matlab)
  • 学习海康VisionMaster之亮度测量
  • 图像批量处理工具 界面直观易懂
  • TCP 与 UDP报文
  • Doo全自动手机壳定制系统
  • 【AI大模型学习路线】第一阶段之大模型开发基础——第四章(提示工程技术-1)Zero-shot与Few-shot。
  • 基于 jQuery 实现灵活可配置的输入框验证功能
  • 模型 - Xiaomi MiMo
  • Sui 上线两周年,掀起增长「海啸」
  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.3 相关性分析(PEARSON/SPEARMAN相关系数)
  • MongoDB入门详解
  • 永磁同步电机控制算法--基于PI和前馈的位置伺服控制
  • C 语言 第五章 指针(7)
  • LLM提示词设计及多轮对话优化策略在心理健康咨询场景中的应用研究
  • 从零开始学习RAG
  • Jetpack Compose 响应式布局实战:BoxWithConstraints 完全指南
  • 从0到1快速了解Redis数据库
  • 数字化转型:激活存量,引爆增量的三大核心逻辑
  • Spring-使用Java的方式配置Spring
  • 基于Python+MongoDB猫眼电影 Top100 数据爬取与存储
  • 常用CPU、GPU、NPU、DSP、ASIC等芯片区别介绍
  • RGB三原色
  • MATLAB仿真定点数转浮点数(对比VIVADO定点转浮点)
  • 【AI论文】像素修补师(PixelHacker):具有结构和语义一致性的图像修复(Image Inpainting)
  • 【PostgreSQL数据分析实战:从数据清洗到可视化全流程】5.2 数据分组与透视(CUBE/ROLLUP/GROUPING SETS)
  • 三十二、命名实体识别概述
  • 前端-Vue的项目流程