Skip to main content

Device Management and I/O Systems

Learning Objectives

By the end of this page, you should be able to:

  • Explain how I/O hardware (controllers, ports, registers) communicates with the CPU.
  • Compare polling and interrupt-driven I/O, and explain when each is preferable.
  • Describe how Direct Memory Access (DMA) reduces CPU overhead during large transfers.
  • Trace the path of an I/O request from an application through the OS to the physical device.
  • Compute and compare total head movement for FCFS, SSTF, SCAN, C-SCAN, and LOOK disk scheduling on a given request sequence.
  • Explain the purpose of spooling and buffering, and give real-world examples of each.

Quick Answer

Device management is how an operating system controls hardware (disks, printers, network cards, keyboards) through a layered stack: device controllers talk to raw hardware, device drivers give the kernel a uniform interface to those controllers, and the I/O subsystem coordinates requests using interrupts, DMA, buffering, and scheduling. It matters because devices are thousands of times slower than the CPU — without careful management (letting the CPU do other work during I/O waits, batching disk requests to minimize seek time, buffering to smooth speed mismatches), a system would waste enormous CPU time and disk requests would be served inefficiently. Disk scheduling algorithms (FCFS, SSTF, SCAN, C-SCAN, LOOK) are the classic exam topic here: they decide the order in which pending disk track requests are serviced to minimize total head movement while balancing fairness and avoiding starvation.

I/O Hardware: Controllers, Ports, and Registers

Every device the OS talks to has a device controller — a small piece of electronics (sometimes with its own processor and firmware) that manages a specific type of device. The CPU never talks to the physical mechanism of a disk directly; it talks to the disk controller through a well-defined set of registers:

  • Status register — tells the CPU whether the device is busy, ready, or has an error.
  • Command register — the CPU writes commands here (e.g., "read block 42").
  • Data register — data is transferred one word/byte at a time through this register (in programmed I/O), or the controller uses DMA to write directly to memory.

On Linux, this abstraction shows up as device files under /dev/dev/sda for a disk, /dev/tty for a terminal, /dev/null for the discard device. Reading or writing these files funnels through the kernel's I/O subsystem to the actual controller; user programs never see registers directly.

Polling vs. Interrupt-Driven I/O

There are two fundamental ways the CPU finds out that a device is ready:

Polling (busy-waiting). The CPU repeatedly reads the device's status register in a loop until it reports "ready," then transfers the data. This is simple but wastes CPU cycles spinning — fine for very fast devices where the wait is a few cycles, wasteful for slow ones like a keyboard or disk.

Interrupt-driven I/O. The CPU issues a command to the device and moves on to other work. When the device finishes, it raises a hardware interrupt, which causes the CPU to save its current state, jump to an interrupt service routine (ISR) registered for that device, handle the completed I/O, and then resume the interrupted process. Linux registers ISRs via request_irq(); when a keystroke or disk completion fires an IRQ line, the corresponding driver's handler runs, often deferring heavier work to a "bottom half" (tasklet/softirq) so the ISR itself stays fast.

Trade-off: polling has zero interrupt overhead but wastes CPU time; interrupts free the CPU for other work but each interrupt carries context-switch overhead. High-frequency devices (10 Gbps network cards) sometimes switch back to polling under heavy load (Linux's NAPI mechanism) because interrupt overhead at that rate would overwhelm the CPU — a good example of the trade-off going the other way at scale.

Direct Memory Access (DMA)

Even interrupt-driven I/O still routes every byte through the CPU in programmed I/O — costly for large transfers like reading a multi-megabyte file. DMA solves this: the CPU programs a DMA controller with a source address, destination address, and byte count, then continues other work. The DMA controller moves the entire block directly between the device and main memory over the bus, and raises a single interrupt only when the whole transfer is complete.

Concretely: copying a 10 MB file from disk without DMA would mean the CPU services one interrupt (or polls) per word transferred — potentially millions of interrupts. With DMA, the disk controller streams the data straight into a memory buffer, and the CPU gets exactly one "transfer complete" interrupt. This is why real disk and network controllers are DMA-capable; software-emulated devices (like an old-style PS/2 keyboard) are not, because their transfer volumes are tiny.

Device Drivers

A device driver is the software layer that translates the OS's generic I/O calls (read(), write(), ioctl()) into the specific command sequences a particular controller understands. Drivers give the kernel hardware abstraction: application code that calls read() on /dev/sda1 doesn't need to know whether the underlying disk is SATA, NVMe, or a USB flash drive — the driver hides those differences behind a common block-device interface.

Key driver responsibilities:

  • Hardware abstraction — uniform interface regardless of vendor/model.
  • Resource allocation — claiming IRQ lines, I/O ports, and DMA channels.
  • Interrupt handling — registering and servicing the device's interrupts.
  • Data transfer protocols — implementing the specific command/response sequence the controller expects.

The I/O Request Path

When an application calls read() on a file, the request passes through several layers before it reaches the physical disk and the data flows back up:

Each layer adds value: the file system translates a filename/offset into physical block numbers; the buffer cache may already have the data, avoiding a disk trip entirely; the I/O scheduler decides when and in what order to service pending disk requests; the driver issues the low-level commands; and the controller operates the physical device. The completion interrupt travels back up the same stack, waking the process that was blocked on the read.

I/O Scheduling: Disk Scheduling Algorithms

Because a mechanical disk's read/write head must physically move across tracks, and seek time dominates disk latency, the order in which pending requests are served has a huge effect on performance. The OS maintains a queue of pending track requests and applies a scheduling algorithm to decide service order. (Note: on SSDs seek time is irrelevant since there's no moving head, but these algorithms remain a core exam topic and still matter for spinning disks and some queuing-fairness scenarios.)

