Principles of Input-output software
Principles of Input-output software
• User Level Libraries − This provides simple interface to the user program to perform input and
output. For example, stdio is a library provided by C and C++ programming languages.
• Kernel Level Modules − This provides device driver to interact with the device controller and
device independent I/O modules used by the device drivers.
• Hardware − This layer includes actual hardware and hardware controller which interact with the
device drivers and makes hardware alive.
A key concept in the design of I/O software is that it should be device independent where it should be
possible to write programs that can access any I/O device without having to specify the device in advance.
For example, a program that reads a file as input should be able to read a file on a floppy disk, on a hard
disk, or on a CD-ROM, without having to modify the program for each different device.
Device Drivers
Device drivers are software modules that can be plugged into an OS to handle a particular device.
Operating System takes help from device drivers to handle all I/O devices. Device drivers encapsulate
device-dependent code and implement a standard interface in such a way that code contains device-
specific register reads/writes. Device driver, is generally written by the device's manufacturer and
delivered along with the device on a CD-ROM.
• Interact with the device controller to take and give I/O and perform required error handling
Suppose a request comes to read a block N. If the driver is idle at the time a request arrives, it starts
carrying out the request immediately. Otherwise, if the driver is already busy with some other request, it
places the new request in the queue of pending requests.
The basic function of the device-independent software is to perform the I/O functions that are common
to all devices and to provide a uniform interface to the user-level software. Though it is difficult to write
completely device independent software but we can write some modules which are common among all
the devices. Following is a list of functions of device-independent I/O Software −
• Device naming - Mnemonic names mapped to Major and Minor device numbers
• Device protection
• Buffering because data coming off a device cannot be stored in final destination.
• Error Reporting
These are the libraries which provide richer and simplified interface to access the functionality of the
kernel or ultimately interactive with the device drivers. Most of the user-level I/O software consists of
library procedures with some exception like spooling system which is a way of dealing with dedicated I/O
devices in a multiprogramming system.
I/O Libraries (e.g., stdio) are in user-space to provide an interface to the OS resident device-independent
I/O SW. For example putchar(), getchar(), printf() and scanf() are example of user level I/O library stdio
available in C programming.
Kernel I/O Subsystem
Kernel I/O Subsystem is responsible to provide many services related to I/O. Some of the services provided
by kernel i/o subsystem are:
• Scheduling − Kernel schedules a set of I/O requests to determine a good order in which to execute
them. When an application issues a blocking I/O system call, the request is placed on the queue
for that device. The Kernel I/O scheduler rearranges the order of the queue to improve the overall
system efficiency and the average response time experienced by the applications.
• Buffering − Kernel I/O Subsystem maintains a memory area known as buffer that stores data while
they are transferred between two devices or between a device with an application operation.
Buffering is done to cope with a speed mismatch between the producer and consumer of a data
stream or to adapt between devices that have different data transfer sizes.
• Caching − Kernel maintains cache memory which is region of fast memory that holds copies of
data. Access to the cached copy is more efficient than access to the original.
• Spooling and Device Reservation − A spool is a buffer that holds output for a device, such as a
printer, that cannot accept interleaved data streams. The spooling system copies the queued spool
files to the printer one at a time. In some operating systems, spooling is managed by a system
daemon process. In other operating systems, it is handled by a kernel thread.
• Error Handling − An operating system that uses protected memory can guard against many kinds
of hardware and application errors.
• Device independence
• Uniform naming
• Error handling
• Buffering
Device independence
• It should be possible to write programs that can access any I/O device without having to specify
the device in advance.
Uniform naming
• Uniform naming: The name of a file or a device should simply be a string or an integer and not
depend on the device in any way.
Error handling
• Only if the lower layers are not able to deal with the problem should the upper layers be told
about it.
• Most physical I/O is asynchronous, the CPU starts the transfer and goes off to do something else
until the interrupt arrives.
• User programs are much easier to write if the I/O operations are blocking after a receive system
call the program is automatically suspended until the data are available in the buffer.
• It is up to the operating system to make operations that are actually interrupt-driven look blocking
to the user programs.
Buffering
• Often data that come off a device cannot be stored directly in its final destination.
• For example, when a packet comes in off the network, the operating system does not know where
to put it until it has stored the packet somewhere and examined it.
Interrupt Handlers
• The best way to hide Interrupts is to have the driver starting an I/O operation block until the I/O
has completed and the interrupt occurs. The driver can block itself by doing a down on a
semaphore, a wait on a condition variable, a receive on a message, or something similar, for
example.
Device Drivers
• Each I/O device attached to a computer needs some device-specific code for controlling it.
• This code, called the device driver, is generally written by the device's manufacturer and delivered
along with the device on a CD-ROM.
• Since each operating system needs its own drivers, device manufacturers commonly supply drivers
for several popular operating systems.
• As we mentioned earlier, operating systems usually classify drivers as block devices, such as disks,
or character devices, such as keyboards and printers.
• Most operating systems define a standard interface that all block drivers must support and a
second standard interface that all character drivers must support.
• These interfaces consist of a number of procedures that the rest of the operating system can call
to get the driver to do work for it.
• Although some of the I/O software is device specific, a large fraction of it is device independent.
• A major issue in an operating system is how to make all I/O devices and drivers look more-or-less
the same.
• If disks, printers, monitors, keyboards, etc., are all interfaced in different ways, every time a new
peripheral device comes along, the operating system must be modified for the new device.
• With a standard interface it is much easier to plug in a new driver, providing it conforms to the
driver interface. It also means that driver writers know what is expected of them.
• (a) Without a Standard Driver Interface.
(b) With a Standard Driver Interface.
Buffering
• For block devices, the hardware generally insists upon reading and writing entire blocks
at once, but user processes are free to read and write in arbitrary units. If a user process
writes half a block, the operating system will normally keep the data around internally
until the rest of the data are written, at which time the block can go out to the disk.
• For character devices, users can write data to the system faster than it can be output,
necessitating buffering. Keyboard input that arrives before it is needed also requires
buffering.
Error Reporting
• Errors are far more common in the context of I/O than in any other context. When they occur, the
operating system must handle them as best it can. Many errors are device-specific, so only the
driver knows what to do (e.g., retry, ignore, or panic).
• A typical error is caused by a disk block that has been damaged and cannot be read any more.
After the driver has tried to read the lock a certain number of times, it gives up and informs the
device-independent software. How the error is treated from here on is device independent. If the
error occurred while reading a user file, it may be sufficient to report the error back to the caller.
• Some devices, such as CD-ROM recorders, can be used only by a single process at any given
moment. It is up to the operating system to examine requests for device usage and accept or reject
them, depending on whether the requested device is available or not. A simple way to handle
these requests is to require processes to perform opens on the special files for devices directly. If
the device is unavailable, the open fails. Closing such a dedicated device then releases it.
• Not all disks have the same sector size. It is up to the device-independent software to hide this
fact and provide a uniform block size to higher layers, for example, by treating several sectors as a
single logical block. In this way, the higher layers only deal with abstract devices that all use the
same logical block size, independent of the physical sector size. Similarly, some character devices
deliver their data one byte at a time (e.g., modems), while others deliver theirs in larger units (e.g.,
network interfaces). These differences may also be hidden.
The arrows show the flow of control. When a user program tries to read a block from a file, for example,
the operating system is invoked to carry out the call. The device-independent software looks for it in the
buffer cache, for example. If the needed block is not there, it calls the device driver to issue the request to
the hardware to go get it from the disk. The process is then blocked until the disk operation has been
completed.