0. 前言

本实验出自斯坦福大学cs140课程,实验环境为Pintos+Bochs,鉴于其文档为全英文,故为了方便读者及自己尝试,整理翻译了其中实验2的主要任务。也加入了自己的理解,方便读者理解实验内容。

1. 进程终结信息

每当一个用户进程因为该进程调用exit或其它原因而结束时,需要打印该进程的进程名和退出码(exit code)。输出格式为:

printf ("%s: exit(%d)\n", ...);

打印的进程名应当是要作为参数传递给process_execute函数的完整名字(省略命令行参数),当不是用户进程的内核线程终止或调用系统调用时,请勿打印这些消息。当一个进程没有成功加载时,这个消息是可选的(不一定需要打印)。

2. 参数传递

暂时(未改动之前),process_execute函数不支持传递参数给一个新的进程,因为process_execute函数的参数仅仅只有一个文件名而已。所以,需要拓展process_execute函数的功能来实现这一点。我们要把它这唯一一个参数用空格分隔开来实现上述功能。分隔后的第一个单词是文件名,第二个单词是第一个参数,以此类推。比如:process_execute("grep foo bar")应该会执行grep线程,并传递两个参数foobar

在命令行中,多个空格的效果和一个空格是一样的。你可以对命令行参数的长度加以合理的限制。比如:你可以限制它的长度在一页的范围里(4kB)。

我们可以通过任何方式来实现参数分离。推荐的方法是在“lib/string.h”中定义的strtok_r()函数,该函数在"lib/string.c"里有注释可以参阅。

3. 系统调用

在“userprog/syscall.c”里实现系统调用,具体来说,是通过其中的syscall_handler函数。系统通过传递来的intr_frame *类型的参数f (其实是f->esp,也就是系统调用参数)来识别系统调用的类型并执行相应的操作。

要实现的系统调用一共有以下13个。这些系统调用的原型都在“lib/user/syscall.h”里。系统调用号在“lib/syscall-nr.h”里。

  • void halt(void)

    通过调用shutdown_power_off()来让Pintos关机。

  • void exit(int status)

    结束当前的用户程序,并返回状态给内核kernel,如果当前进程的父进程正在等待该进程,则这个状态就是应该返回的状态。传统来说,状态0代表返回成功而一个非0值代表有错误。

  • pid_t exec(const char * cmd_line)

    cmd_line会传入进程名及其他参数,exec会去执行该进程,并返回新进程的id(pid)。如果这个进程无法加载或运行(无论什么原因),那么就返回-1. 因此,直到父进程判断完子进程是否加载好了可执行文件之前,父进程无法从exec返回。我们必须通过同步操作来保证这一点。

    我们可以调用process_execute()函数并在它之中完成这些修改。

  • int wait(pid_t pid)

    等待子进程pid并检查该子进程的退出状态(exit status)。

    如果pid子进程仍然未被kill,那么就一直等待它直到它进入终结态。然后,返回pid传递给exit的状态值。如果pid进程没有调用exit,而是被kernel内核终结(比如因为一个exception而被kill),那么wait(pid)必须返回-1.

    如果下列情况中有任何一个为true时,wait会失败并返回-1:

    1. pid不是该进程的直接子进程。(pid是子进程当且仅当该进程能够收到pid作为成功调用exec的返回值)。注意:子进程不能继承。A有一个子进程为B,B有一个子进程为C,此时C不是A的直接子进程。A调用wait(C)将失败。相似地,在子进程的父进程exit之前,子进程也不能被重新分配一个父进程。
    2. 该进程已经调用了wait(pid),即已经在等待pid了。

    一个进程可能会产生任意数量的子进程,并以任意的顺序等待它们,甚至会不等待它们的子进程返回就exit。我们要考虑所有wait可能的情况。注意:无论父进程是否等待某个子进程也无论该子进程是否在它的父进程之前或之后exit,该子进程的资源,包括它的线程结构(struct thread)都必须释放。

    我们可以调用process_wait()函数并在它之中完成这些修改。

    斯坦福官方网站提示:Implementing this system call requires considerably more work than any of the rest.

    完成该系统调用花费的精力比其它任何系统调用都要多。

  • bool create(const char *file,unsigned initial_size)

    创建一个叫file的新文件,初始大小为initial_size. 创建成功则返回true,否则返回false。注意:此时不需要打开该文件。

  • bool remove(const char *file)

    删除叫file的文件。删除成功则返回true,否则返回false。一个文件无论其处在打开或者关闭状态,都可能被删除。

  • int open(const char *file)

    打开叫file的文件。打开成功则返回一个非负整数(文件标识符fd),否则返回-1.

    文件标识符中,0和1是默认的:0是标准输入,1是标准输出。系统调用不会返回这两个文件标识符。

    每个进程都有独立的文件标识符,文件标识符不会被子进程继承。

    当一个文件被重复打开了多次,不管它是被同一个或者不同的进程打开的,每一个open都要返回一个新的文件标识符。在删除文件时,同一个文件的不同文件标识符是独立的。他们不会共享内存中的位置。(比如,一个文件以文件标识符2和3打开了,删除标识符为2的文件不会删除标识符为3的文件)。

  • int filesize(int fd)

    返回以fd打开的文件的大小(以byte为单位)。

  • int read(int fd, void *buffer,unsigned size)

    读文件时,往buffer里读入打开的文件fdsize大小的数据。返回实际读入的bytes数量(在文件结尾时则返回0),若读入失败则返回-1.

    读键盘输入时,标识符为0的文件(标准输入)通过input_getc()read键盘输入。

  • int write(int fd, const void *buffer,unsigned size)

    写文件时,往buffer里写入打开的文件fdsize大小的数据。返回实际写入的bytes数量。有些情况下(一些bytes无法写入),这个数量可能比size小。

    在文件末尾写入通常会扩展文件,但是基本的文件系统无法实现文件增长。预期的行为是在文件末尾写入尽可能多的字节并返回实际写入的数量,如果根本无法写入任何字节,则返回0.

    写入console输出时,我们的代码应该在一次调用putbuf()的过程中写入所有的buffer,只要合理地控制大小即可。不然,不同进程的输出会交替出现。

  • void seek(int fd, unsigned position)

    把下一个要读入或写入的字节跳转到已打开文件fdposition位置。(position为0时代表文件开头)

    在文件的当前末尾进行seek不是错误。以后的read将获得0字节,表示文件结束。以后的write将扩展文件,并用零填充所有未写入的间隙。(但是,在Pintos中,文件在项目4完成之前具有固定的长度,因此文件末尾的写入将返回错误。)

  • unsigned tell(int fd)

    返回下一个在已打开文件fd中即将被读入或写入的字节的位置。

  • void close(int fd)

    关闭文件fd。退出或终结一个进程需要关闭所有其文件标识符,就像是对每一个fd都调用了close一样。

