What the Operating System Does

The great illusionist: every program believes it owns the whole machine
• Kernel
• Part 8 of 9
← Series index
The core job
The Illusionist
The OS gives every program three illusions: its own CPU (scheduling), its own memory (virtual memory), and simple devices (drivers and files). None of the three is true.
›
Illusion #1
Processes & Scheduling
Dozens of programs, a handful of cores. The scheduler slices time into ~ms quanta and swaps processes so fast that it looks parallel. It isn't — it's just fast.
›
Illusion #2
Virtual Memory
Every process sees the same clean address space starting at 0. Page tables plus the MMU translate to real DRAM — and keep processes from ever touching each other.
›
Illusion #3
Syscalls & Drivers
Hardware is messy and privileged. The kernel wraps it in ~350 clean system calls and speaks to devices through drivers and interrupts, so you can just write read().
Two real cores, four hopeful processes
RUNNING is the only row that is physically real. Everything else is bookkeeping the kernel keeps in RAM.
Core 0 idle
quantum —
Core 1 idle
quantum —
Timer chip — programmed to fire an interrupt every few milliseconds. This is the OS's grip on the machine: no matter what user code does, the kernel always gets the CPU back.
Ready queue runnable right now, waiting for a core
Blocked waiting on I/O — not runnable, not the scheduler's problem
Terminated called exit(); the kernel reclaims its memory
READY RUNNING BLOCKED dispatch preempt I/O wait device interrupt wakes it → back to Ready exit() → terminated
A process is never "a bit running". It is in exactly one of these states, and only the kernel may move it.
Fictional addresses, real DRAM
4 KB pages. A virtual address is just page number + offset; the page table says where that page really lives.
Process A — virtual address space
Process B has an identical-looking space, also starting at 0. Same numbers, different reality.
MMU · TLB · page table
MMU hardware, in the core
Idle. Every load and store in the machine passes through here.
virtual addr—
page number—
offset (12 b)—
physical addr—
VPN
maps to
V
perm
TLB — cache of recent translations
(empty)
idle
Physical DRAM — 12 page frames
Swap on disk — pages the kernel pushed out to make room. Slot 0x2A10 holds A's heap page VPN 5.
Process B just dereferenced a pointer that lands on frame 7 — a page owned by process A. B's page table contains no entry for it, so the MMU has no path to that frame at all. Trap → kernel → SIGSEGV. Isolation is not politeness; it is the absence of a mapping.
read(fd, buf, 4096) — the whole journey
Your process may not talk to the disk. It may only ask. Follow the dot across the privilege boundary.
User mode · ring 3unprivileged
Your programn = read(fd, buf, 4096)
libc wrapperrax=0 rdi=fd rsi=buf
privilege boundary — the only legal door
Kernel mode · ring 0can touch anything
Syscall table~350 entries → sys_read
VFS + page cachefd → inode → block
Schedulerblock / wake / dispatch
NVMe driversubmission queue + doorbell
DMA enginedevice → DRAM, no CPU
Interrupt handlercompletion IRQ
NVMe SSD~90 µs for a 4 KB read
DRAM · page cache pagewhere the 4096 bytes land
Why this boundary exists: the CPU refuses privileged instructions in ring 3. Not "the OS forbids it" — the silicon faults. That is why a buggy program can crash itself but not the machine.
Wall clock
0.000 ms
nothing dispatched yet
Context switches
0
~1–10 µs each, pure overhead
ProcessStateCPU time used
What a context switch actually costs: save every register into the kernel's task struct, load the next process's registers, swap the page-table root (CR3) and flush TLB entries, then run with cold caches until the new working set warms up. The bookkeeping is ~1–10 µs; the lost cache warmth often costs more.
TLB hits
0
translation ~free
TLB misses
0
walk the page table
Page faults
0
trap to the kernel
Faulting / accessed address—
Resolved frame—
Cost of this access—
Who is in controlprocess A (user mode)
The TLB is the whole trick. A page-table walk is 4 dependent DRAM reads on x86-64. The TLB caches the answer, so 99%+ of translations cost effectively nothing — the same locality bet the caches make in Part 3.
Elapsed
0 ns
before the call
Privilege
USER
ring 3
Where the dot isyour program
Your process stateRUNNING
Who owns the coreyour process
Bytes delivered0 / 4096
Forward reference → Part 9 This orchestration is exactly what HFT refuses to pay for. A tick-to-trade path polls the NIC from user space with kernel bypass — no syscall, no mode switch, no interrupt, no scheduler. It skips this entire diagram, and buys back several microseconds.

Scheduler trace

Step 0 / 0