Creating Test Programs for Nachos Kernels

The test programs for a Nachos kernel are C programs that compile into executables for the MIPS R2000 architecture. These executable programs run on a simulated MIPS machine using the SPIM machine simulator linked with your nachos executable. In effect, your nachos reads the test program executables as data and interprets them, simulating their execution on a real MIPS processor running your Nachos kernel.

Because the user programs are compiled for the MIPS architecture, they will not run directly on the SPARC CPU that you run Nachos on. In fact, since they use Nachos system calls rather than Unix system calls, they cannot even execute correctly on a real MIPS CPU running an operating system such as IRIX or DEC Ultrix. They are built specifically to execute under Nachos. The bizarre nature of these executables introduces some special considerations for building them.

The Makefile in the test directory takes care of all the details of producing the Nachos user program executables. The user programs are compiled using a gcc cross-compiler that runs on Solaris/SPARC but generates code for the MIPS processor. The compiled code is then linked with the MIPS assembly language routines in start.s. (Look at these routines and be sure your understand what they do.) Finally, the programs are converted into a MIPS executable file format called NOFF, using the program coff2noff (supplied).

To run the test programs, you must first build a Nachos kernel that supports user-mode programs. The raw Nachos release has skeletal support for running a single user program at a time; you will extend Nachos to support multiprogramming, virtual memory, and file system calls during the course of the semester. To build a Nachos kernel that can run user programs, edit your Nachos makefile to uncomment the ``cd userprog'' lines, then run gmake to build a new Nachos executable within the userprog directory. You may then use this kernel to execute a user program using the nachos -x option. The argument to -x is the name of the test program executable, produced as described above.

The Nachos distribution includes several sample test programs. For example, look at test/halt.c, which simply asks the operating system to shut the ``machine'' down using the Nachos Halt system call. Run the halt program with the command nachos -x halt, or nachos -x ../test/halt. It may be useful to trace the execution of the halt program using the debug flag. The test directory includes other simple user programs to test your kernels in the later assignments. For these assignments you are also expected to extend these tests and add some of your own.

Some students have difficulty building new test programs. The following guidelines will help you avoid trouble.

  1. Don't screw around with the build process. Place your source code in the test directory, and extend the existing Makefile to build them. Do not remove any of the files in the distributed version of the test directory. In particular, do not remove the file script or any other files used by the build process.

  2. Recognize that your Nachos test programs are extremely limited in what they can do. In particular, their only means of interacting with the outside world is to request services from your Nachos kernel. For example, your test programs cannot call printf, malloc or any other C library routine. If you attempt to call these routines, your program will fail to link. If you somehow succeed in linking library routines into your executable image, the resulting program will not execute because these routines will use Unix system calls, which are not recognized by your Nachos kernel.

  3. The Nachos distribution includes a warning that global variables may not work correctly. It is safest to avoid the use of global variables in your Nachos test programs.

  4. In the past, some students have excused their difficulties with Nachos test programs by informing us that they ``do not know C''. It should come as no surprise that we are not impressed by this excuse. At this point in your career, you have written a large amount of code in C++. We are certain that you are smart enough to adapt quickly to C, which is merely a restricted subset of C++. Just don't try anything fancy: C does not have classes, operator overloading, streams, new, or delete. In addition, C does not permit you to declare items in the middle of a procedure, which is poor programming practice anyway. If you follow these guidelines and use the existing test programs as a starting point, then you should be OK. If you find that you are having problems because you don't know C, then learn it. And stop that whining.

Jeff Chase