要实现系统调用,我们需要提供在用户虚拟地址空间中读取和写入数据的方法。在获得系统调用编号之前,我们就需要此功能,因为系统调用编号位于用户的虚拟地址空间中的用户堆栈上。这可能有点棘手:如果用户提供了无效的指针,指向内核内存的指针或部分位于这些区域之一的块,该怎么办?答案是应该通过终止用户进程来处理这些情况。

我们还必须同步系统调用,以便任意数量的用户进程可以同步进行调用。一次从多个线程调用“filesys”目录中提供的文件系统代码是不安全的 。目前最好不要修改该目录中的代码。

还有一点很重要:用户程序无法执行的任何操作都不应该会导致OS崩溃,死机,断言失败或其他故障。测试将尝试以多种方式中断我们的系统调用。所以需要考虑所有极端情况并加以处理。用户程序应该能够导致OS停止的唯一方法是调用halt系统调用。

4. 拒绝写入数据至可执行文件

我们要添加代码,来拒绝写入数据至用作可执行文件的文件。我们可以调用file_deny_write()来禁止写入,调用file_allow_write()来恢复写入权限。注意:关闭一个文件也会让它恢复写入权限,所以如果我们要禁止写入,我们必须让该文件保持open状态,直到进程结束运行。

Stanford cs140 Pintos Project2实验目标相关推荐

  1. Pintos project2 实验报告

    project2是在src/userprog中进行代码修改,主要分为参数分离和系统调用者两大任务. 任务一 参数传递 用到的相干目录:pintos/src/userprog/process.c thr ...

  2. 操作系统课程设计pintos project1实验摘记

    前言: 本篇意在记录本学期结束的操作系统课程设计pintos project1实验报告和实现过程.整个实验参考了多篇文章也查阅了一些代码,其中部分内容或与其他文章相同,还请见谅.同时,也为了测试CSD ...

  3. Overlapping Experiment Infrastructure,重叠(分层)实验架构。

    重叠实验设施:更多.更好.更快地实验 1. 序言 2. 相关工作成果[略] 3. 背景 4. 重叠实验基础设施 5. 工具与流程 5.1 工具 5.2 实验设计与样本量 5.2.1 样本量 5.2.2 ...

  4. 【操作系统实验6】CPU调度程序模拟实现

    一.实验目标 加深对操作系统CPU调度以及调度算法的理解 二.实验内容 1.思路 1) 单处理器环境下,针对最短作业优先算法(SJF)和优先级调度算法(Priority),分别模拟实现抢占调度和非抢占 ...

  5. 20172329 2017-2018-2 《程序设计与数据结构》实验五报告

    这是这学期最后一次实验了,也是学到了很多东西,希望自己可以可以善始善终,加油! 让我们开始这一篇博客吧! 20172329 2017-2018-2 <程序设计与数据结构>实验五报告 课程: ...

  6. 如何支持亿级用户分流实验?AB实验平台在爱奇艺的实践

    01 背景 随着互联网公司的产品和业务越来越多样,利用数据来驱动业务决策成为必然,而AB实验正是以数据指标来判断产品功能和运营策略迭代效果的方法和工具,其可以在保证样本同时性和同质性基础上,对比两个或 ...

  7. python递归算法 电影院票价问题_算法课堂实验报告(二)——python递归和分治(第k小的数,大数乘法问题)...

    python实现递归和分治 一.开发环境 开发工具:jupyter notebook 并使用vscode,cmd命令行工具协助编程测试算法,并使用codeblocks辅助编写C++程序 编程语言:py ...

  8. 实验三linux服务与进程管理,Linux 进程与服务管理1

    实验1: inittab配置调整 实验环境 在虚拟机Linux系统下 实验目标 注在Linux虚拟机环境中由于系统是装在虚拟机中而你的寄生系统是Windows因此在虚拟机中你需要用到Ctrl+Alt+ ...

  9. MIC4451驱动单管MOS,IGBT 测试实验

    ▌01 MIC4451 MIC4451 (4452) 是低端MOSFET驱动芯片,输出电流峰值为12A. 上升与下降波形时间为25ns.这一点与在无线充电电路所使用的MD1211对应的10ns相比还是 ...