FCFS (First-Come, First-Served). Requests are served strictly in arrival order. Simple and fair, but can cause the head to swing wildly across the disk, producing poor average seek time.

SSTF (Shortest Seek Time First). Always service the pending request closest to the current head position. Minimizes seek time locally but can starve requests far from the current cluster of activity if closer requests keep arriving.

SCAN (the "elevator" algorithm). The head sweeps in one direction (say, toward the highest track number), servicing every request it passes, until it reaches the end of the disk, then reverses direction and sweeps back. Behaves like an elevator — no starvation, and more predictable than SSTF.

C-SCAN (Circular SCAN). Like SCAN, but the head only services requests while moving in one direction. When it reaches the end, it jumps immediately back to the beginning (without servicing on the return trip) and starts sweeping again. This gives a more uniform wait time across all tracks, because tracks aren't serviced twice as densely near the reversal point (a bias SCAN has).

LOOK. A practical refinement of SCAN: instead of going all the way to the physical end of the disk, the head reverses as soon as there are no more requests in the current direction. C-LOOK applies the same "don't go further than needed" fix to C-SCAN.

Worked Example: Comparing SCAN and SSTF

Disk has 200 tracks (0–199). Head is currently at track 53. Pending request queue (in arrival order): 98, 183, 37, 122, 14, 124, 65, 67.

SSTF: From 53, always jump to the closest remaining request.

53 → 65 (11) → 67 (2) → 37 (30) → 14 (23) → 98 (84) → 122 (24) → 124 (2) → 183 (59)

Total head movement = 11+2+30+23+84+24+2+59 = 235 tracks

SCAN (moving toward higher track numbers first, sweeping to track 199 then reversing): sorted requests are 14, 37, 65, 67, 98, 122, 124, 183.

53 → 65 (12) → 67 (2) → 98 (31) → 122 (24) → 124 (2) → 183 (59) → 199 (16, end of disk) → 37 (162) → 14 (23)

Total head movement = 12+2+31+24+2+59+16+162+23 = 331 tracks

At first glance SSTF looks like the clear winner here, and locally it is — but note it starved the far-side requests (14, 37) until the very end, and in a live system with continuously arriving requests near 53–124, SSTF could delay them indefinitely. SCAN guarantees every request is serviced within one sweep, trading some extra head movement for fairness. LOOK would improve on SCAN here: it stops sweeping at 183 (the last request in that direction) rather than continuing to track 199, saving 16 tracks of wasted movement — Total = 331 − 16 = 315 tracks.

Spooling and Buffering

Buffering temporarily holds data in memory to smooth out speed mismatches between a fast producer and a slow consumer (or vice versa). A buffer cache for disk I/O keeps recently read blocks in RAM so repeated reads don't hit the disk again; double buffering lets a device fill one buffer while the CPU processes the other, overlapping I/O and computation.

Spooling (Simultaneous Peripheral Operations On-Line) is a specific application of buffering for devices that can't support interleaved access from multiple processes, most classically printers. Instead of a process holding exclusive access to the printer while it prints, the OS writes the output to a disk spool (queue), and a separate spooler process feeds jobs to the printer one at a time. This is why multiple users can "print" concurrently on a shared network printer without conflict — each job lands in the spool and is dispatched in order.

Key Terms

