实验正文
打开实验链接 Lab: Xv6 and Unix utilities ,可以看到他一共有6个小实验(头大,让我们争取日拱一卒吧...):
- Boot xv6 (easy)
- sleep (easy)
- pingpong (easy)
- primes (moderate)/(
hard
) - find (moderate)
- xargs (moderate)
Boot xv6
第一个直接跳过吧,其实上一篇文章已经做过了,就是
- 启动
bash
make queue
- 输入ls
bash
ls
- 然后就是两个额外的小技巧
xv6 has no ps command, but, if you type Ctrl-p, the kernel will print information about each process. If you try it now, you'll see two lines: one for init, and one for sh.
To quit qemu type:Ctrl-a x
(pressCtrl
anda
at the same time, followed byx
).
sleep
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.
实验要求第一条,上来就让你读教材。。我反正老老实实去读了。。虽然读完发现他让我读第一章,我读的是序章???我建议有兴趣你也跟着去读吧 xv6 book
Before you start coding, read Chapter 1 of the xv6 book.
然后就是其他要求或者说步骤吧
- Put your code in user/sleep.c. Look at some of the other programs in user/ (e.g., user/echo.c, user/grep.c, and user/rm.c) to see how command-line arguments are passed to a program.
- 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.
- If the user forgets to pass an argument, sleep should print an error message.
- The command-line argument is passed as a string; you can convert it to an integer using atoi (see user/ulib.c).
- Use the system call sleep.
- See kernel/sysproc.c for the xv6 kernel code that implements the sleep system call (look for sys_sleep), user/user.h for the C definition of sleep callable from a user program, and user/usys.S for the assembler code that jumps from user code into the kernel for sleep.
- sleep's main should call exit(0) when it is done.
- Look at Kernighan and Ritchie's book The C programming language (second edition) (K&R) to learn about C.
我就不做翻译了直接上修改
- 新建 user/sleep.c
c
#include "kernel/types.h"
#include "user/user.h" // for sleep and exit
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(2, "Usage: sleep <seconds>\n");
exit(1);
}
if (sleep(atoi(argv[1])) != 0)
{
fprintf(2, "sleep: failed to sleep\n");
exit(1);
}
exit(0);
}
查看他的 user/user.h 可以看到预定义了一些系统调用方法和libc的函数,还是很熟悉的看起来,但是看到他的commit记录,让我有点郁闷
- 修改Makefile支持编译sleep.c
makefile
UPROGS=\
$U/_cat\
$U/_echo\
$U/_forktest\
$U/_grep\
$U/_init\
$U/_kill\
$U/_ln\
$U/_ls\
$U/_mkdir\
$U/_rm\
$U/_sh\
$U/_stressfs\
$U/_usertests\
$U/_grind\
$U/_wc\
$U/_zombie\
$U/_sleep\
- 重新编译~
bash
make claen;make qemu
- 查看我们的sleep可执行文件
bash
xv6 kernel is booting
hart 2 starting
hart 1 starting
init: starting sh
$ ls
. 1 1 1024
.. 1 1 1024
README 2 2 2305
xargstest.sh 2 3 93
cat 2 4 33520
echo 2 5 32336
forktest 2 6 16136
grep 2 7 36960
init 2 8 32792
kill 2 9 32280
ln 2 10 32088
ls 2 11 35616
mkdir 2 12 32336
rm 2 13 32328
sh 2 14 55112
stressfs 2 15 33200
usertests 2 16 183160
grind 2 17 48544
wc 2 18 34424
zombie 2 19 31680
sleep 2 20 32160
console 3 21 0
$
果然有了,至于为什么编译后就自动挂载到了系统中,引用jyy一句话"计算机的世界里没有魔法,冤有头债有主",后面的课程中一定可以发现他是如何实现的
- 运行 sleep 10
bash
sleep 10
- 运行测试用例 ./grade-lab-util sleep
bash
./grade-lab-util sleep
make: `kernel/kernel' is up to date.
== Test sleep, no arguments == sleep, no arguments: OK (0.6s)
== Test sleep, returns == sleep, returns: OK (0.8s)
== Test sleep, makes syscall == sleep, makes syscall: OK (0.9s)
虽然通过了他的测试用例,但不能称为一个好的应用,至少我在xv6系统控制台中随便输入点或者加点管道、重定向什么的,就gg了
- 代码已提交
xv6-learn