Skip to content

Drivers

kazah-png edited this page Aug 25, 2026 · 7 revisions

Drivers

Every device driver is compiled into the kernel — there is no module loading. All of them live in kernel/.

See also: Architecture, Networking-Stack, GUI-Subsystem, Filesystem, SMP

Interrupt controllers

APIC (apic.c)

Local APIC at 0xFEE00000, I/O APIC at 0xFEC00000 with 24 redirection entries, and ISA IRQ override handling.

The PIT arrives on I/O APIC pin 2, not pin 0 — QEMU's ACPI interrupt-source override remaps ISA IRQ 0. Unmasking pin 0 is a no-op, which is why the timer appeared dead for several releases.

The legacy PIC is fully masked once the APIC is active.

Input

Keyboard (keyboard.c)

PS/2 on IRQ 1, feeding a circular buffer. US and Spanish layouts with AltGr; Set-2 scancodes.

  • Ctrl-A…Ctrl-Z map to control bytes 0x010x1A for editor bindings
  • Ctrl-C raises SIGINT and Ctrl-Z raises SIGTSTP against the terminal foreground process
  • Two stdin disciplines: TTY_CANON (echoed, backspace-edited lines) and TTY_RAW (byte-at-a-time, arrows as ANSI escapes) — see ttymode in Syscalls
  • A separate raw key-event ring delivers press and release with Set-1 scancodes, for fullscreen games (getkeyevent)
  • The input path is spinlock-protected for SMP safety

The E0-prefix check once ran after the press-bit mask, so extended keys — every arrow, Home, End, PgUp, PgDn — never worked anywhere in the system. Worth remembering when a key seems inert.

layout <us|es> switches keymap at runtime.

Mouse (mouse.c)

PS/2 on IRQ 12. Three-byte packets, relative movement, roughly 4 counts/mm, plus wheel events used by the terminal scrollback.

Timers

PIT (timer.c)

Channel 0 at 1000 Hz, delivered via I/O APIC pin 2 to vector 32. It drives tick_count, the scheduler quantum, and the sleep wait queue.

Local APIC timer (smp.c)

Each application processor runs its own periodic LAPIC timer on a dedicated vector — a real context-switching ISR feeding that core's scheduler. The reload value is deliberately uncalibrated: calibration needs a reference clock the APs do not have, since the PIT belongs to the BSP. Under QEMU, divide-by-16 with 62500 counts gives roughly 500 Hz per AP; real hardware will differ.

RTC (rtc.c)

CMOS ports 0x70/0x71, BCD decoded. Backs the date command, SYS_TIME, gettimeofday, and X.509 certificate validity checks.

Storage

ATA (ata.c)

PIO mode on the primary channel (0x1F0), IRQ 14, 28-bit LBA (up to 128 GB), polled I/O. This is what the EXT2 driver sits on — see Filesystem. The write-cache flush is batched per operation (v6.4.256), which took a 4 MB write from ~120 s to ~0.4 s.

NVMe (nvme.c)

A from-scratch NVMe block driver (kernel/drivers/misc/nvme.c) added for real-hardware disks (v6.4.258–276): PCIe discovery via lspci, BAR mapping (map_mmio_range), controller reset/enable, an admin queue with IDENTIFY, an I/O submission/completion queue pair, and block read/write with PRP-list batching for multi-block transfers. For real SSDs it flushes the write cache, can run write-through (disable the volatile write cache), and sets FUA on every write so installs survive power-off. A blockdev layer routes I/O to ATA or the NVMe namespace (n0); disks/lsblk list it. This is the disk the in-OS installer targets — see Installation.

Display

VBE (vbe.c)

Bochs VBE extensions with a custom CRTC, up to 1024×768×32, linear framebuffer at 0xE0000000. Runtime mode changes via setres / mode.

Audio

Sound Blaster 16 (sb16.c)

I/O port 0x220, IRQ 5, DMA channel 1. 8-bit PCM in auto-init mode with mixer control. sb16play [freq] [ms] from the shell; the Sound Test app exposes sine, square and sweep.

Under QEMU: -audiodev dsound,id=audio0 -device sb16,audiodev=audio0 (which run.ps1 -Sound adds).

wav plays a RIFF/WAV file through the SB16 (v6.4.321).

AC'97 (ac97.c)

A PCI AC'97 audio driver (v6.4.359–361): PCI probe + detection, codec bring-up (reset, ready-wait, vendor id, volume, 44.1 kHz), and BDL/DMA PCM playback through the bus-master engine — a 440 Hz tone plays end to end. This is the modern-audio path alongside the legacy SB16; from v6.4.362 wav plays through AC'97 when present and falls back to SB16.

PC speaker (speaker.c)

PIT channel 2 square wave. beep() and play_melody(), exposed as the beep and play commands.

Network

RTL8139 (rtl8139.c)

PCI NIC with I/O and MMIO BARs, 4 TX descriptors, a circular RX ring, 10/100 Mbps, link detection. Full detail in Networking-Stack.

Interrupt map

IRQ Vector Device
0 (I/O APIC pin 2) 32 PIT timer
1 33 PS/2 keyboard
5 37 Sound Blaster 16
12 44 PS/2 mouse
14 46 ATA primary (polled in practice)
0x41 TLB shootdown IPI (SMP)
per-CPU AP LAPIC timer, AP spurious

See also

External resources

Clone this wiki locally