TermDefinitionContext/Related
Device ControllerHardware component that operates a specific device and exposes status/command/data registers to the CPUSits between CPU and physical device
Device DriverOS software that translates generic I/O calls into device-specific commandsProvides hardware abstraction
InterruptA signal from hardware that pauses normal CPU execution to run an interrupt service routineAlternative to polling
DMA (Direct Memory Access)A mechanism allowing a device to transfer data directly to/from memory without CPU involvement per byteReduces CPU overhead for large transfers
PollingCPU repeatedly checks a device's status register until readySimple but can waste CPU cycles
I/O SchedulingDeciding the order in which pending I/O (typically disk) requests are servicedFCFS, SSTF, SCAN, C-SCAN, LOOK
Seek TimeTime for the disk head to move to the required trackDominant cost in disk scheduling
StarvationA request waits indefinitely because other requests keep being prioritized ahead of itRisk in SSTF
SpoolingBuffering output (e.g., print jobs) on disk so multiple processes can share a device without conflictClassic printer example
BufferingTemporarily storing data in memory to smooth speed differences between producer and consumerBuffer cache, double buffering
/dev filesSpecial files in Unix/Linux representing device interfaces/dev/sda, /dev/tty, /dev/null

Common Mistakes

  1. Misconception: DMA eliminates interrupts entirely. Why it's wrong: DMA still generates an interrupt — just one interrupt for the entire block transfer instead of one per word/byte. Correct explanation: DMA reduces interrupt frequency and removes the CPU from the per-byte data path; the CPU still gets notified once when the whole transfer completes.

  2. Misconception: SSTF is always the best disk scheduling algorithm because it minimizes seek time. Why it's wrong: SSTF only minimizes local, greedy seek time and can starve requests that are geographically far from the current cluster of activity if nearer requests keep arriving. Correct explanation: SCAN, C-SCAN, and LOOK sacrifice some average seek time for bounded wait times and no starvation, which is why real systems favor elevator-style algorithms over pure SSTF for continuous workloads.

  3. Misconception: Disk scheduling algorithms like SCAN/SSTF matter equally for SSDs. Why it's wrong: SSDs have no mechanical read/write head and no seek time in the mechanical sense — access latency is roughly uniform across the device. Correct explanation: These algorithms are essential for HDDs where seek time dominates; SSD-oriented schedulers instead focus on wear leveling, queue depth, and parallelism across flash channels, though exam questions still test SCAN/SSTF as a scheduling-theory topic.

Comparison and Connections

AlgorithmHow It WorksAvg. Seek TimeStarvation RiskFairnessTypical Use Case
FCFSServes requests in arrival orderHigh (no optimization)NonePerfectly fairLight/simple workloads, simplicity valued over speed
SSTFAlways serves nearest request firstLow (locally optimal)HighPoor for far requestsLight, bursty workloads with few concurrent requests
SCANSweeps across disk in one direction, then reverses (elevator)ModerateNoneGood, slight bias toward middle tracksGeneral-purpose disk scheduling
C-SCANSweeps one direction only, jumps back to startModerate (extra jump cost)NoneVery uniform wait timesSystems needing predictable, uniform response
LOOKLike SCAN but reverses at last request, not disk edgeSlightly better than SCANNoneGoodPractical improvement over SCAN in real OS implementations

Practice Questions

Recall

  1. What are the three types of registers typically found in a device controller? Answer guidance: Status register (device state), command register (CPU issues commands), data register (byte/word transfer channel).

  2. Define spooling and give one real-world example. Answer guidance: Spooling writes output to a disk queue so a device that can't be shared directly (e.g., printer) can serve multiple processes in sequence; classic example is a shared network printer queue.

Understanding

  1. Explain why interrupt-driven I/O is generally more efficient than polling for slow devices, but why very high-speed devices sometimes revert to polling. Answer guidance: Interrupts let the CPU do useful work instead of busy-waiting for slow devices; but at very high event rates (e.g., 10 Gbps NICs) the overhead of servicing one interrupt per event exceeds the cost of periodically checking status, so polling (e.g., Linux NAPI) becomes more efficient.

  2. Why does C-SCAN provide more uniform wait times than plain SCAN? Answer guidance: SCAN services tracks near the reversal point twice as frequently as tracks at the far end, biasing service. C-SCAN only services in one direction and jumps back without servicing on return, spreading wait times evenly across all tracks.

