Goal
Understand what happens below your code — how the hardware executes instructions, how the OS manages processes and memory, and why systems behave unexpectedly under load or failure. This path closes the gap between writing a program and understanding what it actually does.
Who this is for
Developers who work in systems-adjacent areas — backend, infrastructure, tooling — and want to stop treating the OS and hardware as a black box. Also essential for anyone debugging subtle performance issues or writing concurrent code.
Prerequisites
- Comfortable writing C or willing to learn the basics alongside reading
- Has written programs that deal with files, processes, or threads, even if only at a high level
- No prior systems knowledge required
Reading order
1. Computer Systems: A Programmer’s Perspective — Bryant & O’Hallaron
Start here. CS:APP builds the complete picture from binary representation up through processes, virtual memory, and network I/O. It is the most important book on this path.
Do the labs. The bomblab (reverse engineering), attacklab (stack exploits), and malloclab (memory allocator) each teach something that no amount of reading alone can replicate. If you skip the labs, you are reading half a book.
Read Chapters 1–9 in order. Chapter 10 (system-level I/O) and Chapters 11–12 (networking and concurrency) can be read selectively based on what you need next.
Expect this to take longer than you plan. Chapter 3 (assembly) alone warrants a slow read with a debugger open.
2. Operating Systems: Three Easy Pieces — Arpaci-Dusseau
Read after CS:APP. OSTEP goes deeper into the OS layer that CS:APP introduces. Where CS:APP gives you the programmer’s view of processes and memory, OSTEP gives you the OS designer’s view.
Part 1 (Virtualization) covers processes and virtual memory in detail — reinforces CS:APP and adds scheduling. Part 2 (Concurrency) is one of the best treatments of locks, condition variables, and semaphores available. Part 3 (Persistence) covers file systems and I/O and is useful context for understanding how databases store data.
Read the source code of xv6 alongside Part 3. It is a small, readable Unix implementation that makes the file system and process management concepts concrete.
OSTEP is free at ostep.org. Print or download the chapters you are actively reading.
Optional books
- The Linux Programming Interface by Michael Kerrisk — the definitive reference for Linux system calls. Not a book to read cover to cover, but invaluable as a reference when writing systems code or reading OSTEP and wondering what the actual Linux API looks like.
- Computer Networking: A Top-Down Approach by Kurose & Ross — if CS:APP Chapter 11 leaves you wanting more on networking. Covers HTTP, TCP, IP, and routing from the application layer down. Good companion if you work on networked systems.
- Systems Performance by Brendan Gregg — read after the main path if you work on performance tuning. Covers CPU, memory, disk, and network performance with Linux tools. Dense and practical.
Practice ideas
- CS:APP labs are non-negotiable. Start with datalab and bomblab before moving to OSTEP.
- After OSTEP Part 1: implement a simple round-robin scheduler in a language you know. Simulate process queues and context switches.
- After OSTEP Part 2: implement a thread-safe bounded buffer using mutexes and condition variables. Test it with multiple producers and consumers.
- After OSTEP Part 3: read the source of a simple file system implementation (xv6 or littlefs). Map each concept from the book to actual code.
Expected outcome
After completing this path, you should be able to:
- Read a memory layout diagram and understand what each region is used for
- Explain virtual memory, page tables, and TLB misses without looking them up
- Debug a race condition using the mental model of interleavings and shared state
- Read strace or perf output and understand what the OS is doing on behalf of your program
- Reason about file system behavior — what happens on a crash, what fsync does, why write ordering matters