MIT6.828_2019_Lab翻译_utilities

实验:Xv6和Unix程序

欢迎大家一起维护中文Lab文档!共同进步! Github

这个实验将会让你熟悉Xv6和它的系统调用

引导Xv6

你必须使用一个X86 Athena machine;也就是说 uname -a 之后应该显示 i386 GNU/Linux or i686 GNU/Linux or x86_64 GNU/Linux。你可以登陆进一个公共的Athena host,通过使用指令ssh -X athena.dialup.mit.edu

我们已经为你在Athena machine上建立了相应的编译器和模拟器。你可以通过运行 add -f 6.828 来使用它们。每次登录你都必须运行此命令(或者将它添加到环境变量)。如果你在编译或运行qemu时得到模糊的错误,请首先检查是否将课程资源添加到了环境变量

获取本Xv6 lab的资源,并检查util分支:

$ git clone git://github.com/mit-pdos/xv6-riscv-fall19.git  
Cloning into 'xv6-riscv'...  
...  
$ cd xv6-riscv-fall19  
$ git checkout util  

为了使lab更加简单,xv6-riscv-fall19代码仓库和书中的xv6-riscv只有轻微的不同

在本实验中你使用的文件是分布式的,通过使用Git版本控制系统。你要为你的答案创建一个新的分支(git branch util)。你可以通过Git用户手册来学习更多关于Git的知识。CS-oriented overview of Git或许也是有用的。Git允许您跟踪您对代码的更改。举个例子,如果你完成了一个练习,和想提交你的变更,你可以通过运行以下内容提交你的修改:

$ git commit -am 'my solution for util lab exercise 1'  
Created commit 60d2135: my solution for util lab exercise 1  
 1 files changed, 1 insertions(+), 0 deletions(-)  
$  

你可以使用git diff命令跟踪你的更改。运行git diff将显示你从上次提交过后更改的代码,“git diff origin/xv6-riscv-fall19”将会显示自初始版本以来改变过的代码。origin/xv6-riscv-fall19就是你下载课程初始代码的分支的名字。

在Athena上build Xv6:

$ make  
riscv64-linux-gnu-gcc    -c -o kernel/entry.o kernel/entry.S  
riscv64-linux-gnu-gcc -Wall -Werror -O -fno-omit-frame-pointer -ggdb -MD -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie   -c -o kernel/start.o kernel/start.c  
...  
$ make qemu  
...  
mkfs/mkfs fs.img README user/_cat user/_echo user/_forktest user/_grep user/_init user/_kill user/_ln user/_ls user/_mkdir user/_rm user/_sh user/_stressfs user/_usertests user/_wc user/_zombie user/_cow  
nmeta 46 (boot, super, log blocks 30 inode blocks 13, bitmap blocks 1) blocks 954 total 1000  
balloc: first 497 blocks have been allocated  
balloc: write bitmap block at sector 45  
qemu-system-riscv64 -machine virt -kernel kernel/kernel -m 3G -smp 3 -nographic -drive   file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0  
hart 0 starting  
hart 2 starting  
hart 1 starting  
init: starting sh  
$  

如果你在命令行输入ls,应该会看到类似于下面的输出:

$ ls  
.              1 1 1024  
..             1 1 1024  
README         2 2 2181  
cat            2 3 21024  
echo           2 4 19776  
forktest       2 5 11456  
grep           2 6 24512  
init           2 7 20656  
kill           2 8 19856  
ln             2 9 19832  
ls             2 10 23280  
mkdir          2 11 19952  
rm             2 12 19936  
sh             2 13 38632  
stressfs       2 14 20912  
usertests      2 15 106264  
wc             2 16 22160  
zombie         2 17 19376  
cow            2 18 27152  
console        3 19 0  

这些就是在初始mkfs文件系统中包含的程序文件。你只是运行了其中一个:ls

如果你是在非Athena机器上工作,你需要根据Tools page安装qume和gcc for RISC-V。

提交程序

你将使用提交网站来提交你的作业。在你提交作业或实验前,你需要从网站上申请一个API key。实验代码采用GNU Make规则来简化提交。在你最后的更改提交后,输入 make handin 提交你的实验。

$ git commit -am "ready to submit my lab"  
[util c2e3c8b] ready to submit my lab  
2 files changed, 18 insertions(+), 2 deletions(-)  

$ make handin  
git archive --prefix=util/ --format=tar HEAD | gzip >     util-handin.tar.gz  
Get an API key for yourself by visiting https://6828.scripts.mit.edu/    2018/handin.py/  
Please enter your API key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  
  % Total    % Received % Xferd  Average Speed   Time    Time         Time  Current  
                             Dload  Upload   Total   Spent        Left  Speed  
100 50199  100   241  100 49958    414  85824 --:--:-- --:--:--           --:--:-- 85986  
$  

make handin 将会把API key存在 myapi.key中。如果你需要改变API key,删除这个文件,然后执行 make handin 再生成一个就可以了(myapi.key不能有换行符)

如果你在 make handin 时有未提交的改变或者有无法追踪的文件,你将会看到类似下面的输出:

M hello.c  
?? bar.c  
?? foo.pyc  
Untracked files will not be handed in.  Continue? [y/N]  

检查上面的,确保你的答案中需要的文件不在上面以??开头的行中,你可以使用git add filename来使Git能追踪到你的文件。

如果make handin不能正常工作,你可以使用make tarball来生成tar文件,然后在web上提交

你可以使用make grade来运行评分程序。TAs将使用与你本地相同的评分程序来评分。

Sleep

