HW6 Task 2 -OS Modifications and The Benchmark Image

Supplement to the hw6 main assignment.

The OS Source Files

The OS code is in .../cebollita/apps/os/. As much as possible of the OS has been written in C--, in a single file named os.c. Some pieces could not be written in C--, however. Of most interest among these is the bootloader, which is in bootloader.s.

Required OS Modifications

Reading from disk into memory happens for two reasons, and is located in two places in the OS code:
  1. During boot, the bootloader must load the OS into memory. The bootloader itself uses memory locations 0-511, as well as the highest address 512 bytes of memory. Thus those lines are likely fetched into the cache(s). Because the OS also is read into and executes at locations 0-511 (among others), if you fail to flush the low locations the OS will not run correctly.

  2. Once the machine has booted, various system calls a user application makes can cause the OS to initiate a disk read. The code for these reads is in os.c -- there is a single routine through which all disk read requests funnel. You will need to invoke flushing in that routine as well.

Where to Put the flush Instructions

  1. bootloader flushes
    Code must be inserted into bootloader.s to flush the blocks corresponding to addresses 0 through 511. (Technically you should flush high memory as well, but I'm sure you won't run into any problems if you ignore those locations.)

    Here is a bit of code you can insert into bootloader.s. It assumes the block size is one word (4 bytes), and that the address range to flush is 0-511.

    	addi	$s0, $0, 0
    	addi	$s1, $0, 512
    floop:	flush	0($s0)
    	addi	$s0, $s0, 4
    	bne	$s0, $s1, floop
    
    Where does it go? Just after this code:
    	addi	$t0, $t0, 16		# block device address
    	addi	$t2, $0, 1		# block to load
    	ori	$t3, $0, 0x8000		# command (read)
    	sw	$t2, 12($t0)		# read 1 block
    	sw	$t2, 8($t0)		# block 1 on the disk
    	sw	$0, 4($t0)		# address 0
    	sw	$t3, 0($t0)		# go
    

  2. Other flushes
    Like all of us, I'm sure you'd rather program in C-- than assembler. Unfortunately, you can't actually write code that flushes the cache is os.c because the compiler won't generate flush instructions. Instead, you have to write a little assembler subroutine that you call from os.c.

    The procedure we use to rebuild the image file to include you modified code is described next. For the moment, it's enough to know that it involves the use of make. Unless you're familiar with make, you probably don't want to have to touch it. The upshot is that even though it doesn't make sense from a coding perspective, your new assembler routine should be put into existing assembler source file, stopProcessor.s. That files is already being assembled and linked into the OS as part of the build procedure, so you don't have to change that to have your new assembler routine linked in. (stopprocessors.s exists because of exactly the problem you're confonting - the OS wants to execute a halt instruction but there is no C-- statement that will cause the compiler to generate one.)

The Benchmark Image

Because you are modifying the OS, you need to be able to rebuild the bootable image file. Because you want to compare a number of cache designs with each other, you need to run a repeatable benchmark suite of programs. These two considerations have led to the use of a a modified version of the bootable image file from HW5 as the benchmark. The important modification is that a new version of the shell has been written that simply runs a fixed set of programs in order and then terminates. Additionally, a Towers of Hanoi application has been added to the image. Finally, the build process will cause your changes to the OS to be compiled and incorporated.

To build the benchmark image:

  1. In cygwin navigate to .../cebollita/apps/
  2. $ make benchImage
The bootable file benchImage is produced.