5.1 Developing and compiling user programs
Nachos cross-compiler allows programmers to write C user programs and compile to
COFF binaries that can be executed on the Nachos MIPS simulator. COFF stands
for Common Object File Format and is an industry-standard binary format which
the Nachos kernel understands. The cross-compiler itself is platform-dependent
(though the COFF binary is not) and therefore one needs to make sure the correct
one is used.
The following code is an example of C user program (nachos/test/cp.c).
1 #include "syscall.h"
2 #include "stdio.h"
3 #include "stdlib.h"
4
5 #define BUFSIZE 1024
6
7 char buf[BUFSIZE];
8
9 int main(int argc, char⋆⋆ argv)
10 {
11 int src, dst, amount;
12
13 if (argc!=3) {
14 printf("Usage: cp <src> <dst>\n");
15 return 1;
16 }
17
18 src = open(argv[1]);
19 if (src==-1) {
20 printf("Unable to open %s\n", argv[1]);
21 return 1;
22 }
23
24 creat(argv[2]);
25 dst = open(argv[2]);
26 if (dst==-1) {
27 printf("Unable to create %s\n", argv[2]);
28 return 1;
29 }
30
31 while ((amount = read(src, buf, BUFSIZE))>0) {
32 write(dst, buf, amount);
33 }
34
35 close(src);
36 close(dst);
37
38 return 0;
39 }
The corresponding COFF binary is also located in the nachos/test directory. This
is the default directory for user programs. Alternatively, one can specify the test
directory by including a line fileSystem.testDirectory = ... in the config
file.
Question: Where and how does Nachos set the test directory? [hint: Check
nachos.machine.Machine.main()]
Inspecting the cp.c source code, we find that it follows the C syntax with familiar
functions such as printf, open, etc. However, a closer look at the test directory
and Makefile reveals that some of the functions are in fact implemented by
Nachos in the test directory. The function prototypes of system calls such as
creat, open, read, write, close, halt, etc., are defined in syscall.h
and their implementations are to be completed in the one of the Nachos
projects.
There are multiple stages to building a Nachos-compatible MIPS binary (all of
which are handled by the test Makefile):
- Source files (*.c) are compiled into object files (*.o) by mips-gcc.
- start.s is preprocessed and assembled into start.o. This file contains the
assembly-language code to initialize a process. It also provides the system
call ”stub code” which allows system calls to be invoked. This makes use
of the special MIPS instruction syscall which traps to the Nachos kernel
to invoke a system call.
- An object file is linked with libnachos.a to produce a Nachos-compatible
MIPS binary, which has the extension *.coff.
- Note that if you create a new test file (*.c), you will need to append
your program name to the variable TARGETS in the Makefile inside test
directory
One can run test programs by running “nachos -x PROGNAME.coff”. In
nachos.conf, the appropriate kernel and process need to be specified:
1 Machine.stubFileSystem = true
2 Machine.processor = true
3 Machine.console = true
4 ...
5 Kernel.processClassName = nachos.userprog.UserProcess
6 Kernel.kernel = nachos.userprog.UserKernel
subFileSystem is enabled to load the user program.