为Xv6实现Unix Sleep调用;你的Sleep应该能够暂停一段用户指定的ticks时长(tick是内核中定义的一个概念,代表两次时钟中断之间的时间长度)。你的答案应该实现在user/sleep.c

一些提示:

  • 你可以通过查看/user下的其他程序来学习如何将命令行参数传入程序。如果用户忘记传入参数,sleep程序应该打印error信息
  • 命令行参数作为字符串传递;你可以使用atoi将它转换成一个整数(见user/ ulib.c)
  • 使用系统调用 sleep (见user/usys.S 与 kernel/sysproc.c)
  • 确保 main 调用 exit() 来退出程序
  • 在makefile中将程序添加到UPROGS并通过 make fs.img 来编译程序
  • 阅读Kernighan and Ritchie’s book The C programming language (second edition) (K&R) 来学习C语言

从Xv6 shell运行程序:

  $ make qemu  
  ...  
  init: starting sh  
  $ sleep 10  
  (nothing happens for a little while)  
  $  

如果您的程序行为如上所示,那么你的答案是正确的

可选:编写一个 uptime 的调用程序,打印出uptime的值(tips:uptime是一个系统调用) 。

pingpong

编写一个程序,该程序使用UNIX系统调用通过一对管道在两个进程之间``乒乓’'一个字节,每个方向一个。父进程通过向byte_fd [1]写入字节来发送,而子进程通过从parent_fd [0]读取来接收字节。子进程从父进程收到一个字节后,通过写入child_fd [1] 响应,然后由父级读取。您的解决方案应该在文件user / pingpong.c中。

一些提示:

  • 使用 pipe 创建管道
  • 使用 fork 创建一个子进程
  • 使用 read 读取管道,并使用 write 写入管道

从xv6 shell运行该程序,它将产生以下输出:

$ make qemu  
...  
init: starting sh  
$ pingpong  
4: received ping  
3: received pong  

如果您的程序行为如上所述,则您的解决方案是正确的。“:”之前的数字是打印输出的进程的进程ID。您可以通过调用系统调用getpid来获取进程ID

primes

利用管道编写一个并发版本的筛素数程序,这个想法来自Unix pipe管道的创始人.web此页中解释了如何去操作.你的答案应该写在user/primes.c

你的目标是使用 pipe 和 fork 去创建一个管道。 第一个进程将[2,35]输入进管道。对于每一个质数,您将安排创建一个进程从其左邻居读取在管道并写入其右邻居管道。因为xv6的文件描述符和进程数量是有限制的,所以第一个进程应该在写入35之后停止写入。

一些提示:

  • 小心的关闭进程不需要的文件描述符,否则你的程序可能在第一个进程到达35之前耗尽xv6的资源
  • 一旦第一个进程到达35,您就应该安排管道干净利落地终止,包括所有子进程(提示:关闭管道的写端时 read 将返回 EOF)。
  • 直接往管道里写入32位 intS 而不是格式化的 ACSII I/O 是最简单的。
  • 你应该根据需求在管道里创建进程

如果你的输入如下所示,那么你的答案就是正确的:

$ make qemu  
...  
init: starting sh  
$ primes  
prime 2  
prime 3  
prime 5  
prime 7  
prime 11  
prime 13  
prime 17  
prime 19  
prime 23  
prime 29  
prime 31  
$  

find

编写UNIX查找程序的简单版本:在目录树中查找名称与参数字符串匹配的所有文件。 您的解决方案应该在文件user / find.c中。

一些提示:

  • 查看user / ls.c以了解如何读取目录
  • 使用递归来进入子目录
  • 不要递归到“.” 和“…”
  • 对文件系统的更改在qemu的运行中持续存在。 要获得干净的文件系统,请先运行 make clean,然后再make qemu
  • 你需要使用C风格字符串。 查看K&R(C book),例如5.5节

可选:支持使用正则表达式进行名称匹配。 grep.c 对正则表达式有一些原始支持。

如果产生以下输出(文件系统包含文件 a/b 时),则您的解决方案是正确的:

$ make qemu  
...  
init: starting sh  
$ mkdir a  
$ echo > a/b  
$ find . b  
./a/b  
$  

xargs

编写UNIX xargs程序的简单版本:从标准输入中读取每行并为每行运行一个命令,并将该行的结果作为参数提供给其他命令。 您的解决方案应该在文件user / xargs.c中。

下面的例子说明了xarg的行为:

$ xargs echo bye  
hello too  
bye hello too  
ctrl-d  
$  

一些提示:

使用fork和exec系统调用在输入的每一行上调用命令。 在父级中使用wait等待子级完成命令的运行。
从标准输入中读取一个字符,直到换行符(’\n’)。
kernel/param.h 中声明了 MAXARG ,如果您需要声明 argv ,这可能很有用。
对文件系统的更改在qemu的运行中持续存在。 要获得干净的文件系统,请先运行make clean,然后再进行qemu。

xargs, find, 和 grep 的结合:

$ find . b | xargs grep hello  

以上命令将会在每个拥有文件名为 b 的文件夹下运行 grep hello

运行 xargstest.sh 脚本来测试你的答案.如果你的答案像接下来输出的一样,那么你的答案就是正确的:

$ make qemu  
...  
init: starting sh  
$ sh < xargstest.sh  
$ $ $ $ $ $ hello  
hello  
hello  
$ $  

您可能需要修复 find 程序中的错误。 输出中有很多 $ ,因为xv6 shell是很原始的,并且它不会意识到正在处理文件中的命令而不是控制台中的命令,它会为文件中的每个命令打印 $

本实验到此完成。 在实验室目录中,使用 git commit 提交更改,然后键入 make handin 提交代码。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值