Submit: Turn in your
entire xinu-hw7
directory
source files using the
turnin command on morbius.mscsnet.mu.edu or
one of the other
Systems Lab machines. Please run "make clean" in the
compile/ subdirectory just before submission to reduce
unnecessary space consumption.
Work should be completed in pairs. Be certain to include both names in the comment block at the top of all source code files, with a TA-BOT:MAILTO comment line including any addresses that should automatically receive results. It would be courteous to confirm with your partner when submitting the assignment.
You must understand classic semaphores before using them to implement this assignment. An implementation of classic semaphores with waiting queues has been provided for you, and can be found across several files including include/semaphore.h, system/semcreate.c, system/semfree.c, system/signal.c, system/signaln.c, and system/wait.c.
The implementation that is given to you is a broken implementation. It will work on a single core machine, but it will not work on a multicore machine. Part of your assignment is to fix the implementation so it will run correctly. Only a few simple modifications need to be done. There is a new file, system/atomic.S, which contains assembly methods that help with carrying out atomic operations such as incrementing and decrementing an integer.
You already have implemented a Synchronous Serial Driver for your operating system. Recall from Assignment 3: "The driver is synchronous because it waits for the slow I/O device to do its work, rather than using interrupts to communicate with the hardware."
Now, you will implement an Asynchronous Serial Driver (for an interrupt-driven UART) using semaphores across multiple cores. A proper asynchronous driver does not wait needlessly for the hardware, but instead only communicates with the UART when a hardware interrupt indicates to the system that it is ready for the next batch of work.
As discussed in lecture and lab, there are two parts to the asynchronous serial driver: the Lower Half and the Upper Half.
The Upper Half of the driver consists of the functions called by various user-level processes, such as getc(), putc(), and printf(). As much as possible, the upper half functions shield the user from the intricate details of the hardware.
The Lower Half of the driver consists of the handler functions run when hardware interrupt requests arrive. Lower half functions must do their work quickly, and deal with data that has been buffered up by the upper half functions.
The Lower half has been implemented for you in system/uarthandler.c. You will be working on the upper half functions in system/printf.c.
To implement your asynchronous driver, follow these steps:
[Revised 2020 Mar 04 10:57 DWB]