Application

  1. A disk has 200 tracks (0–199). The head is at track 50. Pending requests in arrival order: 70, 20, 150, 10, 180. Compute total head movement using FCFS. Answer guidance: 50→70 (20) →20 (50) →150 (130) →10 (140) →180 (170) = 20+50+130+140+170 = 510 tracks.

  2. Using the same queue (head at 50; requests 70, 20, 150, 10, 180, disk 0–199), compute total head movement using SSTF. Answer guidance: 50→70(20)→150? nearest to 70 is actually... check distances from 70: 20(50),150(80),10(60),180(110)→ nearest is 20(50). Continue: from 20, remaining 150,10,180: nearest is 10(10). From 10: remaining 150,180: nearest 150(140). From 150: remaining 180(30). Total = 20+50+10+140+30 = 250 tracks — much better than FCFS's 510.

Analysis

  1. Compare SCAN and LOOK for the same request queue and explain under what condition their total head movement becomes identical. Answer guidance: They become identical when the outermost pending request coincides with the physical edge of the disk (no "wasted" travel to the edge exists in that direction), since LOOK's only saving is skipping the empty stretch between the last request and the disk boundary.

  2. A system experiences occasional very long delays for requests to low-numbered tracks even though overall throughput is high. Which scheduling algorithm is most likely in use, and how would you fix it? Answer guidance: Likely SSTF, since it can indefinitely deprioritize far-away requests when a cluster of nearer requests keeps arriving. Switching to SCAN, C-SCAN, or LOOK bounds the maximum wait since every request is guaranteed service within one sweep.

FAQ

Q: Why can't the CPU just talk to the disk platters directly instead of going through a controller? A: Physical disk mechanics (motor speed, head positioning, encoding/decoding bits from magnetic flux) are far too detailed and timing-sensitive for the CPU to manage cycle-by-cycle. The controller hides that complexity behind a simple register-based command interface, letting the CPU issue high-level commands like "read block N."

Q: Is DMA available for all devices? A: No — only devices with sufficiently high data volume to justify the extra hardware (disks, network cards, graphics cards) typically have DMA-capable controllers. Low-bandwidth devices like keyboards and mice use simple interrupt-driven or polled I/O since per-byte CPU overhead is negligible at their data rates.

Q: Why do modern OS textbooks still emphasize disk scheduling if most systems now use SSDs? A: Two reasons: many production and legacy systems (enterprise storage, some servers) still use HDDs where seek time matters enormously, and the scheduling theory (fairness vs. optimality, starvation avoidance) generalizes to other resource-scheduling problems, including I/O queue management on SSDs and network packet scheduling.

Q: What's the practical difference between SCAN and the elevator in a building? A: They work almost identically — the disk head, like an elevator car, moves in one direction servicing requests along the way and only reverses when it reaches the end (or, for LOOK, the last request). That's exactly why SCAN is nicknamed the "elevator algorithm."

Q: How does buffering differ from caching? A: Buffering primarily smooths a speed or timing mismatch between two sides of a data transfer (e.g., holding data while a slow printer catches up); caching primarily avoids redundant work by keeping a copy of data likely to be reused. In practice the disk buffer cache does both jobs at once, which is why the terms are often used together.

Quick Revision

  • I/O hardware = device controller (status/command/data registers) + physical device; CPU never touches raw hardware directly.
  • Polling wastes CPU cycles busy-waiting; interrupts free the CPU but add per-event overhead — high-speed devices may revert to polling (e.g., NAPI).
  • DMA lets a device transfer whole blocks directly to/from memory, generating just one interrupt per transfer instead of one per byte.
  • Device drivers provide hardware abstraction, handle resource allocation (IRQs, ports, DMA channels), and manage interrupts/data protocols.
  • I/O request path: application → system call → file system/buffer cache → I/O scheduler → device driver → controller → device.
  • FCFS: fair but can cause long, inefficient head swings; no starvation but poor average seek time.
  • SSTF: minimizes local seek time but risks starving far-away requests.
  • SCAN ("elevator"): sweeps end-to-end, reverses; no starvation, slight bias toward middle tracks.
  • C-SCAN: services in one direction only, jumps back to start; more uniform wait times than SCAN.
  • LOOK/C-LOOK: like SCAN/C-SCAN but reverses at the last request instead of the disk edge, saving wasted movement.
  • Worked example: head at 53, requests 98,183,37,122,14,124,65,67 — SSTF total = 235 tracks; SCAN = 331 tracks; LOOK = 315 tracks.
  • Spooling lets multiple processes share a non-interleavable device (like a printer) by queuing jobs on disk; buffering smooths producer/consumer speed mismatches.

Prerequisites: File Systems, Process Management, Memory Management

Related Topics: Interrupts and Interrupt Handling, Storage Devices and Architecture, Kernel I/O Subsystem Design

Next Topics: Deadlocks and Synchronization, Virtual Memory Management