Programming Assignment 2 - Device Management

Operating Systems, Summer 2002


Table of Contents

Due Date

This assignment is due on Tuesday, 9 July, no later than 2:00 p.m. See the submissions page (last modified on 9 July 2002) for information about submitting your assignment.

Introduction

This assignment extends the operating system developed in the previous assignment by adding device management features. This new version of the operating system gives user processes access to the disk and terminal devices, and lets the user process read and write data to and from the disk and terminal.

Device Allocation Policies

A device allocation policy determines how and when a user process may obtain access to a device.

Disk Allocation

The disk allocation policy provides unlimited concurrent access to the disk by allowing the disk to be opened by any number of processes. This means the open system call should never return status::device_busy.

Terminal Allocation

The terminal allocation policy provides exclusive access to the terminal by allowing the terminal to be opened by at most one process. Any process that attempts to open the already opened terminal should receive the status::device_busy status code in response to the open system call.

Device Management Policies

A device management policy determines what a process may do to a device, and how the device behaves.

Disk Management Policy

The disk management policy presents the operating system's view of the disk to the user process. A user process' view of the disk is the same as the operating system's view of the disk; that is, the disk appears to a user process as an C-style array of disk blocks.

This policy is known as raw disk management, and is important for those application, such as data-base applications, that need to control all aspects of data movement between disk and primary store.

Terminal Management Policy

The terminal management policy makes the terminal appear to a user process as a character-oriented device which can read and write a variable-number of bytes in one operation.

The terminal management policy also specifies the terminal line discipline (or just "line discipline" when the terminal part is understood), which specifies how, if at all, the operating system should interpret the characters begin read and written from the terminal on behalf of the user process. The input line discipline applies to the characters being read from the terminal, and the output line discipline applies to the characters being written to the terminal.

The input line discipline in this project is simple: the operating system does not interpret any of the bytes read from the terminal except for the device::eof_char end-of-file character. When the end-of-file character appears in the byte stream from the terminal, it should be removed from the stream and no further bytes from the terminal should be passed along until the terminal is closed and re-opened again.

The output line discipline is even simpler than the input line discipline: there is none. All bytes from the user process are passed along to the terminal without interpretation.

Device Management System Calls

The system calls that should be supported by the operating system are (the constant in parenthesis is the value in register 0):

open system call (system_call::open)
Open an I-O connection to the device d; d is passed in CPU register 1. Legal values for d are device::disk and device::terminal. The status of the open system call is returned in CPU register 0; the possible status codes are

After the open system call is completed, CPU register 0 contains the system call status:

status::okcommand completed successfully
status::device_busyrequested device has already been allocated
status::bad_devicethe value d in CPU register 1 is not device::disk or device::terminal

If the open system call completed successfully, CPU register 1 contains a connection identifier, which must be included as an argument to other system calls related to this device. If the open system call didn't complete successfully, the contents of CPU register 1 is undefined.

close system call (system_call::close)
The currently executing process is closing its connection to the device associated with the connection id passed in CPU register 1. The status code for the close system call is passed back to the user process in CPU register 0, and is one of the values

After the close system call is completed, CPU register 0 contains the system call status:

status::okcommand completed successfully
status::bad_devicethe connection id in CPU register 1 is not associated with any device

If the close system command completes successfully, the connection id held by the user process becomes invalid and may not usefully be used in any other system call.

read system call (system_call::read)
The currently executing process wants to read data from the device associated with connection id given in CPU register 1. The data read from the device are placed in Primary Store starting at the address given in CPU register 2. The interpretation of the contents of CPU register 3, n, depends on the type of device from which the data are being read. If the disk is being read, then n is the disk block number to read; if the terminal is being read, then n is the maximum number of characters to read from the terminal.

After the read system call is completed, CPU register 0 contains system call status:

status::okcommand completed successfully
status::bad_devicethe connection id in CPU register 1 is not associated with any device
status::bad_addressthe Primary Store address in CPU register 2 is bad
status::bad_countthe contents of CPU register 3 is bad

If the read system command completes successfully, CPU register 1 contains either the number of the disk block read (if the read was from the disk) or the number of characters read from the terminal (if the read was from the terminal). The number of characters actually read from the terminal may be smaller (never larger) than the number of characters requested if the terminal sends an end-of-file character during the read. Once a terminal receives the eof-character, it will always read 0 characters.

write system call (system_call::write)
The currently executing process wants to write data to the device associated with connection id given in CPU register 1. The data written to the device are located in Primary Store starting at the address given in CPU register 2. The interpretation of the contents of CPU register 3, n, depends on the type of device to which the data are being written. If the disk is being written, then n is the disk block number to which the data will be written; if the terminal is being written, then n is the number of characters to write to the terminal.

After the write system call is completed, CPU register 0 contains the system call status:

status::okcommand completed successfully
status::bad_devicethe connection id in CPU register 1 is not associated with any device
status::bad_addressthe Primary Store address in CPU register 2 is bad
status::bad_countthe contents of CPU register 3 is bad

Interrupt Handlers

