GreyZhang/g_unix: some basic learning about unix operating system. (github.com)

         在计划表中看到了这样一份作业,做一个简单的翻译整理。原来的页面:Homework: xv6 lazy page allocation (mit.edu)

家庭作业:xv6延迟页面分配

在下一堂课开始前,将您的解决方案提交到提交网站。

O/S在使用页表硬件时可以使用的许多巧妙技巧之一是延迟分配堆内存。Xv6应用程序使用sbrk()系统调用向内核请求堆内存。在我们给您的内核中,sbrk()分配物理内存并将其映射到进程的虚拟地址空间。有些程序分配内存,但从不使用内存,例如用于实现大型稀疏阵列。复杂的内核会延迟每一页内存的分配,直到应用程序尝试使用该页——这是由页面错误发出的信号。在本练习中,您将把这个延迟分配功能添加到xv6中。

第一部分:消除sbrk()中的分配

         您的第一个任务是从sbrk(n)系统调用实现中删除页面分配,这是sysproc.c中的函数sys_sbrk()。sbrk(n)系统调用将进程的内存大小增加n个字节,然后返回新分配区域的起始位置(即旧大小)。新的sbrk(n)应该只将进程的大小(myproc()->sz)增加n,然后返回旧的大小。它不应该分配内存,所以应该删除对growtproc()的调用(但仍然需要增加进程的大小!)。

         试着猜测这次修改的结果是什么:什么会坏?

         进行此修改,启动xv6,并在shell中键入echo-hi。你应该看到这样的东西:

1673_MIT 6.828 Homework xv6 lazy page allocation要求翻译_服务器

 

         “pid 3 sh:trap…”消息来自trap.c中的内核陷阱处理程序;它发现了一个页面错误(陷阱14,或T_PGFLT),xv6内核不知道如何处理。请确保您理解出现此页面错误的原因。“addr 0x4004”表示导致页面错误的虚拟地址是0x4004。

第二部分: 延迟分配

         修改trap.c中的代码以响应来自用户空间的页面错误,方法是在错误地址映射新分配的物理内存页面,然后返回到用户空间,让进程继续执行。您应该在生成“pid 3 sh:trap 14”消息的cprintf调用之前添加代码。您的代码不需要涵盖所有角落情况和错误情况;它只需要足够好,就可以让sh运行echo和ls之类的简单命令。

         提示:查看cprintf参数,了解如何查找导致页面错误的虚拟地址。

提示:从vm.c中的allocuvm()中找到参考代码,这是sbrk()调用的(通过growtproc())。

提示:使用PGROUNDDOWN(va)将出现错误的虚拟地址向下舍入到页面边界。

提示:中断或返回以避免printf和myproc()->killed=1。

         提示:您需要调用mappages()。为了做到这一点,您需要删除vm.c中mappages()声明中的static,并且需要在trap.c中声明mappages:

        

1673_MIT 6.828 Homework xv6 lazy page allocation要求翻译_unix_02

 

         提示:您可以通过检查trap()中的tf->trapno是否等于T_PGFLT来检查故障是否为页面故障。

         如果一切顺利,您的延迟分配代码应该会导致echo-hi工作。您应该在shell中至少得到一个页面错误(从而得到延迟分配),也许还有两个。

         顺便说一句,这不是一个完全正确的实现。请参阅下面的挑战,以获取我们意识到的问题列表。

         可选挑战:处理负的sbrk()参数。处理错误情况,如sbrk()参数过大。

验证fork()和exit()是否工作,即使某些sbrk()地址没有为它们分配内存。正确处理堆栈下方无效页面上的错误。确保内核对尚未分配的用户地址的使用有效——例如,如果程序将sbrk()分配的地址传递给read()。