能想要编写一些新的用户级程序来帮助测试您对`getfilename`的实现。该文档是关于CS 537项目2的说明,主要内容是在xv6操作系统中创建一个新的系统调用`getfilename`,并创建一个新的用户级程序来调用该系统调用。此外,还介绍了项目的截止日期、提交方式、测试、协作等相关信息。 代写

CS 537项目2 – 创建一个xv6系统调用

管理信息

  • 截止日期:2月6日,晚上11:59

  • 项目最多可延迟3天提交,但每延迟一天将扣除10个百分点。

  • 延迟天数

    • 如果您需要在项目上额外的时间,每个人将有2个个人项目的延迟天数和3个小组项目的延迟天数(本学期总共5个延迟天数)。在截止日期后,我们将为按时评分制作提交目录的副本。
    • 要使用延迟天数或延迟提交作业,您将提交文件以及一个额外的文件,该文件仅包含一个数字,表示您的作业延迟的天数(例如1、2、3)。在每连续的一天,我们将制作任何包含这些slipdays.txt文件的目录的副本。在您提交最终提交时,此文件必须存在,否则我们将不知道对您的代码进行评分。
    • 我们将在项目之间跟踪您的延迟天数和延迟提交,并在您用完延迟天数后开始扣除百分比。
    • 在用完延迟天数后,如果延迟1天提交,您最多可以获得90%的分数;延迟2天提交,最多可以获得80%的分数;延迟3天提交,最多可以获得70%的分数,但对于任何单个作业,如果没有例外情况,我们在第三天后将不接受提交。这意味着如果您在单个作业上使用了两个个人延迟天数,您只能再额外提交一天,总共延迟3天,扣除10%的分数。
    • 任何例外情况都需要向教师请求。
    • 示例slipdays.txt
    1
  • ~cs537 - 1/tests/P2提供了一些测试。该目录中有一个README.md文件,其中包含运行测试的说明。测试部分完成,鼓励您创建更多测试。

  • 问题:我们将使用Piazza回答所有问题。

  • 协作:作业必须自己完成。复制(他人的)代码被视为作弊。阅读此内容以获取更多关于哪些是可以的,哪些是不可以的信息。 请不要这样做,帮助我们大家度过一个愉快的学期。

  • 这个项目将在Linux实验室机器上完成,这样您可以在一个典型的基于UNIX的平台(Linux)上学习更多关于C编程的知识。您的解决方案将在这些机器上进行测试。

  • 提交方式:请参阅下面的详细提交说明。

目标

  • 理解xv6操作系统,一个简单的UNIX操作系统。

  • 学习构建和定制xv6操作系统

  • 理解系统调用一般是如何工作的

  • 理解如何实现一个新的系统调用

  • 能够在更大的代码库中导航并找到进行更改所需的信息。

项目简介

创建一个新的系统调用

在这个项目中,您将向xv6操作系统添加一个新的系统调用。更具体地说,您必须实现一个名为getfilename的系统调用,其签名如下:

int getfilename(int fd, char* buf, int n)

系统使用一个称为文件描述符的数字来跟踪进程的打开文件。open()系统调用向进程返回一个文件描述符。操作打开文件的系统调用,例如read()write(),将文件描述符作为其参数之一。在xv6内部,对应用程序隐藏,在进程表中有一个数组,其中文件描述符是索引,数据是打开文件的指针。 您正在添加的新系统调用将一个整数文件描述符、一个字符指针和一个整数n作为其参数,n指定传递的缓冲区的长度。然后,它必须将与该文件描述符关联的文件的名称复制到第二个参数指向的字符缓冲区中。例如,假设一个程序打开一个名为helloworld.txt的文件,并且open()返回3作为分配给该文件的文件描述符。然后,程序使用3作为文件描述符(第一个参数)和一个名为message的字符缓冲区调用getfilename()。当getfilename()返回时,名称helloworld.txt应该被复制到message缓冲区中。此缓冲区的最大长度应为256,因为我们不会测试超过该长度的文件名。 – 如果文件描述符无效,或者没有与该文件描述符关联的打开文件,则getfilename()不需要将任何内容复制到字符指针中,只需返回-1。您可以使用函数argfd来验证这一点。 – 如果用户程序使用空指针作为字符缓冲区调用系统调用,则应返回-1表示失败。 – 如果系统调用成功,返回值应为0表示成功。 – 您可以假设我们将始终传递长度为256的字符缓冲区,并在测试您的系统调用时将第三个参数设置为256。

请注意,向系统调用传递参数和从系统调用返回值有点棘手,并且不遵循我们期望在用户空间中看到的正常参数和返回语义。一个好的起点是查看如何实现chdir系统调用,以及如何处理其参数。请记住,本作业的目标之一是能够在大型代码库中导航并找到您可以基于其工作的现有代码的示例。作为一个小提示,您可能想要在struct file(在file.h中)中创建一个缓冲区,该缓冲区将跟踪使用open系统调用打开的文件的名称。