最新文章

  1. 2009年国内十强开源CMS排行榜[转]
  2. javase(Properties集合及学生对象信息录入文本中案例)
  3. 关于python直接用列表名复制的一些问题 以及 python 子串查找
  4. 浅析去中化区块链游戏资产交易平台
  5. android 解决小米手机上选择照片路径为null的问题
  6. linux下面的安卓模拟器genymotion运行taptap游戏-还没弄完
  7. IOS 修改UIAlertController的按钮标题的字体颜色,字号,内容
  8. 使用 | Java使用WebMagic 爬取网站
  9. “BASH: FORK: RESOURCE TEMPORARILY UNAVAILABLE”的解决方案
  10. 详细讲解怎样做数据仓库需求分析
  11. Android 端 Rsa加密数据
  12. Java Web开发实战—简介篇
  13. Thingworx连接Kepware
  14. AI人工智能仿写在线v.1.2.3
  15. IE11设置默认以IE8的方式解析
  16. vmware虚拟机安装win11系统教程
  17. 计算机共享文件误删怎么恢复,电脑数据恢复分享:电脑文件删除了怎么恢复
  18. 树莓派搭建kms服务器
  19. 最热门的国人开发开源软件 TOP 50
  20. SWAN之ikev2协议inactivity-timeout配置测试

热门文章

  1. 1.1、SR(Segment Routing Over MPLS) 介绍
  2. 魔法成为现实?武大学生团队造出了“隐身衣”,成本不到 500 元
  3. 云师大计算机科学与技术,云南师范大学信息学院
  4. 【性能测试】性能测试的概念和术语介绍 性能测试分类(了解每种测试的目的)
  5. mysql最快导表,IIS通过ISAPI_Rewrite完美实现Wordpress伪静态 | 沉默过客
  6. 关于UnityHub下载 Android NDK/SDK 失败的解决方式
  7. STM32F030F4P6 IIC HAL库驱动CH455G
  8. vs项目中的引用是什么意思
  9. Mediawiki Cargo
  10. AD9235芯片手册阅读笔记