MIT6.s081-2020 Lab1 Xv6 and Unix utilities
安装
我用的腾讯云的ubuntu20.4
,按照官方指南“Installing via APT (Debian/Ubuntu)”一节安装较为流畅
如果是16和18会在apt install的时候容易找不到package,并且执意更改源容易存在不可未知的错误,所以在此建议直接使用ubuntu20.4
或安装docker
。
需要补充的是安装完了之后还要apt install riscv64-unknown-elf-gcc
官方指南文档的安装部分
Lab Xv6 and Unix utilities
lab1 文档
做这个Lab之前首先应该先通读一下xv6-book的charpter1
$ git clone git://g.csail.mit.edu/xv6-labs-2020
Cloning into 'xv6-labs-2020'...
...
$ cd xv6-labs-2020
$ git checkout util
Branch 'util' set up to track remote branch 'util' from 'origin'.
Switched to a new branch 'util'
然后每次写完一个部分在项目目录先make clean
再make qemu
就能跑起来了。
sleep
这里就是帮你熟悉一下怎么开始在6.s081里写程序,熟悉的过程可能比较曲折,调用sleep()系统调用就好。
引言
实现 UNIX 程序sleep
对于 xv6;你的sleep
应该暂停用户指定的 ticks。ticks是 xv6 内核定义的时间概念,即来自计时器芯片的两次中断之间的时间。您的解决方案应该在文件中 user/sleep.c
.
实现
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc, char *argv[]) {
int time;
if (argc <= 1) {
fprintf(2, "sleep: need one arg for sleep time");
exit(1);
}
time = atoi(argv[1]);
sleep(time);
exit(0);
}
pingpong
引言
编写一个程序,使用 UNIX 系统调用通过一对管道在两个进程之间“乒乓”一个字节,一个管道用于每个方向。父母应该向孩子发送一个字节;子进程应该打印“: received ping”,其中 是它的进程 ID,将管道上的字节写入父进程,然后退出;父母应该从孩子那里读取字节,打印“: received pong”,然后退出。您的解决方案应该在文件中user/pingpong.c
.
实现
根据文档提供的HINT,我们可以知道大致的实现流程如下:
- 利用
pipe
创建管道。 - 利用
fork
创造一个孩子。 - 利用
read
从管道中读取,并且write
写入管道。 - 利用
getpid
查找调用进程的进程ID。 - 将程序添加到
UPROGS
在生成文件中。 - xv6 上的用户程序有一组有限的库函数可供他们使用。您可以在中查看列表
user/user.h
; 源(系统调用除外)在user/ulib.c
,user/printf.c
, 和user/umalloc.c
.
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
//0 - read 1 - write
int
main(int argc, char *argv[])
{
int p1[2], p2[2];
int ppid, cpid;
char buf[1];
pipe(p1);
pipe(p2);
//child
if(fork() == 0){
//start
close(p1[1]);
close(p2[0]);
cpid = getpid();
read(p1[0], buf, 1);
fprintf(1,"%d: received ping\n",cpid);
write(p2[1],"x",1)