Operating Systems

Everything described here was done in our 15-412 OS class.
I think this was by far the most time consuming course I ever took, but I also think this was the most rewarding and exciting course at CMU.

Device Driver
This was the first project for this course. We had to write several device drivers - one for console output, one for the keyboard input, and one for the timer. The result of this was a tiny terminal on which you could type. It also had a clock at the upper right corner. The project was simple, but quickly gave us a preview of interrupts, hardware registers, and such.
Pacman
That's the second project - we had to write a thread library and test it out using Pacman. The thread library would support thread creation, destruction, cloning, yielding, waiting, etc. If you think about it, Pacman is awesome for testing concurrency since all the little monsters can be controlled by a separate thread with some simple rules of movement. We learnt a great deal about mutexes, locks, condition variables and other things relevant to concurrency.
Kernel
The most complicated project of the course - we had to write a complete kernel from scratch. The kernel was capable of executing, running, yielding, descheduling, and whatever else you can do with a process. It also supported system calls to perform things like user I/O.
We had to implement our own scheduler, paging system, and context switcher. I think after implementing the code that could successfully switch between two processes, my understanding of how computer really works improved a lot. The scheduler was also really interesting - someone once described our design as an 'octopus' - the scheduler was almost completely self contained and was pulling out processes from one set of queues and putting them into another...
The project took about a month, but in the end the kernel could actually run user programs.. I even wrote a little screen saver program for it.
File System
This was more straightforward than the kernel, but required a lot of work. We learnt a great deal about blocks and sectors, fragmentation, inodes, and whatnot. We used a doubly-indirect index structure for our file system. We also had to write our own buffer cache - that was an interesting piece of code.
The final product supported all the basic commands that any file system has - creating and removing files and directories, shortcuts and symbolic links, reading and writing files, retrieving directory listing and file sizes. We also had a little text editor for it :)