There are two objectives that is important in designing the management of I/O. The first one is efficiency and second is generality. Efficiency is important because I/O operations often form a bottleneck in a computing system. The second one is generality. In the interests of simplicity and freedom from error, it is desirable to handle all devices in a uniform manner. This applies to both the way in which processes view I/O devices and to the way in which the OS manages I/O devices and operations.
There are two types of I/O in UNIX, the buffered and unbuffered. Buffered I/O passes through system buffers, whereas unbuffered I/O typically involves the DMA facility, with the transfer taking place directly between the I/O module and the process I/O area. For buffered I/O, two types of buffers are used, system buffer caches and character queues.
In windows, I/O operations are layered. The I/O manager exports I/O system services, which user-mode protected subsystems call to carry out I/O operations on behalf of their applications and/or end users. The I/O manager intercepts these calls, sets up one or more IRPs, and routes them through possibly layered drivers to physical devices. The I/O manager defines a set of standard routines, some required and others optional, that drivers can support. All drivers follow a relatively consistent implementation model, given the differences among peripheral devices and the differing functionality required of bus, function, filter, and file system drivers. Like the operating system itself, drivers are object-based. Drivers, their devices, and system hardware are represented as objects. The I/O manager and other operating system components export kernel-mode support routines that drivers can call to get work done by manipulating the appropriate objects.