This assignment also implements the handlers for illegal instruction, invalid address and the terminal interrupts. If a user process throws an illegal-instruction or illegal-address interrupt, your operating system should terminate it, recovering any resources the process may hold.

Test Device Files

Some new batch disks have been added to the directory /export/home/class/cs-438-505/devices to test the new features added to your operating system. Because programs in the pa2 disks write to devices, the simulator will create the result files results.dsk and results.tty.

pa2-diskio.dsk
Contains a single process that repeatedly read and writes the last block on the disk, writing a new word in the disk block each time. When finished, the last block contains the values 51100 through 51131 in succession.
$ /e*/h*/c*/*5/Linux/bin/os2 -d /e*/h*/c*/*5/devices/pa2-diskio.dsk

The system is halted.
Total execution time:  1925 ticks, idle time:  1138 ticks (59%).

$ /e*/h*/c*/*5/Linux/bin/print-disk-block results.dsk 511
Block 511
0000051100 0000051101 0000051102 0000051103 
0000051104 0000051105 0000051106 0000051107 
0000051108 0000051109 0000051110 0000051111 
0000051112 0000051113 0000051114 0000051115 
0000051116 0000051117 0000051118 0000051119 
0000051120 0000051121 0000051122 0000051123 
0000051124 0000051125 0000051126 0000051127 
0000051128 0000051129 0000051130 0000051131 

$ 

pa2-dio-checked.dsk
Contains two programs; one reads and writes the disk as in pa2-diskio.dsk and the other checks the disk block once the first program is done. The two processes coordinate with fork-join. These program check their work, so if you don't get an error message, everything worked.

pa2-dio-shared.dsk
Contains the same two programs as pa2-dio-checked.dsk and a third, big program that does nothing but fill up user space. Tests disk sharing between the operating system and user processes. These program check their work, so if you don't get an error message, everything worked.

pa2-3dio.dsk
Contains three copies of the program in pa2-diskio.dsk, each working on one of the last three blocks in the disk. Test disk sharing among user processes. These programs don't check their work.
$ /e*/h*/c*/*5/Linux/bin/os2 -d /e*/h*/c*/*5/devices/pa2-3dio.dsk

The system is halted.
Total execution time:  11165 ticks, idle time:  8788 ticks (78%).

$ /e*/h*/c*/*5/Linux/bin/print-disk-block results.dsk 509 510 511
Block 509
0000050900 0000050901 0000050902 0000050903 
0000050904 0000050905 0000050906 0000050907 
0000050908 0000050909 0000050910 0000050911 
0000050912 0000050913 0000050914 0000050915 
0000050916 0000050917 0000050918 0000050919 
0000050920 0000050921 0000050922 0000050923 
0000050924 0000050925 0000050926 0000050927 
0000050928 0000050929 0000050930 0000050931 
Block 510
0000051000 0000051001 0000051002 0000051003 
0000051004 0000051005 0000051006 0000051007 
0000051008 0000051009 0000051010 0000051011 
0000051012 0000051013 0000051014 0000051015 
0000051016 0000051017 0000051018 0000051019 
0000051020 0000051021 0000051022 0000051023 
0000051024 0000051025 0000051026 0000051027 
0000051028 0000051029 0000051030 0000051031 
Block 511
0000051100 0000051101 0000051102 0000051103 
0000051104 0000051105 0000051106 0000051107 
0000051108 0000051109 0000051110 0000051111 
0000051112 0000051113 0000051114 0000051115 
0000051116 0000051117 0000051118 0000051119 
0000051120 0000051121 0000051122 0000051123 
0000051124 0000051125 0000051126 0000051127 
0000051128 0000051129 0000051130 0000051131 

$ 

pa2-bad.dsk
Contains a bunch of programs that do bad things. A correct execution prints no error messages.
$ /e*/h*/c*/*5/Linux/bin/os2 -d /e*/h*/c*/*5/devices/pa2-badpgms.dsk

The system is halted.
Total execution time:  784 ticks, idle time:  177 ticks (22%).

$ 

pa2-ttycopy.dsk, pa2-ttycopy.tty
Contains a program that read and writes the terminal. A correct execution creates a results.tty file identical to pa2-ttycopy.tty.
$ /e*/h*/c*/*5/Linux/bin/os2 -d /e*/h*/c*/*5/devices/pa2-ttycopy.dsk -t /e*/h*/c*/*5/devices/pa2-ttycopy.tty

The system is halted.
Total execution time:  2752 ticks, idle time:  792 ticks (28%).

$ diff /e*/h*/c*/*5/devices/pa2-ttycopy.tty results.tty

$ 

If you're looking for a way to proceed, you might want to consider the following steps:

  1. Get your operating system to work with the diskio disk. This makes sure your operating system is managing the disk correctly. Once diskio works, then dio-checked, dio-shared, and 3dio should work too. Your operating system should be able to do at least this much.

  2. Make sure the badpgms disk works.

  3. Get the ttycopy disk to work. This makes sure your operating system is managing the terminal correctly.

  4. Make sure the pa1 disks still work correctly.


This page last modified on 25 June 2002.