Computer Systems from First Principles
A guided bridge from bits and instructions to memory, processes, operating systems, and the hardware-software boundary.
Start with state and transitions
A computer is not magic and it is not merely a fast calculator. It is a machine whose stored state changes on clocked boundaries according to instructions. The course begins with binary representation, logic, registers, and a program counter. Each later abstraction is tied back to concrete state, addresses, and events so that software behavior can be explained from the hardware upward.
Follow one instruction completely
Fetching identifies an instruction address, decoding determines required operands and control actions, execution performs arithmetic or address generation, memory access moves data when required, and retirement makes results architecturally visible. The interactive traces show what changes and what must remain unchanged. This makes bugs involving stale state, wrong addresses, and ordering constraints easier to diagnose.
Build the memory hierarchy
Registers are small and immediate, caches exploit locality, main memory provides capacity, and storage provides persistence. Virtual memory adds translation, permissions, isolation, and demand paging. The important skill is not memorizing a pyramid. It is predicting where a value lives, how an address is interpreted, who owns a cache line, and what latency or fault can occur next.
Connect hardware to an operating system
Privilege levels, exceptions, interrupts, timers, and system calls allow an operating system to share hardware safely. The labs connect these mechanisms to embedded firmware and Linux rather than treating them as separate subjects. Mastery means being able to narrate a real event, such as a UART interrupt or page fault, from electrical arrival through software handling and return.
What you will be able to do
- Trace a program from source code to machine execution
- Distinguish registers, caches, RAM, storage, and virtual memory
- Explain privilege, interrupts, exceptions, and system calls
- Reason about performance using latency, throughput, locality, and contention
What a computer actually is
A computer is a system that accepts information, transforms it according to stored instructions, keeps information for later, and communicates results. CPU, memory, storage, and I/O are roles in that system—not a list of unrelated products.
Information enters through input devices or sensors. The processor applies instructions. Working state sits close enough to the processor to be accessed repeatedly. Persistent state survives power loss. Output devices, actuators, displays, and networks expose the result. The same model describes a laptop, a server, and a tiny microcontroller board.
A component can serve more than one role. A network adapter is both input and output; a GPU is a specialized processor with its own memory; an SSD contains processors, RAM, firmware, and flash media inside the storage device. Roles are therefore more reliable than judging a device by its shape.
A system is also a set of contracts. Hardware defines electrical and protocol contracts, firmware initializes devices, drivers translate operating-system requests, and applications ask the OS for services. Debugging becomes easier when you name the layer that failed.
Vocabulary
- Input
- Information entering the system: keys, packets, sensor voltages, files, or commands.
- Processing
- Applying instructions or logic to transform state.
- Working memory
- Fast storage for code and data currently being used.
- Persistent storage
- State designed to remain after power is removed.
- Output
- Information or physical action produced by the system.
Opening a photograph
- The SSD preserves the encoded image while power is off.
- The OS asks a storage driver to read blocks into RAM.
- The CPU decodes the file; the GPU may render the pixels.
- Display hardware sends the final frame to the panel.
One click crosses storage, memory, processing, software, and output layers.
Common mistakes
- A computer is not only the CPU.
- Memory and storage are not interchangeable just because both hold bits.
- A faster component cannot help if another layer is the bottleneck.
Once the four roles are clear, every new term has a home: a CPU transforms, RAM holds active state, an SSD preserves state, and PCIe moves information between components.
From electricity to bits and clocks
Digital circuits map voltage ranges to logic states. Transistors form gates, gates form state and arithmetic circuits, and a clock coordinates many state changes. A bit is a logical distinction, not a tiny physical box containing the number 0 or 1.
Real voltage is continuous and noisy. A digital input interprets one range as low and another as high, with invalid or transition regions between. Noise margins let small disturbances occur without changing the logical value. Different logic families and I/O standards use different thresholds, so 'high means 5 V' is not universal.
Combinational logic produces outputs from current inputs. Sequential logic also remembers previous state using latches, flip-flops, or other storage elements. Registers, counters, state machines, and processor pipelines all rely on stored state. The physical memory technologies used to build larger storage arrays are introduced only after addresses and hierarchy are established.
A clock is a timing reference, not the speed of every operation. Some work spans multiple cycles; memories and peripherals can wait; modern CPUs execute several operations concurrently. Frequency tells you cycles per second, while performance depends on useful work per cycle and time spent waiting.
Vocabulary
- Bit
- One binary logical state; its meaning comes from the surrounding representation.
- Logic gate
- A circuit implementing a Boolean operation such as AND, OR, or NOT.
- Flip-flop
- A clocked circuit that retains a state bit.
- Clock
- A periodic timing reference used to coordinate state transitions.
- Frequency
- Events per second, measured in hertz; 1 GHz is one billion cycles per second.
Why 3 GHz is not 'three billion instructions'
- The clock provides 3 billion cycles each second.
- One instruction may need several internal stages.
- Multiple instructions may overlap or retire in one cycle.
- A cache miss can stall useful work for many cycles.
Clock frequency alone neither states instructions per second nor application performance.
Common mistakes
- A logical 1 is not always 5 V.
- Higher frequency does not guarantee a proportionally faster program.
- Digital signals still obey analog voltage, timing, and signal-integrity limits.
Bits become useful only after a representation says what they mean; the next chapter builds bytes, numbers, addresses, and units from them.
Bytes, words, numbers, and capacity
Bits are grouped into representations. A byte is normally eight bits; a machine word is a processor-dependent natural data width. Decimal prefixes use powers of 1000, binary prefixes use powers of 1024, and rate units must say whether they count bits, bytes, transfers, or operations.
The same bits can mean an unsigned number, a signed two's-complement number, characters, colors, flags, or an instruction. Width and interpretation are part of the data contract. Endianness describes byte order for multi-byte values, not the order of bits drawn on a page.
SI storage prefixes are decimal: 1 kB = 1000 bytes and 1 GB = 10^9 bytes. IEC binary prefixes are powers of two: 1 KiB = 1024 bytes and 1 GiB = 2^30 bytes. Product labels, operating systems, and memory specifications do not always display the same convention.
Bandwidth is amount per time, latency is delay for one request, IOPS is operations per second, and transfers per second describes signaling events. PCIe GT/s is not directly GB/s because encoding and protocol overhead exist. Interface rates written as Gb/s, GT/s, MB/s, or GB/s normally use decimal SI units unless a binary prefix such as GiB/s is explicitly shown. Always preserve the unit while calculating.
Vocabulary
- Byte
- The smallest normally addressable unit in modern systems, conventionally eight bits.
- Word
- A processor's natural data-sized unit; not a universal number of bytes.
- Address
- A number that identifies a location or mapped device resource.
- Bandwidth
- How much data can be transferred per unit time.
- Latency
- How long one operation takes before its result becomes available.
Bits per second to bytes per second
- Start with 8,000,000,000 bit/s.
- Divide by 8 bit/byte.
- The raw result is 1,000,000,000 byte/s.
- Then account for encoding and protocol overhead if the link specification requires it.
8 Gb/s raw is 1 GB/s raw, not necessarily 1 GB/s of application payload.
Common mistakes
- 64-bit does not mean every instruction, address, or stored value is 64 bits.
- GB and GiB are not identical.
- Latency and bandwidth are different axes; a high-bandwidth link can still have high latency.
With units under control, we can follow an instruction and see why CPUs need registers, addresses, and several kinds of nearby memory.
CPU, ISA, registers, and instruction flow
The instruction-set architecture defines the programmer-visible instructions and registers. A concrete CPU microarchitecture fetches, decodes, and executes those instructions, using registers for immediate working values and memory for a larger state space.
An ISA such as Arm, x86-64, or RISC-V is a software-visible contract: instructions, registers, data types, privilege behavior, and memory rules. A microarchitecture is one implementation of that contract, with particular pipelines, caches, execution units, predictors, and power behavior.
Privilege modes separate ordinary application execution from trusted kernel, hypervisor, or firmware control. The privileged layer configures address translation, interrupts, and device mappings, while user-mode software normally reaches devices through operating-system services rather than touching PCIe BARs or physical registers directly.
At a simplified level, the program counter identifies the next instruction, fetch obtains its encoded bytes, decode determines the operation, execute performs arithmetic or starts a memory request, and retirement makes the result architecturally visible. Real CPUs overlap these stages and may execute speculatively while preserving the required visible behavior.
Registers are the CPU's smallest and fastest named working storage. The ALU performs integer/logic operations; load/store units move data; vector or floating-point units handle specialized arithmetic. A core is one independent instruction-execution engine, while SMT threads may share parts of one core.
Vocabulary
- ISA
- The instruction and programmer-state contract software targets.
- Microarchitecture
- A particular hardware design that implements an ISA.
- Program counter
- The architectural register identifying instruction flow.
- Register
- Small processor-local storage directly named by instructions.
- Core
- An execution engine capable of following an instruction stream.
Adding two array elements
- The CPU fetches and decodes load instructions.
- Address-generation logic computes each element address.
- Caches or memory supply the values to registers.
- The ALU adds them; a store instruction writes the result through the memory system.
Even a simple addition may spend more time obtaining data than performing arithmetic.
Common mistakes
- x86, Arm, and RISC-V are ISAs/families, not single CPU models.
- A core is not the same thing as a process or an OS thread.
- Registers are not a replacement for RAM; there are too few and they are managed through instructions.
Instruction fetch and loads need locations. That leads directly to address spaces, memory maps, virtual memory, and memory-mapped devices.
Addresses, memory maps, MMU, and MPU
An address is interpreted by the system's memory map. It may select RAM, ROM, a peripheral register, or an interconnect target. Systems with an MMU translate virtual addresses to physical locations; many MCUs instead use a fixed physical map and may have an MPU for access permissions without translation.
A byte-addressed space assigns an address to each byte. Interconnect decode routes address ranges to targets: RAM controllers, flash, PCIe windows, and peripheral registers. Memory-mapped I/O lets load/store instructions access device registers, but those registers can have side effects unlike ordinary RAM.
Virtual memory gives each process a managed virtual address space. Page tables describe translations and permissions; an MMU performs and caches translations. Virtual memory supports isolation, relocation, shared mappings, demand paging, and other OS policies, but a virtual address is not itself a physical RAM coordinate.
An MPU usually defines permission/attribute regions without general virtual-to-physical translation. This is common in real-time microcontrollers. DMA devices may use physical or I/O virtual addresses and can observe memory differently from a CPU cache, which is why ownership and coherency matter.
Vocabulary
- Memory map
- The assignment of address ranges to memories and devices.
- MMIO
- Memory-mapped I/O: device registers accessed through load/store addresses.
- Virtual address
- An address interpreted through a process and translation context.
- MMU
- Hardware that translates addresses and enforces page-level attributes and permissions.
- MPU
- Hardware that enforces region permissions/attributes, commonly without address translation.
One load, two very different targets
- A load from a RAM range asks the memory system for stored bytes.
- A load from a UART status-register range reaches a peripheral over the bus.
- The peripheral may clear a flag when read.
- The source code syntax can look identical while the hardware behavior differs.
The memory map and device manual—not the pointer syntax—define the access semantics.
Common mistakes
- Every pointer does not necessarily identify physical RAM.
- Virtual memory is not the same thing as swap space.
- volatile affects compiler accesses but does not configure an MMU, cache, or hardware ordering.
Addressing provides one view of many storage technologies. The next chapter explains why systems arrange them as a hierarchy instead of choosing one perfect memory.
Why a memory hierarchy exists
No memory technology simultaneously offers register-like latency, DRAM-like capacity, flash persistence, low cost, and low power. Systems combine small fast layers with larger slower layers and exploit locality to make the common path fast.
A typical path is registers → L1 cache → larger cache levels → DRAM → persistent storage. Capacity usually increases and cost per byte falls as access latency increases. Not every MCU or SoC contains every level, and some include scratchpad or tightly coupled memory instead of a transparent cache.
Temporal locality means recently used data is likely to be used again. Spatial locality means nearby addresses are likely to be used. Caches fetch and evict fixed-size lines because programs often exhibit both. A hit is served by the current cache; a miss requests a lower level and may evict another line.
Caches improve average behavior but complicate timing, sharing, and DMA. They can hold stale copies, dirty modified data, or create contention. Cache is a role/policy layer, usually implemented with SRAM—not a synonym for every fast memory.
In multicore systems, coherence protocols such as MESI-family designs track whether cached copies may be read or modified and propagate ownership/invalidation events. Coherence does not remove synchronization or ordering requirements: it can keep copies consistent while the program still has a data race. Scratchpads and tightly coupled memories may be software-managed and outside the coherent hierarchy.
Vocabulary
- Cache line
- The fixed-size block transferred and tracked by a cache.
- L1 / L2 / L3
- Common names for progressively farther cache levels; exact size, sharing, inclusion, and latency are CPU-specific.
- Hit
- A requested block is present in the checked cache level.
- Miss
- The request must continue to a lower level.
- Locality
- The tendency to reuse recent or nearby data.
- Coherency
- Rules that keep multiple cached views of shared memory consistent.
Walking an array versus chasing pointers
- Sequential array access reuses each fetched cache line.
- A randomly linked list may request a new line for every node.
- Both can execute the same number of high-level iterations.
- The linked traversal spends more time waiting for memory.
Data layout can dominate performance even when algorithmic operation counts look similar.
Common mistakes
- Cache is not persistent storage.
- More cache does not eliminate all memory stalls.
- A cache hit rate alone is incomplete without miss cost, access pattern, and workload.
Hierarchy describes roles such as register, cache, main memory, and storage. The next chapter separates those roles from the physical technologies—SRAM, DRAM, ROM, EEPROM, and flash—that implement them.
Memory types: SRAM, DRAM, ROM, EEPROM, NOR, NAND
SRAM and DRAM are volatile read/write technologies commonly used for caches and main memory. ROM families and flash are non-volatile. NOR flash favors random reads and execute-in-place; NAND flash favors dense page/block storage. EEPROM supports electrically changed non-volatile data, with exact granularity and endurance defined by the device.
SRAM stores state in bistable cells and does not need periodic refresh while powered. It is fast but uses more silicon area per bit, so it commonly implements registers, caches, small MCU RAM, and buffers. DRAM stores charge that leaks and must be refreshed. Its density makes it suitable for large main memory despite controller and timing complexity.
SDRAM means DRAM operations are coordinated with a clock. DDR SDRAM transfers data on both clock edges; DDR generations change signaling, burst behavior, power, training, and controller requirements. DIMM and SO-DIMM are module form factors carrying DRAM devices plus identification and sometimes registers/ECC-related hardware; they are not memory technologies themselves.
DRAM is organized into channels, ranks, banks, rows, and columns. Opening a row, switching rows, refreshing cells, bus turnaround, and controller scheduling produce timing constraints and variable latency. Terms such as CAS latency cannot be compared across products without clock period and the complete timing/workload context.
LPDDR is a JEDEC DRAM family optimized around mobile/low-power requirements; GDDR is a graphics-oriented DRAM family; HBM stacks DRAM dies and uses a very wide interface close to a processor. 'VRAM' usually describes memory serving a graphics processor, not one universal cell technology—modern products may use GDDR, HBM, or shared system DRAM.
NOR flash exposes comparatively convenient random reads and can support execute-in-place, so it is common for firmware images. NAND flash is organized around pages and erase blocks, offers higher density, and requires bad-block management, error correction, wear management, and a controller or flash translation layer for block-storage use. 'ROM' is often used loosely for non-volatile firmware storage even when the technology is reprogrammable flash.
Mask ROM is fixed during manufacture; PROM is programmed after manufacture; EPROM is erased using ultraviolet light; EEPROM is electrically erasable; flash is electrically erasable in larger organizations. FRAM and MRAM are other non-volatile random-access technologies with different density, write, endurance, retention, and cost tradeoffs. Product documentation—not the broad family name—sets the real guarantees.
Vocabulary
- Volatile
- Needs power to retain its stored state.
- SRAM
- Static RAM; no refresh while powered, fast and relatively area-expensive.
- DRAM
- Dynamic RAM; dense cells requiring periodic refresh.
- EEPROM
- Electrically erasable programmable non-volatile memory; details are device-specific.
- LPDDR / GDDR / HBM
- DRAM families optimized respectively for low power, graphics-style bandwidth, and stacked very-wide interfaces.
- PROM / EPROM
- Earlier programmable ROM families, with one-time programming or ultraviolet erasure respectively.
- FRAM / MRAM
- Non-volatile random-access memory families using ferroelectric or magnetic storage mechanisms.
- NOR flash
- Flash suited to random reads and often execute-in-place firmware.
- NAND flash
- Dense flash organized around pages and erase blocks, widely used for storage.
Choosing memory for a data logger
- Use MCU SRAM for the active sample buffer because it changes frequently.
- Use internal NOR-like flash for firmware if the MCU boots/executes from it.
- Use EEPROM or a managed non-volatile region for small infrequent configuration updates.
- Use managed NAND, eMMC, SD, or an SSD for a large log.
The choice follows capacity, persistence, access granularity, endurance, latency, and software-management needs.
Common mistakes
- Static RAM does not mean a C static variable.
- ROM does not always mean physically impossible to rewrite.
- All flash is not byte-writable RAM; erase/program rules matter.
- RAM is a role/category in everyday usage, while SRAM and DRAM name technologies.
These technologies become products only after controllers, packages, channels, error correction, and protocols are added. The next chapter follows raw non-volatile media into an SSD or embedded storage device.
From flash cells to files and SSDs
An SSD combines non-volatile media with a controller, firmware, RAM or other working state, error correction, mapping, wear management, queues, and a host interface. The host normally reads logical blocks; the controller translates them to changing physical flash locations.
NAND cannot generally overwrite arbitrary bytes in place. Data is programmed in pages and erased in larger blocks; cells wear with program/erase cycles and exhibit errors. A flash translation layer maps logical block addresses to physical pages, performs garbage collection, distributes wear, handles bad blocks, and coordinates error correction.
HDDs store magnetic data on rotating media and pay mechanical seek/rotation costs. SSDs remove mechanical movement, enabling much lower random-access latency and higher parallelism, but they still have controller queues, flash-channel limits, garbage collection, thermal constraints, and finite write endurance.
A block device exposes numbered blocks, not filenames. Partition tables divide address ranges; filesystems organize files, directories, metadata, allocation, recovery, and permissions. Formatting a filesystem and choosing a storage transport solve different layers of the stack.
eMMC combines managed NAND and a controller in a soldered package with a standardized host interface; UFS is another managed-flash standard designed for greater concurrency and full-duplex operation; SD cards are removable managed-flash devices with their own interface and performance classes. They solve similar storage roles with different packaging, buses, queues, power, removability, and platform support.
Vocabulary
- LBA
- Logical block address exposed by a block-storage interface.
- FTL
- Flash translation layer mapping host logical blocks to physical flash locations.
- Wear leveling
- Distributing writes/erases so a small region does not fail prematurely.
- Garbage collection
- Reclaiming erase blocks by relocating still-valid pages.
- Filesystem
- Software structures that organize files and metadata on block storage.
- eMMC / UFS / SD
- Managed-flash product/interface families used especially in embedded and mobile systems; none is raw NAND.
Updating 4 KiB in a nearly full SSD
- The host submits a write for one logical range.
- The controller may program new physical pages instead of overwriting old NAND.
- Mapping metadata changes and old pages become invalid.
- Garbage collection may later move valid pages and erase a block.
A small logical write can cause more internal media work; this is one source of write amplification and latency variation.
Common mistakes
- An SSD is not raw NAND directly controlled by the filesystem.
- Deleting a file does not necessarily erase the physical cells immediately.
- Interface peak bandwidth does not describe sustained writes after caches fill or garbage collection begins.
A storage controller must communicate with the CPU. To understand that path, we next separate physical connectors, electrical links, buses, protocols, and software drivers.
Motherboard, SoC, chipset, GPU, and controllers
A motherboard supplies physical interconnect, power delivery, clocks, firmware storage, sockets, and controllers. A modern CPU or SoC integrates cores plus memory and I/O controllers; a chipset or companion device provides additional I/O. GPUs and device controllers are processors specialized for particular workloads.
The CPU package may contain CPU cores, last-level caches, memory controllers, PCIe root ports, integrated graphics, accelerators, and security/management logic. A microcontroller integrates CPU, SRAM, flash, timers, analog blocks, and peripheral controllers on one chip. 'SoC' emphasizes this integration but does not prescribe one exact feature set.
A discrete GPU is a specialized parallel processor, usually with dedicated VRAM and a PCIe connection to the host. Integrated graphics may share system DRAM. The GPU still needs drivers, command buffers, memory management, and synchronization; it is not simply a display socket.
Power delivery and thermal design are functional constraints. Voltage regulators convert rails, firmware establishes power/clock states, sensors report temperatures, and cooling removes heat. A component may throttle below its nominal capability when power, temperature, firmware, or platform lanes are constrained.
Vocabulary
- Motherboard
- The board providing mechanical, electrical, power, clock, firmware, and interconnect infrastructure.
- SoC
- A chip integrating processing and multiple system functions/controllers.
- Chipset
- Companion platform logic providing additional I/O and management functions.
- GPU
- A processor optimized for highly parallel graphics and compute workloads.
- Controller
- Hardware/firmware that implements one side of an interface and manages a device or medium.
Why two identical SSDs may run differently
- One socket may connect directly to CPU PCIe lanes.
- Another may traverse a chipset uplink shared with USB/network traffic.
- The sockets may support different lane counts or generations.
- Cooling and firmware power policy can change sustained behavior.
The whole platform path—not only the SSD label—sets the available performance envelope.
Common mistakes
- The chipset is not the CPU's cache.
- Every motherboard socket is not wired identically.
- A GPU is not only output hardware; it executes programs and accesses memory.
Components need well-defined paths. The next chapter gives a layer model for buses and protocols so USB, DDR, PCIe, SATA, and I2C stop looking like equivalent acronyms.
Connector, form factor, bus, protocol, and driver
A connector is physical; a form factor defines shape/mechanics; signaling defines electrical transfer; a bus or transport moves transactions; a protocol gives messages meaning; a controller implements the hardware side; and a driver lets software use it. Product names often combine several layers, so compatibility requires checking each one.
USB-C demonstrates the problem: it describes a reversible connector, while the port may support different USB data generations, USB Power Delivery, DisplayPort alternate mode, Thunderbolt/USB4 capabilities, or only charging. The visible shape does not guarantee every protocol.
Parallel buses transfer several data bits on separate wires per beat; high-speed serial links encode data across differential pairs and may aggregate lanes. Serial does not automatically mean slow—signal integrity and clock recovery let modern serial links operate at very high rates.
Software discovers a controller, maps registers, configures queues or descriptors, handles interrupts, and exposes an OS abstraction. A physically connected device can remain unusable if firmware, enumeration, security policy, or the driver does not support it.
Vocabulary
- Connector
- The physical mating contacts and mechanical interface.
- Form factor
- Mechanical dimensions, mounting, and related physical constraints.
- Bus/transport
- How transactions and data move between endpoints.
- Protocol
- Rules and message meanings used by communicating components.
- Driver
- Software that controls a device/controller and exposes services to the OS.
A USB-C port that cannot drive a monitor
- The connector accepts the cable physically.
- The port supports USB data and charging.
- It lacks DisplayPort alternate-mode routing.
- No adapter can invent display signals the host never provides.
Mechanical fit is necessary but not sufficient for protocol compatibility.
Common mistakes
- Same connector does not guarantee same speed, power, or protocol.
- Serial links are not inherently slower than parallel buses.
- A driver is not the same as device firmware.
This layer vocabulary is the key prerequisite for PCIe. Without it, M.2 is easily mistaken for NVMe and NVMe for a physical plug.
PCI Express from first principles
PCI Express is a packet-based, point-to-point serial interconnect. A lane has transmit and receive differential pairs for full-duplex communication. Links combine lanes—x1, x2, x4, x8, x16—and train to a mutually supported speed and width. PCIe connects many device types; it is not itself a storage protocol.
The root complex connects processor/memory resources to a PCIe fabric. Endpoints are devices; switches add downstream ports. During link training, partners establish electrical operation, generation, and lane width. A physically x16 connector may be electrically wired for fewer lanes, and bifurcation can divide a root port when the platform supports it.
PCIe transactions are packetized. Configuration space identifies functions and capabilities. Base Address Registers describe memory or I/O windows the platform allocates; the OS maps them so a driver can reach device registers. Devices can use DMA to read/write system memory under platform and IOMMU rules.
GT/s is transfers per second per lane, not application bytes per second. Generations use different encoding and protocol overheads; higher generations demand stricter signal integrity. A link falls back to the highest speed and width both ends and the board path support.
Active State Power Management can place an idle link into lower-power states at the cost of exit latency, while Advanced Error Reporting improves PCIe error visibility and recovery policy. Capabilities such as SR-IOV, ACS, and function-level reset matter in virtualized or fault-contained systems but are optional/platform-dependent—not basic properties of every endpoint.
Vocabulary
- Root complex
- The host-side PCIe connection between processor/memory and the PCIe hierarchy.
- Endpoint
- A PCIe function/device at the edge of the fabric.
- Lane
- One full-duplex PCIe serial path using transmit and receive differential pairs.
- Link training
- Partners establish link operation, speed, width, and other parameters.
- BAR
- A configuration register describing a device address window to be allocated/mapped.
- DMA
- A device transferring data to/from memory without the CPU copying each byte.
A Gen4 x4 SSD in a Gen3 x2-capable socket
- The device supports up to Gen4 and four lanes.
- The platform path supports only Gen3 and two lanes.
- Training selects a mutually supported Gen3 x2 link.
- Protocol, controller, workload, and overhead reduce payload below the raw link ceiling.
Compatibility can remain while peak bandwidth is limited by the negotiated link.
Common mistakes
- PCIe is not only a slot for graphics cards.
- x16 describes lane capacity/width, not a guarantee that all lanes are wired or active.
- GT/s is not GB/s.
- PCIe is a transport/interconnect, not the NVMe command set.
PCIe can carry accesses to an NVMe controller, a GPU, a network adapter, or another endpoint. The next chapter explains the controller-enumeration path before storage-specific protocols are layered on top.
How software finds and uses a PCIe device
Firmware and the OS enumerate PCIe functions, assign address resources, configure capabilities, and bind a matching driver. The driver maps controller registers, allocates memory queues/descriptors, establishes interrupts, and coordinates DMA with ownership and protection rules.
A PCIe device can expose one or more functions, identified by vendor/device IDs and class information. Configuration mechanisms let firmware/OS walk the topology and allocate bridge windows, bus numbers, BAR address space, interrupt resources, and power-management policy.
Legacy line interrupts gave way to message-signaled interrupts such as MSI/MSI-X, where a device writes a configured message to signal work. Multiple vectors can distribute queue completions across CPU cores, subject to OS policy and device capability.
DMA improves throughput and CPU efficiency, but the device and CPU must agree on buffer ownership, addresses, cache coherency, completion, and lifetime. Like a CPU MMU, an IOMMU uses translation and permission structures, but its requester is an I/O device performing DMA rather than a CPU instruction stream; the two address spaces and fault paths are distinct.
Vocabulary
- Enumeration
- Discovering functions/topology and assigning usable resources.
- Configuration space
- Standard PCIe-visible identity, resource, status, and capability registers.
- MSI-X
- Message-signaled interrupts supporting multiple independently configured vectors.
- Descriptor
- A memory structure describing buffers or operations to a controller.
- IOMMU
- Hardware translating and restricting device DMA address spaces.
Receiving a network packet
- The driver gives the NIC DMA descriptors pointing to owned buffers.
- The NIC writes packet bytes into system memory.
- It records completion and raises a message-signaled interrupt.
- The driver validates completion, transfers buffer ownership upward, and replenishes the queue.
PCIe carries the transactions; the NIC protocol and driver define the queue and buffer semantics.
Common mistakes
- Enumeration is more than detecting physical presence.
- DMA does not mean no CPU involvement at all.
- An IOMMU and CPU MMU protect different initiators/address spaces.
Storage standards differ largely in the controller/register/command model the driver speaks. That makes this the final prerequisite for comparing SATA/AHCI and NVMe correctly.
SATA, AHCI, NVMe, and the storage stack
SATA is a serial storage interface family historically carrying ATA commands; AHCI is a common host-controller programming model for SATA. NVMe defines a scalable controller/register and command/queue interface for non-volatile storage across transports, most commonly PCIe in client systems. Neither SATA nor NVMe names the NAND technology or physical size of the drive.
A SATA HDD and SATA SSD share a host-facing interface while their media and internal behavior differ. AHCI lets software control SATA ports using defined register and command structures. SATA's compatibility history and queue model differ from an NVMe controller designed around many submission/completion queues and contemporary solid-state parallelism.
An NVMe host driver creates queues in memory, submits commands, rings controller doorbells, and consumes completions. The NVMe specification set separates base architecture, command sets, and transports. PCIe is the common local transport, but NVMe is not linguistically or architecturally identical to PCIe.
SATA transports information in structures called FISes, and Native Command Queuing lets a capable SATA device manage multiple outstanding commands within that model. These details do not turn AHCI into NVMe: NVMe's register/doorbell and submission/completion queue architecture is a different host-controller contract designed for scalable parallelism.
Performance comparisons require workload context: sequential bandwidth, random IOPS, queue depth, block size, latency distribution, read/write mix, thermals, controller cache, media state, and OS behavior. Saying 'NVMe is always N times faster' ignores both workload and device implementation.
Vocabulary
- SATA
- Serial ATA storage interface family connecting hosts and ATA storage devices.
- AHCI
- A standardized host-controller interface/programming model commonly used for SATA.
- NVMe
- A scalable non-volatile-memory controller and command/queue specification set.
- Submission queue
- Host-memory queue into which software places NVMe commands.
- Completion queue
- Queue through which the controller reports finished commands.
Reading a file from an NVMe SSD
- The filesystem resolves file offsets to logical block requests.
- The block layer and NVMe driver build commands in submission queues.
- The controller fetches commands over PCIe and DMA-transfers data.
- Completion entries and interrupts tell software which requests finished.
NVMe defines the storage-controller conversation; PCIe transports its memory/register transactions.
Common mistakes
- NVMe is not a physical connector.
- SATA SSD does not mean a different kind of NAND by definition.
- PCIe and NVMe are not synonyms.
- AHCI is not the filesystem.
Now that the transport/protocol layer is clear, M.2 can be introduced safely as a mechanical family whose sockets may expose SATA, PCIe, USB, and other signals depending on keying and platform design.
M.2, keys, sizes, and compatibility
M.2 is a family of module and connector form factors. Numbers such as 2280 describe width and length in millimetres. Edge-connector keys constrain mechanical insertion and available interfaces, but the host socket must also be electrically wired and firmware-enabled for the drive's protocol and lane count. An M.2 storage module may use SATA or PCIe/NVMe.
M.2 replaced older mobile expansion formats with compact modules of several lengths. A 2280 module is nominally 22 mm wide and 80 mm long; other lengths include 42 and 110 mm. Mounting position, component height, single/double-sided support, power, cooling, and platform documentation all matter.
Key notches prevent some incompatible insertions and allocate pin groups, but keying alone is not a complete compatibility oracle. Storage modules are commonly discussed as B-key, M-key, or B+M-key, while other M.2 modules can implement Wi-Fi, cellular, or different functions. Always consult the module and motherboard/SoC documentation.
A socket might accept the board mechanically yet expose only SATA, only PCIe, or both through platform multiplexing. Installing one device can disable a SATA port or share lanes on some boards. Boot firmware may also lack support for booting from a logically usable device.
Vocabulary
- M.2
- A PCI-SIG-defined family of compact module/form-factor and connector specifications.
- 2280
- A common M.2 module size: 22 mm wide and 80 mm long.
- Key
- Connector notch/pin assignment scheme constraining module/socket combinations.
- U.2
- A cabled/cased PCIe form factor used particularly for 2.5-inch enterprise SSDs.
- AIC
- Add-in card, typically using a PCIe CEM slot form factor.
Checking an M.2 upgrade
- Confirm the physical length and mounting point, such as 2280.
- Confirm socket key and supported module type.
- Confirm SATA versus PCIe signaling, NVMe support, lane width, and generation.
- Check lane/SATA-port sharing, boot support, component height, power, and cooling.
A matching notch and screw position are only the first two checks.
Common mistakes
- M.2 does not mean NVMe.
- NVMe does not mean M.2; NVMe drives also use U.2, AIC, and EDSFF forms.
- B+M notches do not guarantee the host supports every protocol.
- 2280 is a size, not a speed or capacity.
This completes the acronym chain. The final chapters connect hardware compatibility to boot firmware, partitions, filesystems, performance evidence, and system selection.
Power-on, firmware, bootloader, driver, and filesystem
Reset starts processor-defined firmware code. Platform firmware initializes enough hardware to discover a boot target, follows a boot policy, loads a boot program, and hands off. The OS initializes its memory and drivers, mounts filesystems, and starts services. Each transition has its own data structures and failure modes.
On PC-class systems, UEFI firmware provides standardized boot services and variables; legacy BIOS is a different historical model. On MCUs, a reset vector and startup code may lead directly to one firmware image or a small bootloader. 'Firmware' is the broad category; UEFI and bootloaders are particular uses.
A partition table describes ranges and types on a block device. A filesystem interprets a partition or device as files/directories and metadata. In a typical UEFI system, firmware boot variables identify boot options and an EFI System Partition contains filesystem-visible boot applications. A bootloader understands enough storage/filesystem/image format to locate and validate the next software stage. Secure Boot is about authenticity/policy, not disk encryption by itself.
The OS driver stack turns controller-specific operations into block requests; filesystems add names and consistency; virtual memory maps executable/image pages; processes and libraries start above that. A boot error can therefore be electrical, enumeration, firmware-policy, driver, partition, filesystem, image, or security-policy failure.
Vocabulary
- Firmware
- Software closely associated with hardware initialization/control and stored non-volatilely.
- UEFI
- A standardized PC platform firmware interface and boot environment.
- Bootloader
- Software that locates, validates, loads, and transfers control to another image.
- Partition table
- Metadata describing logical disk regions and their intended use.
- Secure Boot
- A policy/process for authenticating boot components before execution.
Drive visible in OS but absent from boot menu
- Electrical link and OS driver clearly work after another boot path.
- Firmware may lack a matching NVMe boot driver or option ROM path.
- The disk may lack the expected partition/boot files.
- Boot policy or Secure Boot may reject the loader.
Runtime visibility does not prove firmware can or will boot from the device.
Common mistakes
- UEFI is not just a graphical BIOS skin.
- A filesystem is not the same as a partition table.
- Secure Boot does not encrypt user files.
- The OS cannot use a device before any driver/controller path exists.
The last two chapters turn the model into engineering judgment: measuring bottlenecks, protecting data, selecting parts, and defending a complete design.
Performance, endurance, integrity, and evidence
Translate the workload into latency, bandwidth, IOPS, queue depth, capacity, power, endurance, retention, and integrity requirements. Measure the complete path under representative steady-state and failure conditions. Peak interface numbers are ceilings, not application guarantees.
Sequential throughput rewards long contiguous transfers; random workloads emphasize request latency, IOPS, and parallel queues. Queue depth can increase throughput while also increasing waiting latency. Average latency can hide tail outliers that matter to interactive or real-time systems.
ECC detects/corrects some bit errors at different layers: DRAM modules/controllers, caches, storage media, and protocols may each have mechanisms with different coverage. Checksums, redundancy, backups, journaling, power-loss protection, and end-to-end validation solve different failure classes.
Flash endurance figures depend on workload, capacity, over-provisioning, write amplification, temperature, and vendor specification. Thermal throttling, SLC-style caches, garbage collection, memory pressure, and shared links can make short benchmarks unrepresentative of sustained application behavior.
Vocabulary
- IOPS
- Input/output operations per second for a specified operation size and workload.
- Queue depth
- Number of outstanding operations available for service.
- Tail latency
- High-percentile delay, such as the slowest 1% or 0.1% of requests.
- ECC
- Error-correcting code; exact detection/correction coverage depends on the implementation.
- Endurance
- A specified ability to tolerate writes/erases under defined conditions.
Why a '7 GB/s' SSD may copy at 900 MB/s
- The label may describe a favorable sequential read workload.
- The copy includes both source reads and destination writes.
- The destination may exhaust a fast write cache or throttle thermally.
- Measure a distribution: 1 ms median with 35 ms p99 exposes rare stalls that an average can hide.
Benchmark method, bottleneck location, steady-state duration, and latency percentiles must be stated before comparing a measurement with a headline ceiling.
Common mistakes
- Peak bandwidth is not sustained application throughput.
- ECC is not a backup.
- RAID is not automatically a backup.
- A single short benchmark does not characterize tail latency or steady-state writes.
The capstone uses these requirements to choose components and explain every layer from a bit to a booted application.
Capstone: explain and select a complete system
Start from workload and failure requirements, draw the data path, assign every acronym to a layer, verify mechanical/electrical/protocol/software compatibility, calculate bottleneck ceilings with units, then validate assumptions using platform documentation and measurements.
A defensible selection states what the system must do before naming products. Required capacity, working set, persistence, latency distribution, throughput, parallelism, power, temperature, dimensions, boot policy, service life, cost, and recovery strategy constrain different layers.
Draw both a hardware path and software path. Hardware might be CPU root port → PCIe switch/socket → NVMe controller → NAND. Software might be application → filesystem → block layer → NVMe driver → queues/DMA. Mark shared resources, ownership transitions, caches, and evidence points.
Compatibility evidence comes from exact CPU/SoC, motherboard, firmware, module, and OS documentation—not from matching marketing words. Validation includes enumeration, negotiated link status, driver binding, sustained workload, power-loss behavior, thermal state, error logs, and recovery testing.
Vocabulary
- Requirement
- A measurable need or constraint, not a preferred implementation.
- Bottleneck
- The limiting resource for the observed workload and state.
- Compatibility matrix
- Evidence table across mechanical, electrical, protocol, firmware, driver, power, and thermal layers.
- Acceptance test
- A repeatable check that proves a stated requirement under defined conditions.
- Observability
- The measurements/logs needed to infer internal state and diagnose failures.
Selecting storage for a fanless edge computer
- Define capacity, sustained writes, boot time, temperature, power-loss, lifetime, serviceability, and a startup/steady/peak power budget.
- Verify socket size/key, PCIe generation/lanes, NVMe boot support, cooling, power rails, and lane sharing.
- Select endurance and power-loss features using vendor specifications rather than connector type.
- Measure sustained writes, thermals, latency tails, health logs, rail behavior, and recovery after controlled power interruption.
The chosen M.2 NVMe drive is the end of a requirements chain, not the beginning of the design.
Common mistakes
- Buying the highest generation is not architecture.
- A compatible connector is not a complete compatibility proof.
- One benchmark is not an acceptance plan.
- Knowing acronym expansions is not the same as understanding their layer and behavior.
This is the handoff into architecture, operating systems, embedded Linux, drivers, performance engineering, and hardware design.
More in Foundations
- PointersComplete visual pointer laboratory: addresses, dereferencing, pointer arithmetic, arrays and decay, double pointers, dynamic memory, function pointers, const/volatile, MMIO, lifetime bugs — with a step-through memory simulator, 100+ interview questions and a mastery exam.
- Cache Coherency 0 → 100A first-principles course from cache lines and the coherence problem through MSI, MESI, MOESI, snooping, directories, memory ordering, atomics, false sharing, DMA, NUMA, measurement and verification—with a live protocol engine and code lab.
- From Power-On to main()What runs before main(): the Cortex-M reset sequence that gives C the machine it assumes, the linker script that decides where every section lives and why .data has two addresses, the four build stages and which one your error came from, and the order to work through a debug probe that will not connect.
- Number RepresentationBases and why hex is the one you read, two's complement and the asymmetry that makes abs(INT_MIN) undefined, the bit-manipulation idioms with the edge case in each, and byte order - which matters in exactly three places and in none of the arithmetic.
- FoundationsComputer systems from first principles—memory, storage and interconnects through cache coherence, ordering, atomics and DMA—then the firmware foundations of numbers, linking, interrupts and pointers.