Chapter 29 Further Reading: Device I/O
Primary References
OSDev Wiki — Programmable Interval Timer https://wiki.osdev.org/Programmable_Interval_Timer Complete PIT documentation: mode descriptions, register formats, the exact timing formula, and mode-specific behavior. The "Reading the Current Count Value" section covers the latch command for sub-tick resolution. Also covers the PIT's relationship to the PC speaker (Channel 2) and legacy DRAM refresh (Channel 1, now irrelevant).
OSDev Wiki — Serial Ports https://wiki.osdev.org/Serial_Ports 16550 UART documentation covering register layout, initialization sequence, the self-test loopback mode, interrupt configuration, and FIFO operation. Includes the baud rate divisor table for all standard baud rates and the formula for unusual rates. The "Receiving Data" section covers interrupt-driven receive, which is important for production serial drivers.
OSDev Wiki — APIC https://wiki.osdev.org/APIC Local APIC (LAPIC) and I/O APIC documentation. Covers detection, enabling, the spurious interrupt vector, LAPIC timer calibration, and the ICR (Interrupt Command Register) for inter-processor interrupts. The APIC is the foundation of SMP interrupt handling in all modern x86 OS kernels.
Deep Dives
"How to Write a PCI Driver" — OSDev Wiki https://wiki.osdev.org/PCI PCI configuration space layout, BAR (Base Address Register) interpretation, capability lists, and bus/device/function enumeration algorithm. The section on MSI (Message Signaled Interrupts) explains how modern PCIe devices avoid the I/O APIC entirely, writing directly to memory to trigger an interrupt.
Intel 82579 Ethernet Controller Datasheet https://www.intel.com/content/www/us/en/products/docs/network-io/ethernet/network-adapters/82579-datasheet.html A representative example of a real MMIO device datasheet. The register descriptions show the complexity of a real device: hundreds of registers, detailed initialization sequences, interrupt management, DMA descriptor rings. Understanding one real device datasheet is worth more than reading three textbook device I/O chapters.
"Low-Level I/O on x86" — Linux Device Drivers (LDD3), Chapter 9
https://lwn.net/Kernel/LDD3/
Chapter 9 of Linux Device Drivers (3rd edition, available free online) covers I/O memory vs. I/O ports from the Linux kernel driver perspective. The ioremap() function maps physical MMIO addresses into kernel virtual space; readb()/writeb() provide the barrier semantics needed for correct device access. Understanding the Linux abstractions shows why the barriers matter.
Tools
QEMU Device Emulation
https://www.qemu.org/docs/master/system/invocation.html
QEMU emulates a wide range of real hardware: 8259A PIC, 8254 PIT, 16550 UART (via -serial), APIC, PCI bus, AHCI, RTL8139/E1000 network cards. Using QEMU to test bare-metal device drivers is faster and safer than testing on real hardware. The QEMU monitor (Ctrl+Alt+2) provides info irq, info pci, and xp commands for debugging device state.
lspci(8) — PCI Device Enumeration
https://man7.org/linux/man-pages/man8/lspci.8.html
On Linux, lspci -v shows all PCI devices with their vendor IDs, device IDs, BAR addresses, and IRQ assignments. lspci -vvv shows capability lists and interrupt vectors. Running this before testing your own PCI enumeration code lets you verify your results against a known-good implementation.
picocom and minicom — Serial Terminal Programs
https://github.com/npat-efault/picocom
https://www.man7.org/linux/man-pages/man1/minicom.1.html
Serial terminal programs for connecting to a real or virtual (QEMU PTY) serial port. Essential for testing serial drivers when using a real embedded board. picocom -b 115200 /dev/ttyUSB0 connects to a USB-to-UART adapter at 115200 baud.