Xv6 Lab Utilities
6.S081 Lab 1: Xv6 and Unix utilities
sleep
Implement the UNIX program sleep
for xv6; 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
.
Some hints:
- Before you start coding, read Chapter 1 of the xv6 book.
- Look at some of the other programs in
user/
(e.g.,user/echo.c
,user/grep.c
, anduser/rm.c
) to see how you can obtain the command-line arguments passed to a program. - 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 thesleep
system call (look forsys_sleep
),user/user.h
for the C definition ofsleep
callable from a user program, anduser/usys.S
for the assembler code that jumps from user code into the kernel forsleep
. - Make sure
main
callsexit()
in order to exit your program. - Add your
sleep
program toUPROGS
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. - Look at Kernighan and Ritchie’s book The C programming language (second edition) (K&R) to learn about C.
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int ticks; // time to sleep
if(argc <= 1){
fprintf(2, "usage: sleep ticks\n");
exit(1);
}
ticks = atoi(argv[1]);
sleep(ticks);
exit(0);
}
build & run:
$ make qemu
...
init: starting sh
$ sleep 10
(nothing happens for a little while)
$
pingpong
Write a program that uses UNIX 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 “<pid>: received ping
”, where <pid>
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 “<pid>: received pong
”, and exit. Your solution should be in the file user/pingpong.c
.
Some hints:
- Use
pipe
to create a pipe. - Use
fork
to create a child. - Use
read
to read from the pipe, andwrite
to write to the pipe. - Use
getpid
to find the process ID of the calling process. - Add the program to
UPROGS
in Makefile. - User programs on xv6 have a limited set of library functions available to them. You can see the list in
user/user.h
; the source (other than for system calls) is inuser/ulib.c
,user/printf.c
, anduser/umalloc.c
.
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int
main(int argc, char *argv[])
{
int p[2]; // file descriptors for pipe
char recv_buf[128];
pipe(p);
if (fork() == 0) {
// child
read(p[0], recv_buf, 4);
close(p[0]);
printf("%d: received %s\n", getpid(), recv_buf);
write(p[1], "pong", 4);
close(p[1]);
exit(0);
} else