Lab util: Unix utilities

This lab makes you familiar with xv6 and its system calls.

Boot xv6

Install QEMU and gcc for RISC-V following the directions on the tools page.

Clone the base xv6 repository and set up a branch for this lab by following the directions on the git page.

Build xv6:

$ make
riscv64-unknown-elf-gcc    -c -o kernel/entry.o kernel/entry.S
$ make qemu
gcc -Werror -Wall -I. -o mkfs/mkfs mkfs/mkfs.c
xv6 kernel is booting

hart 1 starting
hart 2 starting
init: starting sh

If you type ls at the prompt, you should see output similar to the following:

$ ls
.              1 1 1024
..             1 1 1024
README         2 2 2226   2 3 93
lazytests      2 4 27672
cat            2 5 23496
echo           2 6 22352
forktest       2 7 13104
grep           2 8 26664
init           2 9 23160
kill           2 10 22280
ln             2 11 22152
ls             2 12 25704
mkdir          2 13 22416
rm             2 14 22408
sh             2 15 40416
stressfs       2 16 23376
usertests      2 17 125048
wc             2 18 24496
zombie         2 19 21648
cowtest        2 20 29352
uthread        2 21 27360
call           2 22 22184
kalloctest     2 23 27264
bcachetest     2 24 29736
alloctest      2 25 25824
specialtest    2 26 31944
console        3 27 0

These are the programs/files that mkfs includes in the initial file system. You just ran one of them: ls.


To quit QEMU, type Ctrl-a x, which means:

  • first press both Ctrl and a,
  • then release the keys, and
  • afterwards press x.

Grading procedure

You can run python3 to test your solutions with the grading script. This same grading script is used by the Gradescope autograding process.



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:

Run the program from the xv6 shell:

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

Your solution is correct if your program pauses when run as shown above. However, you should test it using the grading script to make sure it operates correctly. You can see the exact tests that are run by inspecting the grading script code.



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:

Run the program from the xv6 shell and it should produce the following output:

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

Your solution is correct if your program exchanges a byte between two processes and produces output as shown above.

Kernel space system calls: countsys


In this part, you will implement a shell command for xv6 kernel called countsys, which returns the number of syscalls made by far (regardless of whether the syscall number is valid). You will implement your syscall function in the file kernel/sysproc.c and make neccesary modifications to kernel/syscall.c and kermel/syscall.h in order to make it work. You will also implement the user space program for countsys in the file user/countsys.c as you did for sleep.

Some hints:

Run the program from the xv6 shell:

$ make qemu
init: starting sh
$ countsys


When you are ready to submit your work to Gradescope to be automatically graded, you can run make gradescope which generates a file that can be uploaded to Gradescope. This file should only contain the files that were changed as a result of completing the lab assignment.

If you are using the remote VCM infrastructure, you can use scp or rsync to download the zip file.