As discussed in class, true support for user programs and a protected kernel requires that we give each of you your own machine. This is because your kernel will need complete control over how memory is managed and how interrupts and exceptions (including system calls) are handled. Since we cannot afford to give you a real machine, we will give you a simulated machine that models a MIPS CPU.
The simulated MIPS machine is really just a big procedure that is part of the Nachos distribution. This procedure understands the format of MIPS instructions and the expected behavior of those instructions as defined by the MIPS architecture. When the MIPS simulator is executing a ``user program'' it simulates the behavior of a real MIPS CPU by executing a tight loop, fetching MIPS instructions from a simulated machine memory and ``executing'' them by transforming the state of the simulated memory and simulated machine registers.
Your Nachos kernel can control the simulated machine in the same way that a real kernel controls a real machine. Like a real kernel on a real machine, your kernel can direct the simulated machine to begin executing code in user mode at a specific memory address. The machine will return control to the kernel (by calling the Nachos kernel procedure ExceptionHandler) if the user program executes a system call trap instruction, or if an interrupt or other machine exception occurs.
Your Nachos kernel will need to examine and modify the machine state in order to service exceptions and run user programs. Your kernel may also find it useful to examine and modify the page table data structure that is used by the simulated machine to translate virtual addresses in the current user program, or to switch the page table in effect, e.g., before switching control to a different user process. All of the machine state --- registers, memory, and page tables --- are simply arrays in your Nachos kernel address space, accessible through the Machine object. See the definitions in machine/machine.h.
The Nachos distribution extends the MIPS CPU simulator to simulate some devices, e.g., disks, a timer, and a console. Nachos maintains a queue of interrupts that are scheduled to occur (e.g., completion of a pending disk operation), and simulates delivery of these interrupts by calling kernel interrupt handler procedures at the appropriate times.
Currently, Nachos has an annoying ``feature'' that has caused problems for some groups. The Nachos kernel will not shut down if there are pending I/O operations, even if there are no threads or processes ready to run. This is the behavior you would expect, but the Nachos simulates a console by using the interrupt queue to repeatedly poll for characters typed on the console. This means that if you create a Console object by uncommenting the lines in main.cc, as required for the later assignments, then Nachos will never shut down when it is done running your test programs. Instead it will idle just like a real kernel, waiting for console input. Feel free to kill it with ctrl-C. It is bad manners to leave idle Nachos processes running, since they chew up a lot of CPU time.