The hardware simulator code and your operating system code combine to form the simulation program. However, it’s easier to understand the simulation program if the hardware and operating system code are thought of as being separate parts of the simulation program. As with a real computing system, the connection between the hardware and the operating system occurs at the interrupt handlers.
Unlike a real computing system, however, the operating system in the simulation program does not run on the hardware it controls. The operating system executes as native Java code, while user processes execute on the simulated hardware. This may be a bit confusing at first, particularly for those that have written native operating systems, but this approach is much simpler than writing a native operating system, and the fundamental concepts used in each are the same.
Files related to the simulator can be found under the /export/home/class/cs-os/pa
i
project directory, where i is the assignment number (1, 2, 3, or 4). The
project directory should be accessible from most Monmouth University machines.
The simulator jar contains all the code needed to build a simulator, including
main()
. To run the simulator, type
where i is the assignment number (1, 2, 3, or 4), yymmdd is the date for the most recent jar file, yourOS is the name of the class implementing thejava -cp /export/home/class/cs-os/pa
i/pa
i-
yymmdd.jar:. main
yourOS batchDiskName
OperatingSystem
interface, and batchDiskName is the name of a
batch disk.
The simulator is written in Java version 6. The simulator jar should be backwards compatible with earlier versions of Java (I have not tested this), but upgrading to version 6 is a good idea.
The simulator comprises many classes, but five constituent classes are the most important. Four of the important classes correspond to the four pieces of the hardware architecture: CPU, Primary Store, Disk, and Terminal. The fifth class, the Hardware-Architecture class, corresponds to the complete hardware architecture.
The Hardware interface extends the PrimaryStore interface; the remaining three classes are represented as private instances and cannot be directly accessed from outside the class implementing the Hardware interface. The private members of the Hardware class are accessed indirectly through Primary Store, as described in various sections of the hardware architecture description.
The simulator creates a single of instance of the class implementing the
Hardware interface. The system class has three public members: its
constructor, an initialize-and-execute routine, and a pointer to an object of
type class memory
. The first two public members should not be accessed by
operating system code; only the pointer to memory is properly a public member.
The PrimarayStore interface defines the fetch()
and store()
methods
to read and write Primary Store. There are a few other public members
available to help simplify code; see PrimaryStore.java
in the class
directory for details.
The Hardware interface Hardware.java
defines a number of named constants
that act as parameters for the hardware architecture; such parameters include
Primary Store size, the way Primary Store’s partitioned into System,
User, and Device Space, and so on. See Hardware.java
in the class
directory for details. The actual value of the named constants may change at
any time; it is important that your code use the named constants and not the
actual values.
void interrupt_handler(interrupt_types);
passing in the identifying code for the interrupt. Your code takes over, and
what happens after that is entirely up to you. When your interrupt handler
returns, either by a return
statement or by falling off the end of the
interrupt handler, the simulator resumes executing the user process.
This see-sawing between the user process and the operating system continues until there are no more user processes to execute, at which point the operating system halts the system.
The interrupts that occur may or may not be a result of the executing user process. If the user process makes a system call, then it will generate a system-call interrupt. If, however, the operating system starts a disk read to bring in the next user program, then the resulting disk-io interrupt has nothing to do with the executing user process.
When the simulator starts, it callsOperatingSystem.interrupt()
with the
identifying code for a reboot interrupt.
The simulator and my implementation of the operating system were developed using Java version 6. Relying on backward compatibility, it should be possible to implement the assignments with an earlier Java version, but it’s probably best to upgrade to (or install) the most recent JDK.
To compile file.java
, use the command
where i is the assignment number (1, 2, 3, or 4) and yymmdd is the date for the most recent jar file. For examplejavac -cp /export/home/class/cs-os/pa
i/pa
i-
yymmdd.jar:.
other-options file.java
$ javac -cp /export/home/class/cs-os/pa1/pa1-120207.jar:. -Xlint scheduler.java $
-Xlint
is a javac
option that checks for legal but questionable code.
As a convenience, the simulator defines the main.debugPrinter.log()
method for printing debugging
messages to std-err. The advantage to using main.debugPrinter.log()
over printing to
std-err is that you can use the -d
option on the simulator command
line to control which main.debugPrinter.log()
calls generate output.
main.debugPrinter.log()
prototype is
void log(String flag, String msg)
The flag
argument determines whether a particular main.debugPrinter.log()
call produces
output. A main.debugPrinter.log()
call produces output only if the flag argument appears as part
of a -d
option on the simulator command line. For example, the main.debugPrinter.log()
call
main.debugPrinter.log("interrupts", String.format("tick %4d: %s interrupt raised.%n", clock, Hardware.Interrupt.reboot));
produces output if the flag "interrupts"
(without the double quotes)
appeared as part of a -d
option on the simulator command line; if
"interrupts"
didn’t appear as part of a -d
option, then the
example main.debugPrinter.log()
method call produces no output.
isFlagged()
method to test if a flag was given in the -d
simulator option. The method
signature is
boolean isFlagged(String flag)
For example
if (main.debugPrinter.isFlagged("syscall")) { // Really complicated output about system calls or whatever. }
isFlagged(
flag
)
returns true if and only if
flag
appeared as part of the flag-list argument to the -d
simulator command-line option.
java -cp /export/home/class/cs-os/pai/pai-yymmdd.jar:.
\ main [options] osClass batchDisk [terminalInput]
where
options
is an optional list of command-line options.osClass
is the name of the class implementing the OperatingSystem
interface.batchDisk
is the name of the .dsk
file the operating system
should use for the disk.terminalInput
is the name of the optional
.tty
file the operating system should use for terminal input.$ java -cp /export/home/class/cs-os/pa1/pa1-120218.jar:. \ main os /export/home/class/cs-os/pa1/pa1-empty.dsk The system is halted. Total execution time: 10 ticks, idle time: 9 ticks (90%). $
The .dsk
extension may be omitted:
$ java -cp /export/home/class/cs-os/pa1/pa1-120218.jar:. \ main os /export/home/class/cs-os/pa1/pa1-empty The system is halted. Total execution time: 10 ticks, idle time: 9 ticks (90%). $
If the programs on the batch disk do terminal I-O, the simulator command-line should also contain a terminal-input file. For example
$ java -cp /export/home/class/cs-os/pa2/pa2-120311.jar:. \ main os.class /export/home/class/cs-os/pa2/pa2-ttycopy.dsk \ /export/home/class/cs-os/pa2/pa2-ttycopy.tty The system is halted. Total execution time: 2653 ticks, idle time: 785 ticks (29%). $
The .tty
extension may be omitted. If the terminal-input file has
the same name as the batch disk, the terminal-input filename may be omitted,
and the simulator will automatically open it:
$ java -cp /export/home/class/cs-os/pa2/pa2-120311.jar:. \ main os.class /export/home/class/cs-os/pa2/pa2-ttycopy.dsk The system is halted. Total execution time: 2653 ticks, idle time: 785 ticks (29%). $
The simulator does not change the device simulation files; the same files
may be used repeatedly, independent of the I-O operations performed on the
device. At the end of a simulation, the simulator creates the files
results.dsk
and results.tty
. The file results.dsk
represents
the state of the disk at the end of the simulation; the file results.tty
contains all the data sent to the terminal during the simulation. If a
device is not written to during a simulation, the associated results file is
not created.
-d
Simulator Command-Line Option
The -d
flag-list command-line option controls which of the main.debugPrinter.log()
calls
writes output to std-err. The argument flag-list is a comma
separated list of debugging-print flags; spaces should not appear in the list.
If a main.debugPrinter.log()
call includes one of the listed flags in its flags
argument,
then it writes to std-err, otherwise, it produces no output. For example,
given the main.debugPrinter.log()
call
main.debugPrinter.log("time", String.format("The time is %d.%n", read_clock()))
;
The command-line option -d time
causes the call to produce output; the
call produces no output if the command-line option was -d
interrupts,systemcalls
.
diskio
- output disk I-O information.
terminalio
- output terminal I-O information.
instructioncounts
- output instruction counts on system halt.
interruptcounts
- output interrupt counts on system halt.
interrupts
- output interrupts.
registers
- output register contents before and after interrupts.
systemcalls
- output system calls.