创建一个新的用户级程序

您还将创建一个新的用户级程序,也称为getfilename,它将调用您的系统调用并以以下格式打印其输出XV6_TEST_OUTPUT Open filename: syscalloutput,其中syscalloutput是一个占位符,用于您的系统调用返回的输出。您应该将要由此用户级程序打开的文件的名称作为命令行参数传递,因此调用此程序的语法将是

prompt> getfilename <name_of_file>

注意事项

请注意,我们不会测试超过256个字符的文件名或路径,因此您可以在struct file中创建新的name字段,并且在用户级程序中的任何缓冲区的大小为256。 另一件需要注意的是,我们只会在代码运行的同一目录中调用getfilename对文件进行操作,因此您不必担心解析文件路径。

内容

  • 必须提交整个XV6目录,并在适当的地方进行修改以添加新的系统调用和新的用户程序。当您运行make qemu - nox时,xv6应该成功编译。重要:请确保在提交XV6目录之前运行make clean。 确保您正确获取提交路径对于脚本能够识别您的提交并进行适当评分绝对至关重要。为了强调这一点,以下树结构描述了您的提交路径应该是什么样子:
handin/<您的cs登录名>/P2/
|---- README.md 
|---- resources.txt
|---- xv6 - public
      | ---- xv6的所有内容以及您的修改,以及一个名为getfilename.c的附加用户级程序
  • 您的项目应该(希望)通过我们提供的测试。

  • 您的代码将在CSL Linux环境(Ubuntu 22.04.3 LTS)中进行测试。这些机器已经安装了qemu。请确保在相同的环境中进行测试。

  • 在顶级目录中包含一个名为README.md的文件,描述实现。该文件应包括您的姓名、您的cs登录名、您的wisc ID和电子邮件,以及您的实现状态。如果一切正常,只需说明即可。如果有不起作用的地方,请告诉我们。请列出您在xv6中更改的所有文件的名称,并简要描述更改的内容。这将不会被评分,所以不要担心。

  • 请注意,xv6已经有一个名为README的文件,不要修改或删除它,只需包含一个单独的名为README.md的文件,其中包含上述详细信息,它不会影响其他README或导致任何问题。如果您删除了xv6的README,将导致编译错误。

  • 如果适用,一个名为resources.txt描述使用的在线资源的文档。欢迎您使用在线资源来帮助您完成作业。我们不建议您使用大型语言模型,如ChatGPT。对于本课程,我们已经看到这些工具给出的示例或解释接近但不完全正确,这会让学生更加困惑,如果他们不知道正确答案是什么。请注意,当您向教学人员寻求帮助时,我们不会协助您使用这些LLM,并且我们希望您能够向教学人员介绍您的代码和逻辑。在线资源(例如stack overflow)和生成工具正在改变包括计算机科学和教育在内的许多行业。但是,如果您使用在线资源,则需要提交一份描述您使用这些资源的文档。在该文档中表明您的解决方案中有多少是完全由您自己完成的,有多少是利用这些工具完成的。请具体说明,指出使用的资源以及您与这些资源的交互方式。不给予外部资源信用是一种剽窃行为。在您的代码中对使用的资源进行注释是一个好习惯。您不会因为使用LLM或阅读帖子而受到惩罚,但您不应该在在线论坛上发布关于本课程项目的帖子。您的大部分代码也应该由您自己努力编写,并且您应该能够解释您提交的所有代码。

其他

启动并运行xv6

xv6操作系统位于CSL AFS的~cs537 - 1/xv6/目录中。该目录包含有关如何启动并运行操作系统的说明,在README.md文件中。该目录还包含此版本操作系统的手册,在文件book - rev11.pdf中。 我们鼓励您事先查看一些资源: 1. 讨论视频 – Remzi Arpaci – Dusseau。 2. 讨论视频 – Shivaram Venkataraman。 3. 关于xv6系统调用的一些背景知识 – Remzi Arpaci – Dusseau。

向xv6添加用户级程序

作为一个示例,我们将向xv6操作系统添加一个新的用户级程序。解压XV6(tar - xzf ~cs537 - 1/xv6/xv6.tar.gz - C.)并进入该目录后,创建一个名为test.c的新文件,内容如下


#include "types.h"

#include "stat.h"

#include "user.h"
int main(void) 
{
  printf(1, "The process ID is: %d\n", getpid());
  exit();
}

现在我们需要编辑Makefile,以便我们的程序能够编译并在我们构建XV6时包含在文件系统中。按照Makefile中其他条目的格式,将您的程序名称添加到UPROGS中。 再次运行make qemu - nox,然后在xv6 shell中运行test。它应该打印进程的PID。