The project for this course is to build an operating system from scratch. We believe that the best way for you to understand operating systems concepts is to build a real operating system and then to experiment with it. To help you get started, we have built a very simple, but functional, operating system called Nachos. Over the course of the semester, your job will be to improve the functionality and performance of Nachos; we expect that you will eventually modify or replace much of what we have written.
The project has four phases, corresponding to four of the major pieces of a modern operating system: thread management, multiprogramming, virtual memory, and networking.
Some phases build on previous phases; for example, all parts of the project use thread management routines. As far as possible, we have structured the assignments so that you will be able to finish the project even if all of the pieces are not working, but you will get more out of the project if you use your own software. Part of the charm of building operating systems is that you get to "use what you build": if you do a good job in designing and implementing the early phases of the project, that will simplify your task in building later phases.
The end result of the project is to build a distributed application, for instance, a chat client and server, with each user on a different computer connected by a network. But before you do this, you have to build the operating system that the distributed application needs in order to be able to run, that is, you have to build the infrastructure for running distributed programs.
Part of the code we provide is a software emulation of a network of MIPS-like workstations. For instance, our code emulates turning on and off interrupts, taking exceptions and page faults, as well as the actions of physical devices (e.g. a disk, a console, and a network controller).
It is important to realize that while we run Nachos on top of this emulation as a Java program, the code you write and most of the code we provide are exactly the same as if Nachos were running on bare hardware. We run Nachos as a Java program for convenience: it is very portable, it is easier to debug (Java is a type-safe language, and we can use jdb), and so that multiple students can run Nachos at the same time on the same machine. These same reasons apply in industry; it is usually a good idea to test out system code in a simulated environment before running it on potentially flaky hardware.
In order to port Nachos to real hardware, we would have to replace our emulation code with a little bit of machine-dependent code and some physical machines. For example, in phase 1, we provide routines to enable and disable interrupts; on real hardware, the CPU provides these functions. In the network project, we emulate the behavior of a physical network; network send and receive requests instead go to sockets and an interrupt is generated after some period of time. The details of how to make network send and receives requests varies tremendously from network device to network device; in practice, you would want to hide these details behind something like the Network abstraction that we provide.
Unless you work for a really smart company, when you develop operating system software you usually cannot change the hardware to make your life easier. Thus, you are not permitted to change any of our emulation code, although you are permitted to change most of the Nachos code that runs on top of the emulation.
Finally, some suggestions for doing well in this course:
- Read the code that is handed out with the assignment first, until you pretty much understand it. Start with the interface documentation.
- Don't code until you understand what you are doing. Design, design, and design first. Only then split up what each of you will code.
- If you get stuck, talk to as many other people as possible.