git clone git://g.csail.mit.edu/xv6-labs-2020 git checkout util make qemu
一切都很顺利,只是……在 make qemu 这一步卡住了。
在网上搜索了一下,才知道是我安装的 qemu 版本太高了,2020 年的实验环境不支持。
没办法,干脆下载 2023 年的最新版本吧!
1 2 3
git clone git://g.csail.mit.edu/xv6-labs-2023 git checkout util make qemu
终于可以进入命令界面了。
sleep (easy)
Implement a user-level sleep program for xv6, along the lines of the UNIX sleep command. Your sleep should pause for a user-specified number of ticks. A tick is a notion of time defined by the xv6 kernel, namely the time between two interrupts from the timer chip. Your solution should be in the file user/sleep.c.
记得按照题目中所说,修改一下 Makefile(Add your sleep program to UPROGS in Makefile; once you’ve done that, make qemu will compile your program and you’ll be able to run it from the xv6 shell.)
1 2 3 4
UPROGS=\ $U/_cat\ ............ $U/_sleep\
然后就可以运行啦:
评分:
pingpong (easy)
Write a user-level program that uses xv6 system calls to ‘‘ping-pong’’ a byte between two processes over a pair of pipes, one for each direction. The parent should send a byte to the child; the child should print “: received ping”, where is its process ID, write the byte on the pipe to the parent, and exit; the parent should read the byte from the child, print “: received pong”, and exit. Your solution should be in the file user/pingpong.c.
大概意思就是说要用在父子进程之间建立一对管道,父进程要先向子进程发一个字节,子进程接收以后打印 <pid>: received ping 然后再发回父进程并退出,父进程接受以后再打印 <pid>: received pong。
Write a concurrent prime sieve program for xv6 using pipes and the design illustrated in the picture halfway down this page and the surrounding text. This idea is due to Doug McIlroy, inventor of Unix pipes. Your solution should be in the file user/primes.c.
Your goal is to use pipe and fork to set up the pipeline. The first process feeds the numbers 2 through 35 into the pipeline. For each prime number, you will arrange to create one process that reads from its left neighbor over a pipe and writes to its right neighbor over another pipe. Since xv6 has limited number of file descriptors and processes, the first process can stop at 35.
voidtest(int fd) { int prime, num; if (read(fd, &prime, sizeof(prime)) == 0) exit(0);
printf("prime %d\n", prime);
int p[2]; pipe(p); if (fork() == 0) { close(p[1]); test(p[0]); exit(0); } close(p[0]); while (read(fd, &num, sizeof(num)) != 0) { if (num % prime != 0) { write(p[1], &num, sizeof(num)); } }
close(p[1]); close(fd); wait(0); }
int main(int argc, char *argv[]) { int p[2]; pipe(p);
if (fork() == 0) { close(p[1]); test(p[0]); exit(0); } close(p[0]); for (int i = 2; i <= 35; ++i) { write(p[1], &i, sizeof(i)); } close(p[1]);
wait(0);
exit(0); }
评测:
find (moderate)
Write a simple version of the UNIX find program for xv6: find all the files in a directory tree with a specific name. Your solution should be in the file user/find.c.
任务就是实现一个简单的 find 命令,找到给定目录下文件名为给定名称的文件。
题目说可以参考 user/ls.c,所以我基本上就照搬了 ls.c 的内容,简单修改一下就可以了。
主要是把 fmtname 函数改成了 getname,返回路径对应的文件名的指针。
然后把 ls 函数,改成 find 函数,在判断给定文件类型的时候,如果是普通的文件,那么就判断文件名是否相符。如果是目录,那么就枚举目录下所有文件进行递归,要记得判断文件名如果如果是 . 或者 .. 那么不能递归。
Write a simple version of the UNIX xargs program for xv6: its arguments describe a command to run, it reads lines from the standard input, and it runs the command for each line, appending the line to the command’s arguments. Your solution should be in the file user/xargs.c.
int match(char *re, char *text) { if(re[0] == '^') return matchhere(re+1, text); do{ // must look at empty string if(matchhere(re, text)) return1; }while(*text++ != '\0'); return0; }
// matchhere: search for re at beginning of text intmatchhere(char *re, char *text) { if(re[0] == '\0') return1; if(re[1] == '*') return matchstar(re[0], re+2, text); if(re[0] == '$' && re[1] == '\0') return *text == '\0'; if(*text!='\0' && (re[0]=='.' || re[0]==*text)) return matchhere(re+1, text+1); return0; }
// matchstar: search for c*re at beginning of text intmatchstar(int c, char *re, char *text) { do{ // a * matches zero or more instances if(matchhere(re, text)) return1; }while(*text!='\0' && (*text++==c || c=='.')); return0; }