System/161

System/161 is a synthetic (read: made up) hardware platform designed specifically for use in CS161. It includes a simulated system bus and bus devices, and any of several possible simulated CPUs.

The rest of this manual is divided into the following subsections:


Getting System/161

If you are working on the Science Center ICE machines and have the CS161 binary directory ~lib161/usr/bin on your path, you can run the version of System/161 installed by the course staff just by typing sys161 or trace161. You only need download and compile it yourself if you want to work elsewhere.

The source distribution for System/161 can be found on the CS161 web site, here. It supports most Unix-like systems. Windows is not supported. (However, you might be able to compile it with cygwin or a similar toolset. If you do this, you're on your own.)

All you need is sys161-1.0.tar.gz (or whatever the current version is).

Building System/161

Unpack the distribution file by typing
	tar -xvzf sys161-1.0.tar.gz
(substitute whatever version you have for the 1.0.)

This will create a subdirectory called sys161-1.0 with the files in it. Go into this directory by typing

	cd sys161-1.0
(substitute whatever version you have for the 1.0.)

Now you need to know what processor type you want to use. For CS161 this year, you want the "mipseb" processor. For other uses, consult the course staff, or choose from the list of supported processors, which you can get by running ./configure --help.

Run the configure script. Specify the processor type you want as an argument. In the simple case, it looks like this:

	./configure mipseb
It'll grind for a while. If you want it to install the resulting programs someplace other than ~/cs161/root, pass configure the --installdir option, like this:
	./configure --installdir=$HOME/bin
Note that, because of the way the Unix shell handles ~, if you use ~/bin instead of $HOME/bin it won't work.

Now compile things by typing

	make
and install them by typing
	make install
This compiles and installs two programs: sys161, the normal or "fast" simulator, and trace161, which has lots of debugging and diagnostic support built in and thus doesn't run as quickly. You can run OS/161 in either.

If the compilation bombs, contact the course staff.

System/161 has been tested on the following platforms:


Running System/161

There are two versions of System/161 that can be built: the normal one, sys161, and one compiled to be able to log information about what's happening and generally assist debugging, which is called trace161.

The general format for the command line for either of these is like this:

sys161 [ System/161 options ] kernel [ kernel options ]

The System/161 options are:

-c configfile
Specify alternate config file. Default is sys161.conf.
-p port
Listen for debugger connections on specified TCP port. The default is to use the Unix-domain socket ./.sockets/gdb for debugger connections.
Note: because the remote gdb protocol does not support authentication, use this option only with caution.
-s
Pass signal-generating characters (^C, ^Z, etc.) through to the kernel instead of treating them as requests to sys161.
-w
Wait for a debugger connection immediately on startup.

The following additional options control trace161's tracing and are ignored by sys161:

-f tracefile
Set the file trace information is logged to. By default, stderr is used. Specifying -f- sends output to stdout instead of stderr.
-t traceflags
Tell System/161 what to trace. The following flags are available:
d Trace disk I/O
e Trace emufs I/O
j Trace jumps and branches
k Trace instructions in kernel mode
n Trace network I/O
t Trace TLB/MMU activity
u Trace instructions in user mode
x Trace exceptions
Caution: tracing instructions generates huge amounts of output that may overwhelm smaller host systems.

The following option is also only available in trace161:

-P
Collect a kernel profile and leave it in the file gmon.out for analysis by gprof.

The kernel is an operating system kernel to load and run. It should be an ELF-format executable for the same processor type as System/161 is compiled to support. For further information, see below.

Note that options found after the kernel name will be passed to the kernel and not interpreted by System/161.


System/161 Config Files

System/161 reads a config file to determine what hardware it should simulate. The default config file is ./sys161.conf. A different one can be specified with the -c option.

The config file is composed of lines in the following form:

slot-number device-name [args...]

Slots may be 0-31. You must place the bus controller card in slot 31, or the system will not run.

Single-line comments are introduced with #.

The devices available, and the arguments they support, are:

busctl LAMEbus bus controller
ramsize=bytes Specify size of physical RAM. Required.
 
timer CS161 timer device
(no arguments)
 
disk CS161 disk device
rpm=cycles Specify rotation speed. Must be multiple of 60. Default is 3600.
sectors=sectors Specify number of 512-byte sectors on disk. Required.
file=filename Filename to use for disk storage. Required.
paranoid If set, call fsync() on every disk write to hopefully ensure data is not lost if the host system crashes. Slow and not recommended for normal operation.
 
serial CS161 serial console
(no arguments)
 
screen CS161 full-screen console
(no arguments)
Note: not available yet.
 
nic CS161 network interface
hwaddr=addr Set the hardware address for this network card. The hardware address is a 16-bit integer. (Note that 0 and 65535 (0xffff) are reserved for special purposes.) Required.
hub=path Set the path to the socket for the network hub, hub161. The default is .sockets/hub.
 
emufs CS161/OS161 emulator pass-through filesystem
dir=directory Directory to use as root of emufs filesystem. Default is ..
 
trace System/161 trace controller
(no arguments)
 
random CS161 random number generator
seed=number Set seed for pseudo-random-number generator. Default is 0.
autoseed Set seed for pseudo-random-number generator based on the system clock.
Note: if you have multiple random devices, they all share the same randomizer state.

Kernel Debugging with gdb

System/161 supports remote gdb debugging directly into the simulator. The simulator acts like an in-circuit emulator (ICE), only more so, so that you can debug without any interference whatsoever with the debugged code - even timing is unaffected.

To do this, you need a copy of gdb compiled for the same processor that System/161 is simulating, and that understands the ELF kernel file format loaded by System/161. Get and compile the CS161 toolchain. On the Science Center machines, you can just run cs161-gdb.

Run gdb as you normally would:

	gdb kernel
After it finishes loading, attach to System/161 by typing this into gdb:
	target remote unix:.sockets/gdb
and gdb will connect up to the copy of System/161 you have running in the same directory and you can start debugging. (You can debug one in another directory by specifying the right path to its socket.)

Since this is a painful thing to type every time you want to debug, we recommend you create a shortcut for it. Put the following in a file called .gdbinit in the same directory you're working in. (gdb runs this file when you start it up.)

	define db
	target remote unix:.sockets/gdb
	end
Then you can connect up to System/161 for debugging just by running gdb and typing "db".

If you give System/161 the -w option, it will stop and wait for a debugger connection before it runs anything at all. This allows you to start debugging from the very beginning of kernel initialization.

Theoretically everything you can do with gdb normally should work with gdb connected this way. In practice, there are probably some problems. Bring them to the attention of the course staff and we'll see if we can get them fixed.

When System/161 is running, if you type ^G (control-G) into its window, it will immediately stop in gdb (if gdb is attached) or wait for a gdb connection (if gdb is not attached).


Network Connectivity with hub161

If you are using the
network card, you need to use the hub161 program to provide a simulated network for the card to plug into.

When you run hub161, you can optionally give it, on its command line, the name of a unix-domain socket to listen to. The default is .sockets/hub. This pathname may then be specified in the sys161.conf file(s) of the system(s) that wish to connect to that hub.

Each socket can only have one hub running on it at a time; however, you can have as many hubs as you like at once by giving them different socket names.

If you give the cards plugged into the same hub duplicate hardware addresses, bizarre things will happen.

No facility is provided for gatewaying hub161 packets onto the real network via the host system. Such a facility could be written, albeit with some difficulty, but will be fairly useless unless the operating system running within System/161 contains its own complete TCP/IP implementation.

The simulated network is a very simple link layer. All packets are sent to the hub process, which rebroadcasts them to all network cards. There is very little attempt at realism in general.

There is no effort made to synchronize the time among multiple instances of System/161 connected to the same hub; thus, packets may appear to travel in time. Furthermore, because of the way System/161 handles time, any attempt to synchronize the time in software is likely doomed to failure.

Because hub161 communicates over unix-domain sockets, it and all the instances of sys161 or trace161 that wish to connect to it must be run on the same host.

It should not be necessary to restart hub161 if any of the sys161 processes attached to it die, or vice-versa either, although a delay of up to a few seconds on a busy host system may occur.

If you are not using the network, it is recommended that you comment the network devices out of sys161.conf to reduce overhead on the host system.


System/161 Programming Information

At present, System/161 can be compiled to simulate only one fully supported processor type: the MIPS r2000/r3000. There is partial support for the Ant-32 processor as well, but this is incomplete and not supported. It may not be present in the release tarfiles.

This page does not document MIPS r2000/r3000 programming.

The system bus used in System/161 is a simplified architecture made up for the purpose; it is fittingly called LAMEbus. There are also a half dozen or so simulated devices available.

LAMEbus programming info
System/161 LAMEbus devices

The kernel loaded by System/161 is (at present) loaded by the simulator, not a boot ROM within the simulator. Thus, at present, any of the memory regions described as being boot ROMs are in fact unmapped and accesses to them will cause bus errors.

The kernel will be loaded into physical memory at an address chosen so that it appears in kernel virtual memory at the virtual address it was linked to be run at. (The desired address should be passed to the linker at kernel build time.) Precisely what this means depends on the processor and MMU in use. See the processor-specific pages listed at the top of the LAMEbus programming page.

Control will be transferred to the entry point of the kernel specified in the ELF file. The entry point will be called as if it were a C function taking one argument: a string. This string contains the kernel arguments passed on the System/161 command line, concatenated with spaces.

Both the argument string and a small bootup stack, and possibly other machine-dependent data, are located in the top few pages of physical memory. The precise location is not specified and should not be assumed. The kernel should establish its own stack, copy the string to a known location elsewhere, and handle any other machine-dependent data appropriately; then it can reuse the top of physical memory for its own purposes.