The assignments for this course require you to build a real operating system and then to experiment with it. Our base is a very simple, but functional, operating system called dlxos. The system was written at the University of Maryland Baltimore County and the University of California, Santa Cruz, and is based on the DLX instruction set and computer described by Hennessy & Patterson. Over the course of the quarter, your job will be to improve the functionality and performance of dlxos.
As far as possible, the assignments are structured so that you will be able to finish the assignment even if all of the pieces are not working, but you will get more out of the assignment if you use your own code. An interesting aspect of building this operating system is that you get to use what you build if you do a good job in designing and implementing the early phases of the assignment, it will simplify your task in building later phases.
It's important to realize that while you run dlxos on top of this simulation as a user program on UNIX, all of the code you write is exactly the same as if dlxos were running on bare hardware. The simulator runs as a user program for convenience: multiple students can run dlxos at the same time on the same physical machine. These same reasons apply in industry it's usually a good idea to test out system code in a simulated environment before running it on potentially flaky hardware.
In real life, you are not allowed to throw out a running machine and ask for a CPU with different features before your code will work. Thus, you are not permitted to change any of the CPU simulation code, although you are permitted to change any of the dlxos code that runs on top of the simulator. dlxos is coded in C; if you know C++, you should have little trouble with the language. If you don't know C, you're in the wrong course....
The first piece of your toolkit is a cross-compiler and assembler
that translates programs written in C (C++ doesn't quite work yet)
into a format that the DLX
emulator can load; this format is described below. The compiler is a version
of gcc, so code that works on "generic" GNU C
compilers will work here. However, there's one difference. In
dlxos, as in the real world, calls to the C library
(libc) and to other libraries don't work. We've provided a
few calls for you, but most "standard" libc calls
don't work. In particular, a simplified version of printf is
provided as an simulator trap, and memory allocation
work. This lack of memory allocation means that you'll have to
preallocate any structures your operating system uses or write
(borrow) your own memory allocator. We suggest that you simply
preallocate a pool of whatever structures you need - it's the method
commonly used in many operating systems.
The compiler and assembler are installed on the CATS systems at the following locations:
The DLX C compiler uses files that have been hardcoded to live under /afs/cats.ucsc.edu/users/g/elm/pub/dlx, so it won't necessarily work if you copy it off the CATS system to another Solaris machine. However, you can add a soft link to this file (using ln -s) or make an alias to it, and it should work fine.
You use the DLX C compiler much as you would any "normal"
C compiler, but with a few small changes. First, you must use the
-mtraps option to the compiler to tell it not to expect to
find the C library. Second, you shouldn't use the -g flag to
produce debugging output. Third, it's a good idea to always use
-O3 to produce faster code. A sample compile line looks like
gcc-dlx -mtraps -O3 -c synch.c
This will compile the file synch.c into synch.o, which is just a DLX assembly file. You can link together several files using:
gcc-dlx -mtraps -O3 synch.o process.o -o os.dlx
This will combine the code in synch.o and process.o into os.dlx, which is (also) a DLX assembly file. You can then assemble the file into an "object file" that can be loaded the by DLX simulator using:
dlxasm -i _osinit -l os.lst os.dlx
This produces a simulator-loadable file in os.dlx.obj, and a listing file in os.lst. The listing file isn't necessary, but may be useful for debugging. The -i option tells the assembler that the first routine to be executed should be _osinit, rather than the default
The assembler takes other options as well, summarized in this table:
|-output outputfile||Produce a simulator-loadable file in outputfile rather than the default, which is the input file name with .obj appended.|
|-list listfile||Create a listing file in listfile. This listing file may be very useful when you're debugging your code. It's an assembly language listing with addresses and instructions.|
|-sym symfile||Produce a symbol table list into symfile. The table is sorted alphabetically by symbol name. It can be sorted into numerical order using the UNIX sort command.|
|-init initroutine||Tell the assembler to use initroutine as the procedure to call first when running the code. This doesn't change the code itself, but does change the line in the output file that tells the simulator where to start execution.|
|-debug||Turn on debugging for the assembler. The code output isn't changed.|
The options may be abbreviated by using just the first letter of the option.
Examples of how to use the compiler and assembler may be found in the Makefile supplied with the first assignment.
IMPORTANT: The tools (compiler & simulator) only run on machines using the Solaris or Linux operating system. The version installed on CATS runs only on Solaris, but you can get a copy of the source code for the tools and install them on Linux if you want.
DLX object files are actually just assembly language files that have to be assembled by dlxasm. dlxasm produces a file that contains binary data in an easy-to-read text-based format. A piece of a sample file is shown below:
start:000088a8 00013830 00001000 00007c00 00009000 0000a830 00009000:3a207472 :6170732e :632c7620 :312e3220 :31393939 :2f30332f :30372032 :313a3238 :3a303520 :656c6d20 :45787020 :656c6d20 :303030 00001000:afbefffc :001df020 :afbffff8 :2fbd0010 :afa20000
The first line of the file provides six numbers:
<start location> <highest address in file> <text start address> <text length> <data start address> <data length>
All of these numbers are in hexadecimal. The "start location" is the address at which the simulator will start executing this file. The other numbers are self-explanatory keep in mind that "text" is the same thing as "program code".
The following lines in the file (as many as necessary) are in the
If the address is missing, the data in the line immediately follows the data in the preceding line. For example, in the example above, the word 0x3a207472 is stored at location 0x9000, and 0x6170732e is stored at 0x9004.
There's sample code to read object files in process.c. You'll need this information for Assignment #2, but can safely ignore it until then.
The second part of your toolkit is a software simulator for the DLX instruction set, located on the CATS systems at /afs/cats.ucsc.edu/users/g/elm/pub/dlx/bin/dlxsim. This simulator completely defines the computer that your operating system will run on. This includes both the instruction set as well as the actions of hardware page faults, interrupts, and physical devices such as a disk and the console. You aren't allowed to modify the simulator to do things that might make your life as an OS programmer easier, though you can fix bugs and borrow code from it if you like.
More information on how to use the simulator is available online.
The options to list memory accesses and instruction traces can be useful for debugging. Feel free to use dbprintf() for debugging as well.
You can get a copy of dlxos on any machine with AFS directories mounted from /afs/cats.ucsc.edu/users/g/elm/pub/dlx/dlxos.tgz. Copy this file to your home directory and unpack it using the command "gtar xzf dlxos.tgz". The directory has a Makefile and C and assembly files in it to build the operating system. There may be upgrades to the OS during the quarter, which may be picked up from this location.
IMPORTANT NOTE: the Makefile supplied with dlxos requires GNU make, which is accessible as gmake on the (Solaris) CATS systems. The Makefile will not work with the standard Solaris make.
The dlxos code is documented quite well, and part of your job over
the quarter is to figure out exactly how the pieces fit together. To
help you, we've included an easy way to print debugging
statements. Recall that the simulator can pass arguments to programs
run in it just like argc and argv work in regular
Unix. This can be used to implement debugging statements by passing
dlxsim -x os.dlx.obj -a -D p
This would tell the simulator to execute os.dlx.obj and to pass the arguments -D p to os.dlx.obj. os.dlx.obj is then free to interpret those arguments as it desires; the current OS code treats the arguments as a way to specify which debugging statements to print out. Feel free to add additional debugging flags. Also, a '+' in the debugging string means that all debugging statements are enabled. Otherwise, just those statements mentioned in the string are turned on. For example, -D abc means that only debugging statements that specify a, b, or c will be printed; the rest won't be.
The intent of the grading for the assignment is not to differentiate among those students who do a careful design and implementation of the assignments. Rather, the grading helps us identify those students who (i) don't do the assignments or (ii) don't think carefully about the design, and therefore end up with a messy and over-complicated solution. Remember that you can't pass this course without at least making a serious attempt at each of the assignments. Further, the grading is skewed so that you will get substantial credit, even if your implementation doesn't completely work, provided your design is logical and easy to understand. This means that you should first strive to come up with a clean design of your assignment on paper. Second, don't try to add fancy features just because someone else is!
The grading for the assignment will be as follows: 40% design, 60% implementation. We have structured the grading in this way to encourage you to think through your solution before you start coding. If all you do is to work out a detailed design for what you would do to address the assignment (and if the design would work!), but you write no code, you will still get almost half of the credit for the assignment. The implementation portion of the grade considers whether you implemented your design, ran reasonable test cases, and provided documentation that the TA could understand. Part of being a good computer scientist is coming up with simple designs and easy to understand code; a solution which works isn't necessarily the best that you can do. Thus, part of the design and implementation grade will be based on whether your solution is elegant, simple, and easy to understand.
The simulator and compiler/assembler should be capable of running on any Unix-like workstation. We've tested them under Linux and Solaris, but can't make guarantees for any other operating system. The dlxos code, however, runs only in the simulator, and should run anywhere the simulator can run.
There are three pieces of code you need: the operating system code, the DLX simulator, and the DLX compiler/assembler. If you want to do your assignment work on the CATS instructional systems (or associated workstations), you only need the code for the operating system itself. Both the DLX simulator and the DLX compiler and assembler are available on all CATS machines that can mount AFS in the directory /afs/cats.ucsc.edu/users/g/elm/dlx/bin. You need not copy files from this directory; instead, make links to the executables (gcc-dlx, dlxasm, and dlxsim). Of course, your operating system development should be done in your home directory.
If you want to run the system off-campus on your own Linux box,
you'll need to build your own version of the compiler and emulator
(the assembler is written in perl, so you can just copy it
from the AFS directory to your own machine). You'll need the following
packages from /afs/cats.ucsc.edu/users/g/elm/pub/dlx/:
Building the simulator is relatively straightforward: unpack the compressed tar file, enter the directory, and type gmake. The compiler is a little more difficult, so follow these steps:
Note that the compiler is relatively large it requires around 50 MB to install. The assembler and simulator are significantly smaller.
Several people have already installed the DLX tools successfully on Linux boxes. There are a few minor issues which need to be addressed:
Much of the assignment material was taken from Dr. Ethan Miller's CMPS 111 web page.