Project 5: xv6 Intro
Questions about the project? Send them to
Due: Sunday, 4/10, by whenever.
04/05: Slight change to the spec below; basically, each system call counter should be incremented before the call takes place, not after (this makes handling weird system calls, like exec() and exit() , more straightforward).
This project can be done in either by yourself or in a team of size two. If you can't find a partner, come to discussion thursday this week!
We've been doing a lot of what is called systems programming, in which we write code that uses the facilities of the OS. In this (and the remaining) projects, we'll be delving into a real kernel, to see what it is like on the other side. Cover your eyes! It may get ugly.
The real kernel we will use is something called xv6 , which is a port of a classic version of unix to a modern processor, Intel's x86. It is a clean and beautiful little kernel, and thus a perfect object for our study and usage in the final projects.
This first project is just a warmup, and thus relatively light on work. The goal of the project is simple: to add a system call to xv6. Your system call, getcount() , simply returns the value of some counters in the system.
Specifically, you need to add one counter for every existing system call in the system (see syscall.h for the 21 current system calls; getcount() will be the 22nd). Each counter should be incremented every time a particular system call is issued; thus, if you repeatedly call fork() to create new processes, each call to fork() will increment the fork counter by one. When getcount() is called, the calling program can thus discover how often such a call is made.
Your new syscall should look like this: int getcount(int *counts, int size);
The argument counts is a pointer to an array of ints, of size size . Thus, for the system call to work successfully, size should be at least 23 in this project, as there are 21 system calls to begin with, 1 which you are adding, and they are numbered 1 through 22 (the 0 entry in the array is thus undefined).
Your system call returns 0 on success, and -1 on failure.
Some possible failure cases include: the pointer passed in by the user ( counts ) is not a valid pointer; size is not large enough to accommodate all the values (no need to return some of the values in this case).
Your counters should be protected by some kind of lock(s), of course, as multiple processes may be calling into the kernel at the same time, and thus racing to update the counters.
The count for a system call should only be incremented
The code (and associated README) can be found in ~cs537-1/ta/xv6/ . Everything you need to build and run and even debug the kernel is in there.
All of these can be found off the xv6 site .
Particularly useful for this project: Chapters 0 and 3 (and maybe 4).
Unlike before, we will be grading this project by examining your code and reading a write-up describing the changes you made, as well as possibly running a few tests. The write-up should be short (a few pages at most) and concise. You should also describe how you tested your code, to convince us (and yourselves) that it works!
Handing It In
Use the p5 directory for your handin. If working as a team of two, please
handin the material in ONE directory, with a
Turn in a writeup, called p5.pdf , which describes the changes and all the stuff you have done to build and test your kernel.
Turn in all files that you have changed or added (.c and .h files, and possibly a modified Makefile). Thus, we should be able to take your handed in files, add the rest of the source code, and build and run your kernel and any tests you have turned in.