Buses, Ports, Drivers and Firmware
13.0 What this chapter gives you#
- You will be able to point at any part of a motherboard and say what it does.
- You will be able to explain what a bus is, and why fast links stopped being wide and became narrow instead.
- You will be able to read “PCIe 4.0 x4” and work out the bandwidth yourself.
- You will be able to describe every way a processor talks to a device: memory-mapped registers, ports, polling, interrupts and direct memory access.
- You will be able to follow an interrupt from a wire to a running piece of code, and read the interrupt counters on a real machine.
- You will be able to explain exactly what happens in the moment you plug in a USB device, step by step.
- You will be able to answer the question “what is a driver” with a full chain of layers, not a slogan.
- You will be able to say how Windows, Linux and macOS each load drivers, and how each one picks the right driver for a chip.
- You will be able to separate firmware from driver from application, and say where each one lives.
- You will be able to describe what happens in the first second after you press the power button, up to the point where the bootloader takes over.
Chapter 18 continues the story from where the bootloader hands off to the operating system kernel. This chapter stops at that handover.
13.1 The motherboard as a city#
PLAIN13.1.1 in simple words#
- The motherboard is a flat green board with everything plugged into it.
- It is not one thing. It is a set of sockets, slots, wires and small chips.
- The wires are not loose. They are thin copper lines baked into the board itself, called traces.
- A modern board is a sandwich of six to sixteen thin layers of copper and glue, so traces can cross without touching.
- Every part on the board does one job. Once you know the jobs, the board stops looking like a maze.
- The big square socket in the middle holds the processor.
- The long thin slots beside it hold the memory sticks.
- The long slots below hold cards, such as a graphics card.
- The small flat slots hold storage sticks.
- The metal cluster at the back edge holds the connectors you can see from outside the case.
PLAIN13.1.2 a picture in your head#
- Think of the board as a small city seen from above.
- The processor socket is the city centre, where all the work is done.
- The power circuits next to it are the power station, feeding the centre.
- The memory slots are the warehouses, right next to the centre because the trips there are constant.
- The chipset is the suburban traffic hub, handling everything that is not urgent enough to reach the centre directly.
- The card slots are goods yards where big vehicles dock.
- The back panel is the city gates, where things enter from outside.
- The little battery is the town clock’s backup, keeping time when the power is off.
Where this comparison breaks: a real city has traffic that goes anywhere. On a board almost every route is fixed at the factory and cannot change. A trace between two points is a permanent street, not a road that can be re-planned.
PLAIN13.1.3 a worked example#
- Take a common desktop board layout and walk it top to bottom.
- Here is what you would find, in order, on a typical mid-range board sold since about 2023.
[ rear IO panel ] [ CPU power socket ]
+-------------------------------------------+
| VRM | CPU socket | VRM | D | D | D | D |
|------+------------+--------| I | I | I | I |
| PCIe x16 slot (from CPU) | M | M | M | M |
| [ M.2 slot, under heatsink ] M | M | M |
|----------------------------+--------------|
| chipset chip under heatsink | SATA ports |
| PCIe x1 | PCIe x4 | M.2 | M.2 | BIOS chip |
| front panel + USB headers | CMOS battery |
+-------------------------------------------+
- The board is read like a page. Power at the top, processor in the middle, slow devices at the bottom.
- Fast things sit near the processor because the wires must be short.
- Slow things sit far away because a longer wire does not hurt them.
PLAIN13.1.4 what is really happening inside#
- CPU socket: a bed of spring pins that press against the processor. It carries power in and every high-speed signal out.
- VRM, short for voltage regulator module: the small square chips, coils and cylinders next to the socket. They cut 12 volts down to under 1.5 volts for the processor.
- DIMM slots: the long clipped slots holding memory sticks. Their wires go straight to the processor on any modern board.
- Chipset: one large chip under a low heatsink. It is a fan-out switch, turning a few fast lanes from the processor into many slower ports.
- PCIe slots: the long open-ended slots for cards. They carry high-speed serial links plus power.
- M.2 slots: short flat slots for storage sticks. They usually carry the same kind of high-speed link as a card slot, in a smaller shape.
- SATA ports: small flat right-angle sockets for older drives.
- Headers: bare pin blocks with no plastic shell. The case’s power button, front USB ports, fans and front audio plug into these.
- CMOS battery: a coin cell that keeps the clock and settings alive when the machine is unplugged.
- BIOS flash chip: a tiny eight-legged chip holding the startup code. Without it the board cannot even find the processor’s first instruction.
- Super IO chip: a small chip that runs fans, reads temperatures and voltages, and provides the last old-style ports.
- Rear IO panel: the metal strip of outward-facing connectors.
TECHNICAL13.1.5 the engineer’s version#
- Sockets are LGA (land grid array, pins in the socket) or PGA (pin grid array, pins on the chip). Intel LGA1700 has 1700 contacts; AMD AM5 is LGA with 1718 contacts and replaced the pinned AM4 in 2022.
- A large share of socket contacts are power and ground, not signals. On LGA1700 only a minority carry data.
- VRMs are multiphase synchronous buck converters. A phase is one inductor plus a high-side and low-side MOSFET, driven by a PWM controller. Phases are switched out of step to smooth the current ripple.
- A desktop processor core voltage is roughly 0.7 V to 1.4 V, and sustained current can exceed 200 A on high-end parts. That is why the VRM needs heatsinks.
- DDR4 and DDR5 unbuffered DIMMs both have 288 pins, but the key notch sits in a different place, so they are not interchangeable. DDR5 moved the power management IC onto the DIMM itself.
- On Intel platforms the chipset is the PCH (platform controller hub), attached over DMI (Direct Media Interface), which is electrically PCI Express. Recent desktop chipsets use a DMI 4.0 x8 link.
- On AMD AM5 the chipset is called a Promontory device and attaches over a PCIe link; high-end boards chain two chipset chips together.
- The firmware chip is SPI NOR flash in an 8-pin SOIC or WSON package, typically 16 MB or 32 MB (128 or 256 megabit) on boards since about 2020.
- Super IO chips are made by Nuvoton and ITE, for example the ITE IT8689E. They hang off the LPC or eSPI bus and expose fan tachometers, PWM fan control, voltage and temperature sensing, and legacy serial ports.
- The coin cell is a CR2032, 3 V lithium, about 225 mAh, and typically lasts three to seven years.
- Board layer counts: four layers on budget boards, eight to twelve on mainstream boards, and more on server boards, because DDR5 and PCIe 5.0 signalling needs clean reference planes.
| Part | Job in one line | Typical figure |
|---|---|---|
| VRM phase | Step 12 V down | 50 to 110 A each |
| CMOS cell | Keep clock and setup | CR2032, 3 V |
| BIOS flash | Hold startup code | 16 to 32 MB SPI |
| DMI 4.0 x8 | CPU to chipset link | About 16 GB/s |
- Tools that show this without opening the case:
dmidecode -t 2on Linux prints the board maker and model, andlspcilists the chipset devices.
WORDS13.1.6 remember these#
- Trace — a printed wire on the board — a copper track etched in a PCB layer.
- Socket — the seat the processor sits in — LGA or PGA contact array.
- VRM — the power step-down circuit — multiphase synchronous buck converter.
- Chipset — the traffic hub chip — PCH or southbridge fan-out switch.
- Header — a bare block of pins — an unshrouded board-level connector.
- Super IO — the fans and sensors chip — LPC or eSPI attached legacy IO controller.
- Flash chip — where startup code lives — SPI NOR device holding the firmware image.
13.2 What a bus actually is#
PLAIN13.2.1 in simple words#
- A bus is a set of wires shared by several parts, so they can pass numbers to each other.
- It carries three kinds of information: where, what, and when.
- The “where” wires carry an address, meaning which device or which memory slot is being spoken to.
- The “what” wires carry the data itself.
- The “when” wires carry control signals: read or write, start now, I am ready, I am finished.
- Only one part may talk at a time on a shared bus, or the messages would collide.
- There are two ways to send many bits: side by side on many wires, or one after another on a few wires.
- Side by side is called parallel. One after another is called serial.
- Parallel sounds faster, and for a long time it was.
- Above a certain speed, parallel stops working and serial wins. This chapter explains why.
PLAIN13.2.2 a picture in your head#
- Imagine eight runners set off together carrying one letter each. The message is only complete when all eight arrive.
- That is a parallel bus. Eight wires, eight bits, all at once.
- If one runner is slightly slower, everyone waits for them. The whole message is only as fast as the worst runner.
- Now make them run much faster. Tiny differences in path length become large differences in arrival time.
- Worse, running close together, they knock into each other and drop letters.
- Now imagine one runner, on one clean track, carrying letters one after another, but sprinting far faster than the group ever could.
- That is a serial link. Fewer wires, but each wire far quicker.
Where this comparison breaks: real serial links are not truly one runner. They have a separate track in each direction, and often several tracks in parallel called lanes. The difference is that each lane carries its own timing, so the lanes do not have to arrive in perfect step.
PLAIN13.2.3 a worked example#
- The bandwidth of a simple parallel bus is width times clock rate.
- Formula: bytes per second = (bus width in bits / 8) x transfers per second.
- Old PCI: 32 bits wide, 33.33 million transfers per second.
- 32 / 8 = 4 bytes. 4 x 33,333,333 = 133,333,332 bytes per second.
- That is about 133 MB/s, and it is the number the PCI specification quotes.
- Now a 64-bit PCI slot at 66 MHz: 8 bytes x 66,666,666 = about 533 MB/s.
- Now compare one PCI Express 3.0 lane. It is two wires each way, not 32.
- It runs at 8 gigatransfers per second and delivers about 985 MB/s each way at the same time.
- One tiny serial lane beats the whole 32-wire parallel bus, and does it in both directions at once.
| Link | Wires for data | Bandwidth |
|---|---|---|
| PCI 32-bit 33 MHz | 32 shared | 133 MB/s shared |
| PCI 64-bit 66 MHz | 64 shared | 533 MB/s shared |
| PCIe 3.0 x1 | 4 (2 per way) | 985 MB/s each |
PLAIN13.2.4 what is really happening inside#
- On a parallel bus every bit of one number leaves at the same instant, on its own wire.
- Traces on a board are never exactly the same length, because they must bend around other parts.
- A signal moves along a board trace at roughly half the speed of light, about 15 centimetres per nanosecond.
- So a 1.5 centimetre difference in trace length is a 0.1 nanosecond difference in arrival. That gap is called skew.
- At 33 million transfers per second each bit lasts 30 nanoseconds, so 0.1 nanosecond of skew does not matter at all.
- At 8 billion transfers per second each bit lasts 0.125 nanoseconds. Now 0.1 nanoseconds of skew almost swallows the whole bit.
- Board makers fix this by adding wiggles to short traces to match lengths, which is why you see squiggly patterns near memory slots.
- Length matching gets harder as speed rises, and eventually impossible.
- Second problem: a changing signal on one wire pushes a small copy of itself onto the wire beside it. That is crosstalk. More wires close together means more of it.
- Third problem: on a shared bus, every device hanging off the wires adds electrical load, which rounds off the sharp edges of the signal.
- Serial links dodge all three. Fewer wires means less crosstalk. Each lane carries its own timing, so skew between lanes can be corrected in the receiver. Point-to-point means only two ends, so the load is fixed and known.
- Modern serial links do not send a separate clock. The clock is recovered from the data itself, which is why the data has to be encoded so it never stays flat for long.
TECHNICAL13.2.5 the engineer’s version#
- A classic bus has three groups: an address bus, a data bus and a control bus. The 8088 in the 1981 IBM PC had a 20-bit address bus and an 8-bit external data bus, reaching 1 MiB of address space.
- Shared multi-drop buses are limited by settling time, reflections from unterminated stubs, and the capacitive load of every attached device.
- Modern serial links are differential: each lane is a pair of wires driven to opposite voltages. The receiver reads the difference, so noise that hits both wires equally cancels out.
- Signalling levels are low. PCI Express uses roughly 0.8 to 1.2 V differential swing, versus 5 V or 3.3 V single-ended on old PCI.
- Clocking is embedded. Transmitters scramble and encode data so transitions occur often enough for a clock and data recovery (CDR) circuit to lock on.
- Line codes cost bandwidth. 8b/10b sends 10 symbols for 8 data bits, a 20 percent overhead. 128b/130b sends 130 for 128, about 1.5 percent.
- Raw rate is quoted in GT/s, gigatransfers per second, not GHz, because modern links may carry more than one bit per transfer.
- Bandwidth formula for a serial link: bytes/s = (GT/s x lanes x coding efficiency) / 8.
- Worked check for PCIe 3.0 x1: 8 GT/s x 1 x (128/130) / 8 = 0.985 GB/s.
- Worked check for PCIe 5.0 x4: 32 x 4 x (128/130) / 8 = 15.75 GB/s each direction.
Parallel, shared: Serial, point-to-point:
CPU ===================== CPU <--TX--> device
|| || || || (one pair each way,
dev dev dev dev own clock recovery)
(all share one set of wires)
- Skew budget: at 32 GT/s a unit interval is 31.25 picoseconds. Board designers work to intra-pair skew targets in the low single-digit picoseconds. This is why parallel buses stopped scaling.
- The honest version: serial did not beat parallel on raw physics alone. It won because it moved the hard problem into silicon, where equalization, scrambling and error correction are cheap, and away from the board, where length matching is expensive.
- Parallel is not dead. Inside a chip, and between a processor and DRAM, wide parallel interfaces still win because the distances are short and fixed. DDR5 still uses a 64-bit data path per channel pair.
WORDS13.2.6 remember these#
- Bus — shared wires between parts — a multi-drop interconnect with address, data and control groups.
- Parallel — many bits at once — simultaneous transmission across a wide data path.
- Serial — bits one after another — sequential transmission on a lane.
- Skew — bits arriving at different times — timing difference between parallel signals at the receiver.
- Crosstalk — one wire disturbing its neighbour — unwanted coupling between adjacent conductors.
- Differential pair — two wires carrying opposites — balanced signalling with common-mode noise rejection.
- GT/s — how many transfers per second — gigatransfers per second, before coding overhead is removed.
- Line code — the packaging of bits on the wire — the mapping such as 8b/10b or 128b/130b.
13.3 The history of expansion buses#
PLAIN13.3.1 in simple words#
- From the beginning, computers needed a way to add hardware after buying the machine.
- The answer was a slot: a row of contacts on the board, into which a card slides.
- The first widely copied slot on personal computers came with the IBM PC in
- It was slow, but it was documented, so anyone could make cards for it.
- Graphics grew hungry, and each new slot design existed mainly because pictures needed more room.
- Every generation was faster and had fewer wires than you would expect.
- Today one design has replaced them all: PCI Express, usually written PCIe.
- PCIe comes in different physical sizes and different speed generations, and the two are separate ideas.
- A slot’s size tells you how many lanes it can hold. A generation tells you how fast a lane runs.
PLAIN13.3.2 a picture in your head#
- Think of a loading bay with a number of doors.
- The size of the bay is how many doors it has: one, four, eight or sixteen.
- The generation is how fast one door can move goods.
- A sixteen-door bay of an old generation and a four-door bay of a new generation can move about the same amount.
- That is why an older graphics card in a big slot can be matched by a newer card in a smaller one.
- Also, a bay may have sixteen doors built, but only four of them connected to a road. The bay is full-size but only four doors are usable.
Where this comparison breaks: doors move goods one way. A PCIe lane moves data both ways at once, so the total for a link is double the one-way figure if both directions are busy.
PLAIN13.3.3 a worked example#
- A graphics card that says “PCIe 4.0 x16” wants sixteen lanes at generation four speed.
- Generation four gives about 1.969 GB/s each way per lane.
- Sixteen lanes: 16 x 1.969 = about 31.5 GB/s each way.
- Put the same card in a slot wired at x4. Now 4 x 1.969 = about 7.9 GB/s.
- Put it in a PCIe 3.0 x16 slot instead. 16 x 0.985 = about 15.75 GB/s.
- Notice that a generation four x8 link and a generation three x16 link give the same figure. That is not a coincidence: each generation roughly doubles the per-lane speed.
PLAIN13.3.4 what is really happening inside#
- ISA, 1981: 62 contacts, 8 data bits, running at the processor clock of 4.77 MHz. In 1984 the IBM PC/AT added a second connector section for 16 bits, and the speed settled at 8 MHz.
- Cards on ISA had switches and jumpers on them, because nothing was automatic. You set the card’s address and interrupt number by hand.
- VESA Local Bus, 1992: a hack. It bolted an extra connector onto the end of an ISA slot and wired it straight to the 486 processor’s own bus.
- It was fast for the time, up to about 200 MB/s, but the processor could only drive two or three such cards, and it died when the Pentium changed the processor’s bus.
- PCI, 1992: designed at Intel and then handed to a group called the PCI Special Interest Group. 32 bits at 33 MHz, about 133 MB/s, shared by every card in the machine.
- PCI’s real gift was not speed. It was that each card could describe itself, so the machine could set addresses and interrupts automatically. No more jumpers.
- AGP, 1997: a private lane just for graphics, so the video card did not have to queue behind everything else on PCI.
- PCI Express, 2003: the change of shape. It threw away the shared parallel bus and used point-to-point serial lanes with a switch in the middle.
- Each PCIe device gets its own link. Nothing is shared, so one slow device no longer holds up the rest.
TECHNICAL13.3.5 the engineer’s version#
- Dates and figures for the main expansion buses:
| Bus | Year | Peak bandwidth |
|---|---|---|
| ISA 8-bit | 1981 | About 4 to 8 MB/s |
| ISA 16-bit | 1984 | About 8 to 16 MB/s |
| VESA Local Bus | 1992 | Up to about 200 MB/s |
| PCI 32/33 | 1992 | 133 MB/s shared |
| AGP 8x | 2002 | 2133 MB/s |
| PCIe 1.0 x16 | 2003 | 4 GB/s each way |
- AGP was introduced by Intel with the 440LX chipset on 26 August 1997. Its base clock was 66 MHz: 1x gives 266 MB/s, 2x gives 533 MB/s, 4x gives 1066 MB/s at 1.5 V, and 8x gives 2133 MB/s at 0.8 V.
- Compaq coined the retronym Industry Standard Architecture for the IBM AT bus in the late 1980s, because IBM never gave it a public name.
- PCI Express per-lane figures, one direction, after coding overhead:
| Gen | Year | GT/s | Per lane each way |
|---|---|---|---|
| 1.0 | 2003 | 2.5 | 250 MB/s |
| 2.0 | 2007 | 5.0 | 500 MB/s |
| 3.0 | 2010 | 8.0 | 985 MB/s |
| 4.0 | 2017 | 16.0 | 1.969 GB/s |
| 5.0 | 2019 | 32.0 | 3.938 GB/s |
| 6.0 | 2022 | 64.0 | 7.563 GB/s |
| 7.0 | 2025 | 128 | 15.125 GB/s |
- Generations 1.0 and 2.0 use 8b/10b, so the usable fraction is 80 percent. Generations 3.0 through 5.0 use 128b/130b, about 98.5 percent.
- Generation 6.0, released in January 2022, changed the physics: PAM4 signalling carries two bits per symbol, with forward error correction and fixed 256-byte FLIT packets carrying 242 bytes of payload. Generation 7.0 was finalized in June 2025 and keeps PAM4.
- First shipping PCIe 6.0 hardware appeared in 2025, three years after the specification. Specification date and product date are always different. Say which one you mean.
- Physical versus electrical width: a slot with a x16 connector may only have four lanes wired. This is written as “x16 slot, x4 electrical”. It happens because the processor has a fixed lane budget.
- A typical desktop processor since 2021 exposes 20 to 28 usable lanes. A graphics card takes 16 and an NVMe drive takes 4, so the rest of the slots are wired through the chipset and share the chipset’s uplink.
- Bifurcation is splitting one wide link into several narrower ones: an x16 root port configured as x4/x4/x4/x4 to drive four NVMe drives on one adapter card. It must be supported by the processor’s root complex and exposed in firmware setup. Cheap adapter cards that do not include a PCIe switch require bifurcation; cards with a switch chip do not.
- Whether bifurcation is available at all is an implementation detail of one processor and one board’s firmware, not something PCI Express guarantees. Two boards with the same chipset often differ.
- Link training negotiates width and speed at power-on. If a lane fails, the link retrains narrower, so a card can silently fall back to x8 or x1.
- Observe it on Linux with
lspci -vvand read the LnkCap and LnkSta lines:
LnkCap: Speed 16GT/s, Width x16
LnkSta: Speed 2.5GT/s (downgraded), Width x16
- A speed of 2.5 GT/s at idle is usually normal power saving, not a fault. Check under load before concluding anything.
WORDS13.3.6 remember these#
- Slot — the place a card plugs in — a card edge connector on a defined pinout.
- Lane — one serial path — a transmit pair plus a receive pair in PCIe.
- Generation — how fast a lane runs — the PCIe specification revision setting the transfer rate.
- Electrical width — how many lanes are actually wired — the negotiated link width, which may be less than the connector size.
- Bifurcation — splitting one wide slot into several — configuring a root port as multiple narrower links.
- Link training — the handshake at power-on — the LTSSM process that agrees width, speed and equalization.
13.4 How the processor talks to a device#
PLAIN13.4.1 in simple words#
- A device is not magic. It is a chip with a set of numbered boxes inside it, called registers.
- Writing a number into one box makes the device do something.
- Reading a number out of another box tells you what the device is doing.
- So “controlling a device” means writing and reading small numbers at fixed places.
- There are two ways for the processor to reach those boxes.
- The first way pretends the device’s boxes are ordinary memory addresses. Write to address such-and-such and the device hears it. This is called memory-mapped input and output.
- The second way uses a separate, smaller set of addresses reached only by two special instructions. This is called port-mapped input and output.
- Once you can reach the boxes, you still need to know when the device has finished a job.
- You can keep asking, over and over. That is called polling, and it wastes the processor’s time.
- Or the device can tap the processor on the shoulder when it is ready. That is an interrupt.
- Moving a lot of data through the processor one piece at a time is slow. So devices are allowed to move data to and from memory by themselves. That is direct memory access.
PLAIN13.4.2 a picture in your head#
- Imagine a hotel reception desk with a row of pigeonholes on the wall behind it.
- Each pigeonhole is a device register. Putting a card in box 3 means “start the lift”. Reading box 4 tells you which floor the lift is on.
- Memory-mapped input and output means those pigeonholes are simply part of the same wall as all the other room boxes. You use the same ladder.
- Port-mapped input and output means the pigeonholes are in a locked side room with its own small ladder and its own numbering.
- Polling is standing at the desk asking “is the lift here yet?” every two seconds, doing nothing else.
- An interrupt is going back to work and letting a bell ring when the lift arrives.
- Direct memory access is telling the porter to move the luggage between rooms without carrying each bag past the desk yourself.
Where this comparison breaks: a hotel porter can be trusted to only touch the right rooms. A device doing direct memory access can, unless stopped, write anywhere in memory. That risk is exactly why the IOMMU was invented.
PLAIN13.4.3 a worked example#
- Here is a classic serial port, in the style of the original IBM PC, using port-mapped input and output.
- The first serial port lives at port address 0x3F8.
- Port 0x3F8 is the data box. Port 0x3FD is the status box.
- Bit 5 of the status box means “the transmit box is empty, you may send”.
- Sending one character by polling looks like this.
/* wait until bit 5 of the status port is set */
while ((inb(0x3FD) & 0x20) == 0) {
/* spin: the CPU does nothing useful here */
}
/* Linux order is outb(value, port). Some other
headers use outb(port, value). Always check. */
outb('A', 0x3F8); /* write the character */
- At 9600 bits per second, one character takes about 1 millisecond.
- A 3 GHz processor executes roughly 3 million cycles in that millisecond.
- So sending one character by polling burns about 3 million cycles of doing nothing.
- With an interrupt, the processor writes the character, goes off and runs other programs, and is called back when the port is free again.
- With direct memory access, the processor hands over a pointer to 4 KB of text and is called back once, at the end, instead of 4096 times.
PLAIN13.4.4 what is really happening inside#
- When the processor executes a write to a memory address, that address goes out on the interconnect.
- Something has to decide who owns that address. That job belongs to address decoding logic in the processor’s root complex and in bridges.
- Ranges of the address space are handed out at start-up to devices. Each device says how big a window it needs, and firmware assigns it a base address.
- So writing to address 0xF7C0_0010 might not touch memory at all. It might land in register 0x10 of a network card.
- These device windows must not be cached, because reading the same address twice can legitimately give different answers, and a write must reach the device now and not sit in a cache.
- Port-mapped input and output is different. On x86 the instructions IN and OUT carry a 16-bit port number, giving 65,536 ports in a space entirely separate from memory.
- For direct memory access, the processor writes into the device’s registers the address of a buffer in main memory and a length, then sets a “go” bit.
- The device then becomes a bus master: it issues its own read and write requests to memory, without the processor being involved.
- Real buffers are rarely one solid block of physical memory. A 1 MB buffer seen by a program as continuous may be scattered across 256 separate 4 KB physical pages.
- So the driver builds a list of address and length pairs, and hands the list to the device. The device walks the list. This is scatter-gather.
- Since the device writes straight into memory, the processor’s cached copy of that memory can become stale. Either the hardware keeps caches coherent, or the driver must explicitly invalidate the range.
- A device that can write anywhere in memory can overwrite the operating system. The IOMMU sits between devices and memory and translates and checks every device address, exactly as the MMU does for programs.
TECHNICAL13.4.5 the engineer’s version#
- MMIO regions are advertised through PCI Base Address Registers (BARs). A device has up to six 32-bit BARs; a 64-bit BAR consumes two.
- At power-on, firmware writes all ones to a BAR and reads it back. The number of low bits that stay zero tells you the size of the window the device wants. Firmware then programs a base address.
- On x86 the page attributes for MMIO are set to UC (uncacheable) or WC (write-combining) via the MTRRs and PAT, so accesses are not reordered or merged in ways the device would misread.
- Port IO on x86 uses IN, OUT, INS and OUTS. Notable legacy addresses: 0x20 and 0xA0 for the two 8259A interrupt controllers, 0x60 and 0x64 for the keyboard controller, 0x70 and 0x71 for CMOS and the real-time clock, 0x3F8 for COM1, 0x378 for LPT1.
- Port IO survives only for legacy compatibility. ARM and RISC-V have no separate IO space at all; everything is memory-mapped.
- The original PC used an Intel 8237A DMA controller with four channels, and the PC/AT added a second for 16-bit channels 5, 6 and 7, with channel 4 used to cascade. This is third-party DMA, where a central controller moves the data.
- Third-party DMA is obsolete on PCI Express. Every PCIe endpoint that moves bulk data is a bus master doing first-party DMA.
- Bus mastering must be explicitly enabled by setting the Bus Master Enable bit in the device’s PCI command register. A driver that forgets this sees a device that appears to do nothing.
- Scatter-gather lists are called SGLs, or descriptor rings in networking. An NVMe drive supports both PRP (physical region page) lists and SGLs.
- IOMMU implementations: Intel VT-d, AMD-Vi, and Arm SMMU. They provide an IO virtual address space per device, using the PCIe requester ID (bus:device.function) to select a page table.
- The IOMMU defends against DMA attacks. The FireWire DMA attacks of the 2000s and the Thunderclap research of 2019 both exploited devices with unrestricted memory access. It also makes device passthrough to virtual machines safe.
- IOMMU costs. Address translation adds latency, and IOTLB misses hurt. High-throughput setups often use large pages or, in some deployments, passthrough mode, trading protection for speed. Engineers genuinely disagree about where that line should be.
| Mechanism | Who moves the data | Cost per byte |
|---|---|---|
| Polled PIO | The CPU, in a loop | Very high |
| IRQ + PIO | The CPU, on demand | High |
| DMA | The device itself | Near zero for CPU |
- Observe on Linux:
lspci -vvshows BAR regions as “Memory at …” and “I/O ports at …”, andcat /proc/iomemand/proc/ioportslist the whole assignment.
WORDS13.4.6 remember these#
- Register — a numbered box inside a chip — an addressable control or status location in a device.
- MMIO — device boxes look like memory — memory-mapped IO through a BAR window, marked uncacheable.
- Port IO — a separate small address space — x86 IN and OUT over a 16-bit port space.
- Polling — asking again and again — busy-wait on a status register.
- DMA — the device moves data itself — direct memory access by a bus master.
- Scatter-gather — a list of memory pieces — a descriptor list of address and length pairs.
- IOMMU — the guard between device and memory — an IO memory management unit translating and checking device addresses.
13.5 Interrupts, end to end#
PLAIN13.5.1 in simple words#
- An interrupt is a device saying “stop what you are doing and deal with me”.
- Without interrupts, the processor would have to check every device constantly, which would waste almost all of its time.
- The processor finishes the instruction it is on, saves where it was, and jumps to a small piece of code written for that device.
- That piece of code is called the interrupt handler, or interrupt service routine.
- When the handler finishes, the processor restores what it saved and carries on exactly where it left off. The interrupted program never knows.
- Many devices may want attention at once, so a helper chip collects and ranks the requests. That is the interrupt controller.
- Each source has a number, so the processor knows which handler to run.
- A table in memory maps each number to the address of its handler.
- Interrupt handlers must be extremely short, because everything else is frozen while one runs.
- So the work is split: a tiny urgent part now, and the slow part scheduled for a moment later.
PLAIN13.5.2 a picture in your head#
- Imagine a clerk working through a pile of forms, with a bell on the desk.
- Anyone needing attention rings the bell rather than standing in the queue.
- The clerk puts a bookmark in the form they are on, deals with the bell, then goes back to the exact same line of the same form.
- There are many bells, one per department, all wired into a small box on the wall that ranks them and passes the most important one through.
- Beside the desk is a printed list: bell number 1 means the front door, bell number 4 means the fire door.
- If a bell means “the delivery arrived”, the clerk does not unload the van right then. They write “van outside” on a note, and go back to the forms. The unloading happens between forms.
- That split is the top half and the bottom half.
Where this comparison breaks: a clerk can ignore a bell. A processor with interrupts enabled cannot, which is why a device stuck ringing its bell can freeze a machine completely. That failure is called an interrupt storm.
PLAIN13.5.3 a worked example#
- You press the letter A on an old-style keyboard attached to a PC.
- The keyboard controller sees a key change and raises interrupt request 1.
- The interrupt controller checks that IRQ 1 is not masked and that nothing more important is being served, then signals the processor.
- The processor finishes its current instruction and reads the interrupt number, 0x21 in the classic mapping.
- It looks up entry 0x21 in the interrupt descriptor table and jumps to the handler address stored there.
- The handler reads one byte from port 0x60. That byte is a scan code, not a letter. For A it is 0x1E on press and 0x9E on release.
- The handler puts the scan code in a queue and returns immediately. Total time: a few microseconds.
- Later, ordinary kernel code takes the scan code out of the queue, maps it through the current keyboard layout, and delivers the character A to whichever window has focus.
- Note what did not happen inside the handler: no layout lookup, no window search, no drawing.
PLAIN13.5.4 what is really happening inside#
- In the oldest design, an interrupt is literally a wire. The device pulls the wire and holds it until it is serviced. This is level-triggered.
- A wire per device does not scale, so several devices shared one wire and the handler had to ask each of them “was it you?”.
- Message-signalled interrupts replaced the wire completely. The device does a normal memory write to a special address, and that write is the interrupt. No extra wire at all.
- The interrupt controller’s jobs are: collect requests, apply masks, rank by priority, and hand the processor a number.
- The number is an index into a table of handler addresses.
- Before jumping, the processor pushes enough state to return: the instruction pointer, the flags, and on x86 the code segment.
- The handler runs with further interrupts of the same or lower priority blocked, so it must not wait for anything.
- The handler acknowledges the interrupt, so the controller knows it may deliver the next one. Forgetting this leaves the machine wedged.
- Then it does the smallest possible urgent job, and queues the rest.
- The queued rest runs later with interrupts enabled again, so it may take locks, allocate memory, and wake up sleeping processes.
- At very high rates, even a short handler costs too much. A network card receiving 1 million packets per second cannot afford 1 million interrupts.
- So the device is told to wait: fire one interrupt per 32 packets, or one every 50 microseconds, whichever comes first. That is coalescing. It trades a little latency for a lot of processor time.
TECHNICAL13.5.5 the engineer’s version#
- The original IBM PC used one Intel 8259A PIC with 8 inputs. The 1984 PC/AT cascaded a second 8259A into IRQ 2, giving 15 usable lines.
- Classic IRQ assignments, still visible in firmware and in old manuals. These are a convention set by the IBM PC and PC/AT, not a written standard, but every clone copied them and software depended on them:
| IRQ | Assigned to | Note |
|---|---|---|
| 0 | System timer | 8253/8254 PIT |
| 1 | Keyboard | Port 0x60 |
| 2 | Cascade to slave | Not usable directly |
| 6 | Floppy controller | Legacy |
| 12 | PS/2 mouse | Port 0x60 also |
| 14 | Primary ATA | Legacy disk |
- The APIC (Advanced Programmable Interrupt Controller) arrived with the Pentium era. Each core has a local APIC; an IO APIC, such as the Intel 82093AA, routes external lines. This allows routing an interrupt to a chosen core and supports 24 inputs per IO APIC.
- MSI (message-signalled interrupts) was added in the PCI 2.2 specification. A device performs a posted memory write to an address in the range 0xFEE00000 on x86, carrying a vector in the data payload.
- MSI allows up to 32 vectors per device in the PCI specification, though Windows uses at most 16. MSI-X, added in PCI 3.0, allows up to 2048 vectors, each with its own address, data and mask bit in a table in device memory.
- MSI-X is what makes multi-queue devices work: one vector per queue, each pinned to a different core, so a 32-core machine can service a NIC on all 32 cores without lock contention.
- x86 has 256 interrupt vectors, 0 to 255. Vectors 0 to 31 are reserved for processor exceptions such as divide error (0), page fault (14) and general protection fault (13). Devices use 32 upward.
- In real mode the table is the IVT at physical address 0, 256 entries of 4 bytes. In protected and long mode it is the IDT, 256 entries of 8 or 16 bytes, located by the IDTR register and loaded with LIDT.
- Linux names the split top half and bottom half. The top half is the handler registered with
request_irq. Bottom halves are softirqs, tasklets, threaded IRQ handlers, or workqueues, in increasing order of how much they are allowed to do. - Windows names it differently: the ISR runs at device IRQL, and defers work to a DPC (deferred procedure call) at DISPATCH_LEVEL.
- Coalescing on Linux NICs is controlled with
ethtool -c eth0to read andethtool -C eth0 rx-usecs 50to set. NVMe uses a similar aggregation threshold and time window. - Read live counts on Linux:
cat /proc/interrupts # per-CPU counts, per source
watch -n1 'grep nvme /proc/interrupts'
- On macOS there is no /proc; use
ioreg -lfor device trees and the Instruments tool for interrupt activity. On Windows, Performance Monitor exposes “Interrupts/sec” and “DPCs Queued/sec”. - An interrupt storm shows as one line in /proc/interrupts climbing by hundreds of thousands per second while the machine is idle. The usual cause is a shared level-triggered line whose owner never deasserts.
WORDS13.5.6 remember these#
- Interrupt — a device asking for attention — an asynchronous transfer of control to a handler.
- IRQ — the request number — an interrupt request line or its assigned index.
- Vector — the table entry number — an index into the IDT selecting a handler.
- ISR — the code that runs on an interrupt — the interrupt service routine, running with interrupts partly masked.
- Top half and bottom half — urgent bit now, slow bit later — hard IRQ context versus softirq, tasklet, workqueue or DPC.
- MSI-X — an interrupt sent as a memory write — message-signalled interrupts with up to 2048 per-vector table entries.
- Coalescing — batching interrupts — delaying notification by a packet count or time threshold to cut CPU overhead.
13.6 USB, properly#
PLAIN13.6.1 in simple words#
- Before 1996, every kind of device had its own kind of plug.
- A mouse had one plug, a keyboard another, a printer a third, a modem a fourth, and a joystick a fifth.
- Each of them needed its own settings, and each machine had only one or two of each socket.
- USB, the Universal Serial Bus, was made to replace all of them with one plug that anyone could use.
- Its three promises were: one connector for everything, plug it in while the machine is running, and no manual settings.
- It also carries power, so small devices need no separate supply.
- USB is not a shared party line. There is one boss, called the host, and everything else answers only when asked.
- Devices never speak first. Even a mouse only replies when the host asks it for an update, which the host does about once every millisecond.
- You can add more sockets by plugging in a hub, which is a splitter that passes the host’s questions along.
- When you plug something in, the machine goes through a fixed set of steps to find out what it is. That process is called enumeration.
PLAIN13.6.2 a picture in your head#
- Think of a teacher in a classroom who alone decides who speaks.
- The teacher goes around asking each pupil in turn: “anything for me?”
- Most pupils say “nothing”. A mouse says “nothing” a thousand times a second, then once says “moved left by three”.
- No pupil ever shouts out. If two spoke at once, neither would be heard.
- Group leaders sit between the teacher and the pupils, passing questions down and answers back. Those are hubs.
- A new pupil arriving at the door is noticed by the nearest group leader, who tells the teacher. The teacher then asks the newcomer their name, gives them a seat number, and asks what subject they study.
Where this comparison breaks: USB 3 and later added a second set of wires that lets a device signal readiness rather than being asked, which is closer to raising a hand. And USB On-The-Go lets a phone act as the teacher instead of the pupil. The strict one-boss model is true of USB 2 and earlier.
PLAIN13.6.3 a worked example#
- Plug a keyboard into a running computer. Here is the exact sequence.
1 attach device pulls one data line high through a
resistor; the hub sees the change
2 report hub tells host: something on port 3
3 reset host tells hub to reset that port
4 default device now answers at address 0, endpoint 0
5 read 8 host reads first 8 bytes of the device
descriptor to learn the max packet size
6 address host sends SET_ADDRESS with a free number
from 1 to 127; device switches to it
7 descript host reads full device, configuration,
interface and endpoint descriptors
8 match host looks up class, vendor and product
IDs and picks a driver
9 configure host sends SET_CONFIGURATION; device
powers up its interfaces and starts work
- In step 7 the host learns that this device reports interface class 3, which means human interface device, subclass 1 and protocol 1, which mean boot keyboard.
- That is enough. No vendor driver is needed. The operating system’s own HID keyboard driver handles it.
- Total time from plug to working: typically well under a second.
- Now the steady state. The host polls the keyboard’s interrupt endpoint every 8 milliseconds by default for a low-speed keyboard.
- Each poll returns 8 bytes: one byte of modifier keys, one reserved byte, and up to six key codes held down at once.
- That six-key limit is why cheap keyboards cannot report many simultaneous key presses in boot protocol.
PLAIN13.6.4 what is really happening inside#
- The shape is a tiered star. The host controller is the root. Hubs form the branches. Devices are the leaves.
- The specification allows 7 tiers counting the root, which means at most 5 hubs between the host and a device, and up to 127 addresses in total.
- Inside a device, the things the host talks to are called endpoints. An endpoint is a buffer with a number and a direction.
- Endpoint 0 always exists, works both ways, and is used for setup and control. Every device has it.
- A logical connection between the host’s driver and one endpoint is called a pipe.
- There are four kinds of transfer, and a device picks one per endpoint.
- Control: short, guaranteed, used for setup and commands. Endpoint 0 only.
- Bulk: large amounts, correctness guaranteed, timing not guaranteed. Used by drives and printers. It gets whatever bandwidth is left over.
- Interrupt: small and regular. The host promises to ask at least this often. Used by mice, keyboards and touchpads. The name is misleading: nothing interrupts anything, the host simply polls on a schedule.
- Isochronous: a guaranteed slice of bandwidth every frame, with no retries. Used by webcams, microphones and audio interfaces, where a late packet is worse than a lost one.
- Time is divided into frames of 1 millisecond at full speed, and microframes of 125 microseconds at high speed. Bandwidth is reserved inside each frame.
- Interrupt and isochronous endpoints get their reservation first. If not enough is left, the device is refused, which is the real reason a webcam sometimes fails to start when other devices share a controller.
TECHNICAL13.6.5 the engineer’s version#
- USB 1.0 was released in January 1996 by a promoter group including Compaq, DEC, IBM, Intel, Microsoft, NEC and Nortel. Ajay Bhatt led the effort at Intel. USB 1.1, in September 1998, was the version that actually worked in the field.
- Speeds and dates:
| Version | Year | Raw rate | Old marketing |
|---|---|---|---|
| 1.0 Low | 1996 | 1.5 Mbit/s | Low Speed |
| 1.1 Full | 1998 | 12 Mbit/s | Full Speed |
| 2.0 | 2000 | 480 Mbit/s | High Speed |
| 3.0 | 2008 | 5 Gbit/s | SuperSpeed |
| 3.1 | 2013 | 10 Gbit/s | SuperSpeed+ |
| 3.2 | 2017 | 20 Gbit/s | SuperSpeed 20Gbps |
| USB4 | 2019 | 20 or 40 Gb/s | USB4 Gen 2 / 3 |
| USB4 v2.0 | 2022 | 80 Gbit/s | USB 80Gbps |
- The naming is a genuine mess and the USB-IF made it worse twice. When USB 3.1 arrived, plain USB 3.0 was renamed USB 3.1 Gen 1. When USB 3.2 arrived, both were renamed again to USB 3.2 Gen 1 and USB 3.2 Gen 2. So a 5 Gbit/s port has had three official names for the same silicon.
- As of 2026 the USB-IF’s guidance is to drop the version numbers in consumer labelling and use speed names only: USB 5Gbps, USB 10Gbps, USB 20Gbps, USB 40Gbps and USB 80Gbps. Product pages still use the old names, so expect both.
- Mapping: USB 3.2 Gen 1x1 is 5 Gbit/s, Gen 2x1 is 10 Gbit/s, Gen 2x2 is 20 Gbit/s using two lanes. USB4 Gen 3x2 is 40 Gbit/s and USB4 Gen 4x2 is 80 Gbit/s. USB4 Version 2.0 also defines an asymmetric mode of 120 Gbit/s one way and 40 Gbit/s the other, for high-resolution displays.
- Encoding overhead is real. USB 3.0 at 5 Gbit/s uses 8b/10b, so the usable ceiling is 500 MB/s before protocol overhead, and real drives reach around 400 to 450 MB/s.
- Power. USB 2.0 defines a unit load of 100 mA at 5 V, with up to 5 units, so 500 mA or 2.5 W. USB 3.x raises the unit load to 150 mA with up to 6 units, so 900 mA or 4.5 W.
- USB Power Delivery negotiates far more. PD revision 1.0 reached 100 W. PD revision 3.1, published in 2021, added Extended Power Range with 28 V, 36 V and 48 V fixed levels, reaching 240 W at 48 V and 5 A. A cable must be electronically marked to carry 5 A.
- USB Type-C is a connector, defined in a specification finalized in August 2014, with 24 pins and reversible insertion. It is not a speed and not a protocol.
- This is the single most common confusion in the whole subject. A USB-C socket may run USB 2.0 at 480 Mbit/s and nothing else, or it may carry USB 80Gbps plus DisplayPort plus PCIe plus 240 W. The shape tells you nothing. Only the logo and the specification sheet tell you.
- Device classes are defined by the USB-IF so that one driver serves many products. Class 1 audio, class 3 HID, class 6 still image, class 7 printer, class 8 mass storage, class 9 hub, class 14 video, class 255 vendor-specific.
- HID, defined in 1996 and revised as HID 1.11 in 2001, is why a keyboard from any maker works with no download. It uses a self-describing report descriptor, so the device tells the host the layout of its own data.
- Boot protocol is the cut-down fixed 8-byte HID keyboard format that firmware can drive before any operating system loads. That is why your keyboard works in the BIOS setup screen.
- Vendor and product IDs are 16-bit each and assigned by the USB-IF. For example 0x046D is Logitech.
- Observe on Linux with
lsusb -tfor the topology tree andlsusb -vfor descriptors. On macOS,system_profiler SPUSBDataType. On Windows, Device Manager with “Devices by connection” selected.
/: Bus 01.Port 1: Dev 1, Class=root_hub, 480M
|__ Port 2: Dev 3, If 0, Class=HID, Driver=usbhid, 1.5M
|__ Port 4: Dev 5, If 0, Class=Mass Storage, 480M
WORDS13.6.6 remember these#
- Host controller — the boss chip on the machine — the xHCI controller issuing all transactions.
- Hub — a splitter — a device that repeats host traffic to more ports and reports attachments.
- Endpoint — a numbered buffer in a device — a source or sink with a direction and transfer type.
- Pipe — a connection to one endpoint — the logical channel between host driver and endpoint.
- Enumeration — finding out what was plugged in — reset, address assignment, descriptor read and configuration.
- Descriptor — the device’s self-description — the byte structures giving IDs, classes, endpoints and strings.
- Device class — a family with a standard driver — the interface class code that selects a generic driver.
- USB-C — the oval reversible plug — a 24-pin connector specification, not a speed or a protocol.
13.7 The other ports on the machine#
PLAIN13.7.1 in simple words#
- Not every socket on a machine is USB. Each remaining one exists because it does something USB did not do well enough at the time.
- Thunderbolt looks exactly like USB-C but can carry far more, including a graphics card’s connection and a screen’s picture at the same time.
- HDMI and DisplayPort carry picture and sound to a screen.
- The square-ish clicky socket is Ethernet, for a network cable.
- The small round holes are audio jacks, for headphones and microphones.
- The thin slot is for SD cards, used mostly by cameras.
- The old wide sockets, serial and parallel, have almost gone from home machines but are alive in factories and laboratories.
PLAIN13.7.2 a picture in your head#
- Think of USB as a general delivery van that handles most parcels.
- Thunderbolt is a motorway tunnel. Other roads drive through it unchanged and come out the other end still themselves.
- That is the key idea: Thunderbolt does not convert the traffic. It wraps it, carries it, and unwraps it.
- So a graphics card in a box on your desk really is talking to the processor over its normal card connection. The cable just carries it.
Where this comparison breaks: a tunnel has fixed lanes. Thunderbolt shares one budget between video and data, so a very high resolution screen leaves less room for the drive plugged into the same dock.
PLAIN13.7.3 a worked example#
- You plug a laptop into one dock with a single USB-C cable, and get a 4K screen, a wired network, three USB ports and charging.
- Inside the cable there is one Thunderbolt link.
- The screen’s picture rides inside it as DisplayPort.
- The network chip and the USB ports on the dock sit behind a PCI Express switch, and that PCI Express traffic also rides inside it.
- Power travels on separate power pins, negotiated by USB Power Delivery.
- Take the same cable and plug in a second 4K screen at 120 Hz. Something will drop in quality or refresh rate, because the video share of the budget is now full.
PLAIN13.7.4 what is really happening inside#
- Thunderbolt builds a small switched network in the cable. Each end has a controller chip that packs, routes and unpacks.
- Because it tunnels PCI Express, a Thunderbolt device is, to the operating system, a card plugged into the machine. This is why external graphics boxes work and also why Thunderbolt security matters.
- HDMI and DisplayPort differ in origin. HDMI grew from television and carries a clocked stream of pixels. DisplayPort grew from computing and sends packets, which is why it can drive several screens down one cable.
- Ethernet’s eight-pin socket uses two or four twisted pairs. Twisting the pairs is what cancels interference over 100 metres of cable.
- A headphone jack with three black bands has four conductors: left, right, ground and microphone. That is what TRRS means: tip, ring, ring, sleeve.
- An SD card is a small controller chip plus flash memory. The card, not the camera, decides where data physically goes.
TECHNICAL13.7.5 the engineer’s version#
- Thunderbolt began as Intel’s Light Peak research and shipped in February 2011 on the MacBook Pro with a Mini DisplayPort connector.
| Version | Year | Bandwidth | Connector |
|---|---|---|---|
| TB 1 | 2011 | 10 Gbit/s | Mini DisplayPort |
| TB 2 | 2013 | 20 Gbit/s | Mini DisplayPort |
| TB 3 | 2015 | 40 Gbit/s | USB-C |
| TB 4 | 2020 | 40 Gbit/s | USB-C |
| TB 5 | 2023 | 80 Gbit/s | USB-C |
- Thunderbolt 4 did not raise the headline speed over Thunderbolt 3. It raised the minimum requirements: 32 Gbit/s of PCIe tunnelling, two 4K displays, and mandatory DMA protection through the IOMMU.
- Thunderbolt 5, announced by Intel in September 2023 with the controller codenamed Barlow Ridge, provides 80 Gbit/s in both directions and an asymmetric Bandwidth Boost mode of 120 Gbit/s out and 40 Gbit/s back. It tunnels PCIe 4.0 x4, about 64 Gbit/s. It is built on USB4 Version 2.0.
- DMA protection is not optional history. The Thunderspy work published in 2020 showed pre-2019 Thunderbolt machines could be compromised through direct memory access from a malicious device.
- Display standards: HDMI 1.0 in 2002; HDMI 2.1 in 2017 at 48 Gbit/s; HDMI 2.2, announced at CES in January 2025 and published in mid-2025, at 96 Gbit/s with “Ultra96” certified cables. DisplayPort 1.0 came from VESA in 2006; DisplayPort 2.0 in 2019 defines UHBR20 at 80 Gbit/s raw; DisplayPort 2.1b was announced alongside HDMI 2.2 with DP80LL cables.
- HDMI is licensed by HDMI Licensing Administrator with per-unit royalties. DisplayPort is royalty-free from VESA. That commercial difference, not a technical one, is why televisions use HDMI and monitors often use both.
- Ethernet on copper: 10BASE-T from 1990, 100BASE-TX from 1995, 1000BASE-T from IEEE 802.3ab in 1999, 10GBASE-T from 802.3an in 2006, and 2.5GBASE-T and 5GBASE-T from 802.3bz in 2016. The connector is an 8P8C modular plug, almost always called RJ45 by convention rather than by standard.
- Audio jacks are 3.5 mm. TRS is three conductors and stereo out. TRRS is four and adds a microphone. Two incompatible TRRS wirings exist: CTIA, used by nearly everything today, and OMTP, used by some older phones, with microphone and ground swapped. The colour code, green for line out and pink for microphone, comes from the Microsoft and Intel PC 99 guide.
- SD cards were introduced in August 1999 by SanDisk, Panasonic and Toshiba, with the SD Association formed in January 2000. Capacity tiers: SDSC to 2 GB, SDHC to 32 GB from 2006, SDXC to 2 TB from 2009, SDUC to 128 TB from
- Bus modes run from 12.5 MB/s default speed through UHS-I at 104 MB/s and UHS-II at 312 MB/s to SD Express, which puts PCIe and NVMe on the card and reaches into the gigabytes per second.
- Serial: the EIA RS-232 standard dates from 1960. The PC/AT gave it a DE-9 plug in 1984. COM1 sits at port 0x3F8 on IRQ 4. It survives on network switch consoles, laboratory instruments, industrial controllers and embedded debug headers, usually now through a USB-to-serial adapter using an FTDI or Silicon Labs chip.
- Parallel: the Centronics printer interface, standardized as IEEE 1284 in 1994, at port 0x378 on IRQ 7. It survives on old industrial machines and, for hobbyists, as a source of simple bit-banged input and output.
WORDS13.7.6 remember these#
- Tunnelling — carrying one protocol inside another — encapsulating PCIe and DisplayPort inside Thunderbolt or USB4 transport.
- Thunderbolt — the high-capacity USB-C link — an Intel interconnect tunnelling PCIe and DisplayPort, now aligned with USB4.
- TRRS — the four-part headphone plug — tip, ring, ring, sleeve, adding a microphone conductor, in CTIA or OMTP wiring.
- 8P8C — the network socket — the eight-position eight-contact modular connector commonly called RJ45.
- UHS — the faster SD card mode — Ultra High Speed bus modes I, II and III.
13.8 What a driver actually is#
PLAIN13.8.1 in simple words#
- A driver is a piece of code that translates.
- On one side it accepts a general request that says nothing about hardware, such as “write these bytes”.
- On the other side it produces the exact numbers that one particular chip needs, written into that chip’s exact registers, in that chip’s exact order.
- That is the whole job. A translator between the general and the specific.
- It exists because there are thousands of different chips that do the same job in different ways.
- Without drivers, every program would need code for every chip ever made.
- With drivers, a program says “write these bytes” and never learns what kind of drive it is.
- A driver is not a program you run. It is code the operating system loads and calls when needed.
- Most drivers live inside the operating system’s core, so a fault in one can bring down the whole machine.
- The operating system chooses which driver to load by matching numbers the device reports about itself.
PLAIN13.8.2 a picture in your head#
- Imagine an international company where head office issues one instruction: “ship this box to the customer”.
- Each country’s office knows its own local rules, forms, languages and couriers.
- Head office never learns those rules. It only knows the one instruction.
- Each local office is a driver. It turns one general instruction into the specific local procedure.
- Replace a courier in one country and only that one office changes. Head office is untouched.
- Now imagine a local office that files a form wrongly and locks the whole company’s systems. That is what a bad kernel driver does.
Where this comparison breaks: a local office can refuse an instruction it does not understand. A driver is usually trusted, running with the same power as the operating system core, so it is believed even when it is wrong.
PLAIN13.8.3 a worked example#
- Follow one key press from finger to screen. This is the exact chain.
finger presses key
-> keyboard matrix scan in keyboard's own chip
-> USB HID report, 8 bytes, on an interrupt endpoint
-> host controller (xHCI) driver takes the transfer
-> USB core hands the report to the matching driver
-> HID class driver decodes the report descriptor
-> input subsystem turns it into a key event
-> keymap turns key code into a character
-> window system sends the character to the focused app
-> the app draws the letter
- Now follow writing a file. The chain runs the other way.
app calls write(fd, buf, 4096)
-> system call: user mode traps into the kernel
-> VFS picks the filesystem for that mount
-> ext4 or APFS or NTFS turns it into block writes
-> block layer queues and merges the requests
-> NVMe class driver builds a command in a queue
-> PCIe driver has already mapped the device's BARs
-> doorbell register write tells the SSD to look
-> SSD firmware does wear levelling and writes flash
-> completion queue entry plus MSI-X interrupt
-> the kernel wakes the waiting application
- Note how many layers are generic and how few are device-specific.
- Only two boxes in each chain know what chip this actually is.
PLAIN13.8.4 what is really happening inside#
- The layers, from top to bottom, always look like this.
- Application: a normal program. Knows nothing about hardware.
- System call: the doorway into the kernel. The processor switches from user mode to kernel mode.
- Kernel subsystem: the generic manager for a category, such as the file layer, the network stack, or the input layer. Defines the general request.
- Class driver: code for a whole family of devices that follow one standard, such as USB mass storage or NVMe. It knows the standard, not the brand.
- Bus driver: code that knows how to find and reach devices on a particular bus, such as PCIe or USB. It enumerates devices, reads their IDs, and hands out address windows and interrupts.
- Device driver: code for one particular chip or chip family. It knows the register map, the quirks, and the initialization sequence.
- Hardware: the chip itself.
- Not every chain has every layer. A well-standardized device may need no vendor-specific driver at all, because the class driver is enough.
- That is why a USB stick works instantly and a graphics card does not: the stick follows a class standard, the graphics card is a custom machine with a proprietary register map.
- Requests travel down and completions travel up. Down is usually a call. Up is usually an interrupt followed by a callback.
TECHNICAL13.8.5 the engineer’s version#
- A driver is defined by the interface it implements, not by what it contains. On Linux it registers a
struct file_operationsor a bus- specificstruct pci_driverwithprobeandremovecallbacks. - Minimal shape of a Linux PCI driver:
static struct pci_device_id ids[] = {
{ PCI_DEVICE(0x8086, 0x100e) }, /* Intel 82540EM */
{ 0, }
};
MODULE_DEVICE_TABLE(pci, ids);
static struct pci_driver drv = {
.name = "mydrv",
.id_table = ids,
.probe = my_probe,
.remove = my_remove,
};
probeis called by the bus core once a device matching the ID table is found. It maps BARs withpci_iomap, requests an interrupt withpci_alloc_irq_vectorsandrequest_irq, sets bus mastering withpci_set_master, and registers with the relevant subsystem.- Vendor ID 0x8086 is Intel, chosen as a reference to the 8086 processor. 0x10DE is NVIDIA, 0x1002 is AMD graphics, 0x10EC is Realtek.
- Windows layers the same idea as a device stack of driver objects: a bus driver creates a physical device object, and function and filter drivers attach device objects above it. Requests travel as IRPs (IO request packets) down the stack.
- macOS and iOS use IOKit, an object-oriented C++ driver framework with a matching dictionary per driver, and a live registry visible with
ioreg. - The system call boundary is the hard security line. On x86-64 Linux the instruction is
syscall; on ARM64 it issvc #0. Everything above it runs unprivileged; everything below can touch any memory. - Timings that explain the layering, order of magnitude only:
| Step | Typical cost |
|---|---|
| Function call | About 1 nanosecond |
| System call | 50 to 400 nanoseconds |
| Interrupt entry/exit | Around 1 microsecond |
| NVMe read completion | 20 to 100 microsecond |
- This cost table is why fast devices use polling again in some paths. Linux NAPI polls a busy network card instead of taking an interrupt per packet, and
io_uring, merged in Linux 5.1 in 2019, exists to avoid system calls per operation. Polling returned not because interrupts got worse but because devices got faster than interrupt handling. - Observe the stack on Linux with
lsmod,modinfo nvme, andls /sys/bus/pci/drivers/. On Windows,pnputil /enum-driversand the Device Manager driver tab. On macOS,kmutil showloadedandioreg -l.
WORDS13.8.6 remember these#
- Driver — the translator for one device — code implementing a kernel interface and driving a specific register map.
- Class driver — one driver for a whole family — a driver implementing a device class standard such as HID or NVMe.
- Bus driver — the code that finds devices — enumerates a bus, reads IDs and allocates resources.
- System call — the doorway into the kernel — a controlled privilege transition such as
syscallorsvc. - Probe — the moment a driver claims a device — the callback the bus core makes when an ID matches.
- Device stack — the chain of code over one device — layered driver objects passing requests down and completions up.
13.9 Driver mechanics#
PLAIN13.9.1 in simple words#
- Code on a machine runs in one of two worlds.
- In user space, code is fenced in. If it goes wrong, only it dies.
- In kernel space, code can touch everything. If it goes wrong, the machine stops.
- Most drivers live in kernel space, because they need direct access to hardware and must respond in microseconds.
- Modern systems move as many drivers as possible into user space, giving up a little speed for a lot of safety.
- Drivers are usually not built into the operating system. They are separate files loaded when a matching device appears.
- Because a driver has total power, operating systems now refuse to load one unless it carries a valid digital signature.
- The signature does not prove the driver is good. It proves who made it and that nobody changed it since.
- Each operating system has its own driver framework, with different names for the same ideas.
- Matching is done by numbers: the device says “I am vendor 0x8086, product 0x100E”, and the system looks for a driver that claims that pair.
PLAIN13.9.2 a picture in your head#
- Think of a hospital. Visitors stay in the public corridors. Surgeons enter the operating theatre.
- User space is the corridor. A visitor who faints causes a small incident.
- Kernel space is the theatre. A surgeon who faints mid-operation is a disaster for the patient.
- So hospitals check credentials at the theatre door, and keep as much work as possible out in the corridors.
- Driver signing is the credential check. It says this person is who they claim, and their badge has not been forged.
- It does not say they are a competent surgeon.
Where this comparison breaks: a hospital can eject a bad surgeon mid- operation. An operating system usually cannot stop a kernel driver that has already corrupted memory. By the time the fault is visible, the damage is done.
PLAIN13.9.3 a worked example#
- On Linux, you plug in a USB-to-serial adapter. Watch what happens.
$ lsusb
Bus 001 Device 007: ID 0403:6001 Future Technology
Devices International, Ltd FT232 Serial (UART) IC
$ dmesg | tail -3
usb 1-2: new full-speed USB device number 7
usbcore: registered new interface driver ftdi_sio
usb 1-2: FTDI USB Serial Device now attached to ttyUSB0
$ ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Aug 13 10:22 /dev/ttyUSB0
- Read that carefully. 0403 is the vendor ID for FTDI. 6001 is the product ID for the FT232 chip.
- The kernel formed a modalias string from those numbers, looked it up, and loaded the module named ftdi_sio.
- The module then created a device node, /dev/ttyUSB0.
188, 0are the major and minor numbers. 188 identifies the driver, 0 identifies which of its devices this is.- From now on, any program can just open /dev/ttyUSB0 like a file. It never needs to know the chip is an FT232.
PLAIN13.9.4 what is really happening inside#
- A loadable module is compiled machine code with a table of symbols it needs and a table of what it provides.
- Loading it means: copy it into kernel memory, resolve its references to kernel functions, run its init function, and register it with the bus core.
- The bus core then walks its list of known devices and calls the new driver’s probe function for each match.
- Unloading runs the reverse, but only if nothing is using the driver.
- A kernel driver shares one address space with the whole kernel. There is no memory protection between it and everything else.
- So a wild pointer write in a driver silently corrupts unrelated kernel data, and the crash may appear minutes later somewhere else entirely.
- A user-space driver runs as an ordinary restricted process. It reaches hardware only through a narrow, checked path the kernel opens for it.
- If it crashes, the kernel closes the handle, resets the device, and can restart the driver. The machine survives.
- The trade is latency and copies. Every crossing between user space and the kernel costs time, so the fastest devices keep kernel drivers.
TECHNICAL13.9.5 the engineer’s version#
- Windows. WDM (Windows Driver Model), introduced with Windows 98 and Windows 2000, is the low-level model of IRPs and device objects. It is powerful and unforgiving.
- WDF (Windows Driver Frameworks) sits above WDM and handles the hard parts, chiefly power management and plug-and-play state. It comes in two forms: KMDF (Kernel-Mode Driver Framework) and UMDF (User-Mode Driver Framework). As of Windows 11 the shipping versions are KMDF 1.33 and UMDF 2.33. Microsoft publishes the framework source on GitHub.
- UMDF version 2 uses the same object model and function names as KMDF, so a driver can be moved between kernel and user mode with modest changes. UMDF version 1, which used COM, is superseded.
- Windows drivers are described by an INF text file listing hardware IDs, which look like
PCI\VEN_10DE&DEV_2484&SUBSYS_...&REV_A1orUSB\VID_046D&PID_C52B. Matching is by longest, most specific ID first. - Windows driver signing history: Windows Vista x64 in 2006 first required kernel-mode drivers to be signed. Since Windows 10 version 1607, released in August 2016, new kernel-mode drivers must be signed by Microsoft through the hardware developer portal, submitted with an EV certificate, either as WHQL-certified or attestation-signed.
- Linux. Drivers are usually loadable kernel modules, files ending in
.ko, loaded withmodprobeor automatically by udev.lsmodlists them;modinfoshows their aliases and parameters. - Character and block devices appear as nodes under
/dev, created automatically by devtmpfs and managed by udev, in practicesystemd-udevdon most distributions. Rules live in/etc/udev/rules.dand/lib/udev/rules.d. /sys, the sysfs filesystem introduced in Linux 2.6 in 2003, exposes the whole device model as directories:/sys/bus/pci/devices,/sys/class/net,/sys/devices/.... It is how userspace discovers hardware without ioctls.- Matching uses modalias strings. Read one directly:
$ cat /sys/bus/usb/devices/1-2/modalias
usb:v0403p6001d0600dc00dsc00dp00ic FFisc FFip FFin00
- Linux has no stable in-kernel driver ABI, by deliberate policy. Drivers are expected to be merged into the mainline tree, where they are updated with the rest of the kernel. Out-of-tree drivers, such as NVIDIA’s, must be rebuilt for each kernel, usually through DKMS.
- Experts genuinely disagree here. Kernel developers argue the unstable ABI forces good code into the tree and lets interfaces improve. Vendors argue it makes proprietary drivers painful. Both are describing the same fact, valuing it differently.
- Linux also supports user-space drivers: FUSE for filesystems, libusb and usbfs for USB devices, VFIO and UIO for direct device access with IOMMU protection, and SPDK and DPDK for polled user-space storage and network drivers.
- macOS. Kexts (kernel extensions) built on IOKit were the traditional model. Apple announced their deprecation at WWDC in June 2019 and introduced DriverKit, which builds driver code as a user-space system extension using the same IOKit-style class model.
- On Apple silicon Macs, loading a kext requires switching to Reduced Security in recoveryOS and approving it, then rebooting. As of 2026 kexts still load on macOS 26 under that reduced security setting, but Apple’s documented guidance is to use DriverKit and system extensions.
- Inspect on macOS with
kmutil showloaded,systemextensionsctl listandioreg -l.
| System | Kernel driver | User-space driver |
|---|---|---|
| Windows | WDM, KMDF | UMDF 2 |
| Linux | Kernel module .ko | FUSE, libusb, VFIO |
| macOS | Kext (IOKit) | DriverKit extension |
- The honest version: “user-space driver” rarely means no kernel code at all. A small kernel stub still owns the interrupt and the IOMMU mapping. What moves out is the large, complex, bug-prone part.
WORDS13.9.6 remember these#
- Kernel space — where trusted code runs — the privileged address space with no memory protection between components.
- Kernel module — a driver file loaded on demand — a relocatable object linked into the running kernel.
- Device node — the file that represents a device — a character or block special file with major and minor numbers.
- sysfs — the folder view of hardware — the kernel object hierarchy exported under /sys.
- udev — the thing that creates device files — the userspace device manager acting on kernel uevents.
- Driver signing — a proof of who wrote it — a cryptographic signature the loader verifies against trusted keys.
- DriverKit — Apple’s safer driver system — a user-space system extension framework replacing kexts.
- Hardware ID — the number that picks the driver — a vendor and product ID string used for driver matching.
13.10 Firmware: code that lives on the device#
PLAIN13.10.1 in simple words#
- Firmware is software that lives inside a piece of hardware rather than on your disk.
- It runs on a small processor inside the device itself, not on your main processor.
- It is there before your operating system starts, and it keeps running after your operating system stops.
- Almost every device has some. A drive, a keyboard, a network chip, a screen, a mouse, a charger.
- It is called firm-ware because it sits between hardware, which cannot change, and software, which changes all the time.
- Long ago it truly could not be changed. Today it is stored in flash memory and can be rewritten.
- That is useful, because bugs in firmware are common and often serious.
- It is also dangerous, because a failed rewrite can leave a device that cannot start at all.
PLAIN13.10.2 a picture in your head#
- Think of a vending machine. The metal box is the hardware.
- The instructions inside its controller, deciding what happens when you press B4, are the firmware.
- The price list you load in is data. The app you use to pay is software on your phone.
- Changing the firmware changes what the machine does, permanently, even with nobody around.
- And if the engineer’s update fails halfway, the machine will not open its door for anyone, because the instructions are now half old and half new.
Where this comparison breaks: a broken vending machine can be opened with a key. Many devices have no recovery route once their only firmware image is damaged, which is what “bricked” means.
PLAIN13.10.3 a worked example#
- Here is where firmware sits in one ordinary laptop.
| Device | Firmware does what |
|---|---|
| Motherboard flash | Starts the machine |
| SSD controller | Wear levelling, mapping |
| Keyboard chip | Scans the key matrix |
| WiFi module | Runs the radio timing |
| GPU (VBIOS) | Powers up, sets display |
| Monitor scaler | Scaling, menus, inputs |
- Count them. That is six separate processors running six separate programs, before your operating system even loads.
- A modern laptop typically contains between ten and thirty small processors you never see.
PLAIN13.10.4 what is really happening inside#
- Firmware is stored in non-volatile memory, usually NOR flash for code that must run in place, or NAND flash with a small loader.
- When power arrives, the device’s own small processor starts at a fixed address inside that flash and begins executing.
- Some devices do not store their firmware at all. They start empty, and the driver on your machine uploads the firmware image at every boot.
- That is why some WiFi and graphics cards need a firmware package installed separately from the driver, and do nothing without it.
- Updating firmware means erasing a block of flash and writing a new image, then verifying it.
- If power is lost between the erase and the verify, the device has no valid image, and the small processor has nothing valid to run.
- Careful designs avoid this with two images: write to the spare slot, verify it, then flip a pointer. If anything fails, the old image is untouched.
TECHNICAL13.10.5 the engineer’s version#
- Firmware update mechanisms in use today: UEFI capsule updates for system firmware, vendor tools for SSD and GPU firmware, DFU (device firmware upgrade) class for USB devices, and I2C or DDC/CI for monitor scalers.
- On Linux,
fwupdwith the Linux Vendor Firmware Service delivers signed firmware for participating vendors. Commands:fwupdmgr get-devicesandfwupdmgr update. On Windows, firmware arrives through Windows Update as a firmware driver package. On macOS, firmware ships inside system updates. - Real firmware bugs with real consequences. In November 2019 Hewlett Packard Enterprise issued an urgent bulletin: certain SAS solid state drives would fail permanently, with total data loss, at exactly 32,768 hours of power-on time. That number is 2 to the power 15, a signed 16-bit counter overflowing.
- Samsung’s 840 EVO drives, from 2013, slowed dramatically when reading old data, and the fix was a firmware change to the drive’s read-retry and refresh behaviour, shipped in 2014 and again in 2015.
- Intel and AMD ship processor microcode updates, which are firmware for the processor itself, loaded by the platform firmware or by the operating system at every boot. The Spectre and Meltdown mitigations of 2018 arrived partly this way.
- Firmware is a security surface. It runs before any operating system protection exists, and it survives reinstalling the operating system. Attacks that persist in firmware are the reason for Boot Guard, signed capsules and measured boot into a TPM.
- Redundancy schemes: dual-BIOS boards with a backup chip, A/B slots on phones and network gear, and USB BIOS Flashback, which rewrites the flash using a small always-on controller with no processor or memory installed.
- The plain difference, stated once and clearly:
| Thing | Where it lives | Who runs it |
|---|---|---|
| Firmware | Flash on the device | The device’s chip |
| Driver | OS kernel or system | Your main CPU |
| Software | Your disk | Your main CPU |
- The honest version: the boundary is not sharp. A GPU driver contains blobs that get uploaded to the card and run there, which makes them firmware delivered by a driver. Classification follows what runs where, not which file it arrived in.
WORDS13.10.6 remember these#
- Firmware — code inside the device — non-volatile program executed by an embedded controller.
- Flashing — rewriting firmware — erasing and reprogramming non-volatile memory with a new image.
- Bricked — dead after a failed update — an unbootable device with no valid firmware image and no recovery path.
- Microcode — firmware for the processor — patches to the CPU’s internal instruction decoding, loaded at boot.
- DFU — the standard USB update mode — Device Firmware Upgrade class.
- A/B slots — two copies of the firmware — redundant images with an atomic pointer switch for safe updates.
13.11 BIOS and UEFI#
PLAIN13.11.1 in simple words#
- When you press power, your processor has no operating system, no drivers, and no idea what is attached.
- Something must wake it, test the basics, find a disk, and load the first piece of the operating system.
- That something is the platform firmware, stored on the small flash chip on the board.
- The old version, from 1981, was called BIOS, short for Basic Input Output System.
- The modern replacement is called UEFI, short for Unified Extensible Firmware Interface.
- BIOS was simple and limited: it loaded 512 bytes from the start of a disk and jumped into them.
- UEFI is far larger. It can read a real filesystem, keep a list of things it can boot, and check signatures before running them.
- Both do the same job. Only UEFI can handle large disks, many boot options and modern security.
PLAIN13.11.2 a picture in your head#
- BIOS is a caretaker with one instruction: go to the front desk of the building, read the note pinned there, and do whatever it says.
- The note is tiny, so it usually says “go to room 4 and read the longer note there”.
- UEFI is a caretaker with a real address book. It knows several buildings, remembers which one you preferred, and checks each visitor’s identity card before letting them in.
Where this comparison breaks: the identity check, Secure Boot, only verifies the visitor at the door. Once the operating system kernel is running, it can do whatever it likes. Secure Boot does not keep watching.
PLAIN13.11.3 a worked example#
- Here is the first second after you press the power button.
0 ms power supply stabilizes, asserts POWER_GOOD
the CPU is held in reset until then
~1 ms reset released; CPU starts at its reset
vector, the top of the address space
~2 ms firmware runs from flash; no RAM works yet
so cache is used as temporary memory
10-2000 memory training: the controller tunes the
ms timing of every DDR5 signal, then tests RAM
then POST: check CPU, RAM, basic chips
then enumerate PCIe and USB, assign addresses
then read boot order from NVRAM settings
then load the boot file from the EFI partition
then hand control to the bootloader
- Memory training is why a machine with new DDR5 memory can appear dead for thirty seconds on its very first boot, and start in three seconds after.
- The result of the training is cached, so it only happens once.
PLAIN13.11.4 what is really happening inside#
- POST means power-on self test. The firmware checks the processor, tests enough memory to work, and initializes the basic chips.
- If it fails before a screen exists, it must report through beeps, board LEDs or a two-digit code display. That is why beep codes exist.
- Then it enumerates buses. It walks every PCIe and USB port, reads the ID of whatever is there, and assigns address windows and interrupts.
- Then it looks for something to boot.
- Old BIOS did this by reading the first 512 bytes of each disk in a configured order, checking for the two marker bytes 0x55 0xAA at the end, and jumping into that code.
- 512 bytes is almost nothing, so that code’s only job was to find and load a bigger loader.
- UEFI does it differently. It reads a real FAT-formatted partition on the disk, called the EFI System Partition, and runs a normal executable file from it.
- UEFI also keeps a list of boot entries in its own non-volatile memory, each naming a device and a file path, plus an order to try them in.
- Settings and the clock survive power loss because of the coin cell. Remove it and the settings return to defaults, which is the standard fix for a forgotten firmware password on older boards.
TECHNICAL13.11.5 the engineer’s version#
- The IBM PC of 1981 shipped an 8 KB BIOS ROM, and IBM printed its full assembly listing in the technical reference manual. Compaq in 1982 and Phoenix Technologies in 1984 produced clean-room compatible versions, which is what created the PC clone industry.
- BIOS ran in 16-bit real mode with a 1 MiB address space and offered services through software interrupts, notably INT 13h for disk and INT 10h for video.
- The replacement effort began at Intel in 1998 as the Intel Boot Initiative, for Itanium, becoming EFI. Intel stopped at EFI 1.10 in 2005 and gave it to the Unified EFI Forum. UEFI 2.0 was published on 31 January
- Version 2.11 was published in December 2024.
- UEFI runs in 32-bit or 64-bit mode, has a driver model of its own, a shell, and services split into boot services and runtime services. Runtime services survive into the running operating system, which is how a system can set its own next boot entry.
- The EFI System Partition is FAT12, FAT16 or FAT32, conventionally at least 100 MB and often 512 MB, with GUID type C12A7328-F81F-11D2-BA4B- 00A0C93EC93B. The default fallback path is
\EFI\BOOT\BOOTX64.EFI. - Boot entries are UEFI variables named Boot0000, Boot0001 and so on, with BootOrder listing the sequence and BootCurrent naming the one used.
$ efibootmgr -v
BootCurrent: 0002
BootOrder: 0002,0000,0001
Boot0000* Windows Boot Manager HD(1,GPT,...)/File(\EFI\...)
Boot0002* ubuntu HD(1,GPT,...)/File(\EFI\ubuntu\shimx64.efi)
- On Windows the equivalent tool is
bcdedit /enum firmware. - GPT (GUID Partition Table) is part of the UEFI specification. MBR with 512 byte sectors cannot address beyond 2 TiB; GPT uses 64-bit LBAs, keeps a backup table at the end of the disk, protects both with CRC32, and supports 128 entries by default. The UEFI specification requires firmware to support GPT; booting from MBR was handled by the Compatibility Support Module, which Intel removed from client platforms around 2020.
- Secure Boot was added in UEFI 2.3.1, released on 6 April 2011, and enforced on Windows 8 logo machines from 2012. It verifies the signature of each executable the firmware loads against a key hierarchy: PK, the platform key; KEK, key exchange keys; db, allowed signatures; and dbx, the revocation list.
- What Secure Boot actually verifies: the bootloader, the firmware drivers it loads, and, if the operating system continues the chain, the kernel. What it does not verify: your hardware, your applications, your data, or anything after the kernel takes over. It is a chain of trust for boot, not an antivirus.
- Linux distributions boot under Secure Boot through
shim, a small loader signed by Microsoft’s third-party UEFI CA, which then verifies the distribution’s own key. - Current and dated: Microsoft’s 2011-generation Secure Boot certificates reach the end of their validity through 2026, and are being replaced by 2023-dated certificates via firmware and operating system updates. If you read this after 2026, check the current state rather than trusting this line.
- Chapter 18 picks the story up here: from the moment the bootloader is running and begins to load an operating system kernel.
WORDS13.11.6 remember these#
- POST — the start-up self test — power-on self test of CPU, memory and core chipset before boot.
- Reset vector — the first instruction address — the fixed address the CPU fetches from after reset.
- BIOS — the old start-up firmware — 16-bit real-mode firmware with INT-based services and MBR booting.
- UEFI — the modern replacement — a specification with its own executables, FAT system partition and boot variables.
- ESP — the boot partition — the EFI System Partition holding UEFI executables.
- GPT — the modern partition table — GUID Partition Table with 64-bit addressing and CRC-protected redundant headers.
- Secure Boot — signature checking at boot — verification of loaded images against the PK, KEK, db and dbx key stores.
13.12 Plug and play, resources and conflicts#
PLAIN13.12.1 in simple words#
- Every device needs three things reserved for it: an address range, an interrupt number, and sometimes a data-moving channel.
- If two devices are given the same one, both misbehave, often in confusing ways.
- In the 1980s and early 1990s you set these by hand, by moving tiny plastic caps called jumpers on the card itself.
- You had to know what everything else in the machine already used, and read the manual for each card.
- Plug and play was the promise that the machine would work this out by itself.
- It works by having each device describe what it needs, rather than demand a fixed setting.
- The firmware and the operating system then assign resources so nothing overlaps.
- Today conflicts are rare, and when they appear they are almost always a driver problem rather than a real hardware clash.
PLAIN13.12.2 a picture in your head#
- Old cards were like guests who each insisted on a specific seat number printed on their own ticket.
- If two guests printed the same number, you had to reprint one ticket by hand before the meal could start.
- Plug and play is guests who say “I need one seat near a window” and let the host do the seating plan.
- The host has the full list and can always find an arrangement.
Where this comparison breaks: a host can seat anyone anywhere. Some hardware still only works at fixed addresses, so the seating plan has permanent reserved places it must work around.
PLAIN13.12.3 a worked example#
- A 1993 machine with a sound card and a network card, set by jumpers.
| Device | IO port | IRQ | DMA |
|---|---|---|---|
| Sound Blaster | 0x220 | 5 | 1 |
| Network card | 0x300 | 10 | - |
| LPT1 printer | 0x378 | 7 | - |
| COM1 serial | 0x3F8 | 4 | - |
- Set the network card to IRQ 5 by mistake and both cards break: the sound stutters and the network drops, because two devices pull one shared line.
- The fix was physical. Power off, open the case, move a jumper, close, boot, and test.
- Today the same information is assigned automatically at every boot, and can change between boots without anything breaking.
PLAIN13.12.4 what is really happening inside#
- A PCI or PCIe device has a small configuration space that anyone can read before the device is configured.
- It contains the vendor ID, product ID, class code, and a set of base address registers describing how much address space it wants.
- The firmware reads all of these, builds a map with no overlaps, and writes the chosen addresses back into the device.
- Interrupts are assigned the same way, and with message-signalled interrupts there is no physical line to share at all, so classic conflicts simply cannot happen.
- ACPI adds a description of everything that is not discoverable: which interrupt the embedded controller uses, what the power buttons are, how the fans and sleep states work.
- So the operating system reads devices from the buses and reads non-discoverable parts from ACPI tables, and combines both into one tree.
TECHNICAL13.12.5 the engineer’s version#
- ISA Plug and Play was specified by Intel and Microsoft in 1993, using an isolation protocol at ports 0x279 and 0xA79 to enumerate cards that could not otherwise be discovered. It was fragile enough to earn a bad reputation in the Windows 95 era.
- PCI configuration space is 256 bytes per function, extended to 4096 bytes in PCIe. Access is through ports 0xCF8 and 0xCFC in the legacy mechanism, or through the memory-mapped ECAM region described by the ACPI MCFG table.
- ACPI 1.0 was published in December 1996 by Intel, Microsoft and Toshiba. It is now maintained by the UEFI Forum, which took it over in 2013. Current revisions are 6.x.
- ACPI tables to know: DSDT and SSDT contain the AML bytecode describing devices, MADT describes interrupt controllers, MCFG describes PCIe configuration space, and FADT holds fixed hardware descriptions.
- Windows Device Manager error codes you will actually meet: Code 10, the device cannot start, usually a driver or firmware fault; Code 12, not enough free resources, the modern trace of a genuine resource conflict; Code 28, no drivers installed; Code 43, the driver reported a failure.
- Code 12 today is usually not two devices fighting over one IRQ. It is normally exhausted PCIe lanes or, on older 32-bit systems, exhausted address space below 4 GiB.
- Inspect resource assignment on Linux with
cat /proc/iomem,cat /proc/ioportsandlspci -vv. On Windows usemsinfo32and look under Hardware Resources for Conflicts/Sharing. - The honest version: interrupt sharing is still normal and correct on legacy PCI lines. Several devices on one line is not a conflict. A conflict is when the same exclusive resource is claimed twice.
WORDS13.12.6 remember these#
- Jumper — a manual setting cap — a shorting block across two header pins selecting a hardware option.
- Resource — something a device must be given — an IO range, memory window, interrupt or DMA channel.
- Plug and play — automatic setup — enumeration and dynamic resource allocation without user configuration.
- Configuration space — the device’s self-description — the 256-byte or 4096-byte PCI header with IDs and BARs.
- ACPI — the description of the rest of the board — tables and AML bytecode describing power, and non-discoverable devices.
13.13 System-on-chip: when the whole board fits on one die#
PLAIN13.13.1 in simple words#
- A phone has no slots, no card connectors and no chipset you can point at.
- Nearly everything discussed in this chapter has been folded onto a single piece of silicon called a system-on-chip, or SoC.
- The processor, graphics, memory controller, camera processor, radio controller, video decoder and security block all sit on one die.
- The memory is usually stacked directly on top of the same package.
- Nothing is removable, so nothing needs a slot, a connector or a plug and play discovery process.
- The parts still talk to each other over buses, but those buses are inside the chip, made of metal layers, not board traces.
- Because nothing can be discovered by asking, the software must be told in advance what exists and where. That description is called a device tree.
PLAIN13.13.2 a picture in your head#
- A desktop is a town with separate buildings and roads between them.
- A system-on-chip is a single very large building, where every department is a room on the same floor.
- Walking between rooms is far quicker than driving between buildings, and uses far less energy.
- But you cannot add a new department. The building is finished.
- And there is no directory at the entrance, because the plan was fixed when it was built. Everyone must be handed a map instead.
Where this comparison breaks: parts of the chip can still be discovered. A PCIe controller inside an SoC enumerates its own devices exactly as a desktop does. It is the fixed on-chip blocks that need the map.
PLAIN13.13.3 a worked example#
- A device tree entry describing a serial port on an ARM board looks like this.
uart0: serial@fe215040 {
compatible = "brcm,bcm2835-aux-uart";
reg = <0xfe215040 0x40>;
interrupts = <0 93 4>;
clocks = <&aux_clk>;
status = "okay";
};
- Read it line by line.
compatibleis the matching key, the equivalent of a vendor and product ID. regsays the registers start at address 0xFE215040 and occupy 0x40, that is 64, bytes.interruptssays which interrupt line it uses.clockssays which clock must be switched on before it works.- The kernel reads this, finds the driver whose compatible string matches, and calls its probe function with the address and interrupt filled in.
- That is exactly the same probe mechanism as PCIe, with the tree taking the place of bus enumeration.
PLAIN13.13.4 what is really happening inside#
- Inside the chip, blocks connect to a shared on-chip fabric: a set of wide internal buses with an arbiter deciding who gets access.
- Fast blocks such as the processor and graphics sit on a wide, high-speed part of the fabric. Slow blocks such as a serial port sit on a narrow, cheap part behind a bridge.
- Wide parallel buses are fine here, because the distance is millimetres and fixed at design time, so skew is controlled by the layout tools.
- The device tree is compiled into a binary blob and handed to the kernel by the bootloader at start-up.
- So the boot chain is: chip’s internal ROM, then a small first-stage loader, then a full bootloader, then the kernel plus the device tree.
- On x86 machines the same job is done by ACPI tables from the firmware. Arm servers use ACPI too; Arm phones and embedded boards use device trees.
TECHNICAL13.13.5 the engineer’s version#
- On-chip interconnect standards come mostly from Arm’s AMBA family: AXI for high-performance memory traffic, AHB for medium speed, and APB for slow peripheral registers. Larger chips use a network-on-chip with routers rather than a single bus.
- Device tree came from Open Firmware, standardized as IEEE 1275 in 1994 and used by Sun and Apple PowerPC machines. Linux adopted it for PowerPC and then for Arm, source files ending
.dts, compiled bydtcinto.dtb. - Arm Linux switched to device trees around Linux 3.x, from 2011 onward, replacing thousands of lines of hardcoded board files.
- Why phone drivers age badly. An SoC vendor ships a board support package: a kernel fork with hundreds of out-of-tree drivers. Because Linux has no stable in-kernel driver ABI, moving to a newer kernel means porting all of them. Vendors support a chip for a few years and then stop.
- Google’s Project Treble, introduced with Android 8.0 in 2017, split the vendor implementation from the Android framework behind a stable interface called the HAL, so the framework could be updated without the vendor’s code changing.
- The Generic Kernel Image work, from Android 11 onward, went further: one common kernel binary with vendor code confined to loadable modules across a defined module interface. Google Pixel and Samsung Galaxy devices now advertise seven years of updates, which was not possible under the old model.
- Inspect on a running Linux SoC:
ls /proc/device-tree/ # the live tree
cat /proc/device-tree/model # the board name
dtc -I fs -O dts /proc/device-tree | less
- The honest version: “no slots” is not quite true. Many SoCs expose PCIe and USB, and a laptop built on an SoC still has USB-C ports that enumerate normally. What disappeared is the socketed, replaceable, discoverable internal hardware, not discoverable buses in general.
WORDS13.13.6 remember these#
- SoC — the whole computer on one chip — a die integrating CPU, GPU, memory controller and peripherals.
- Fabric — the buses inside the chip — an on-chip interconnect such as AMBA AXI or a network-on-chip.
- Device tree — the map of fixed hardware — a data structure describing non-discoverable devices, compiled to a DTB.
- Compatible string — the matching key — the device tree property a driver binds to, in place of a vendor and product ID.
- Board support package — the vendor’s kernel fork — a chip-specific kernel plus out-of-tree drivers.
13.98 Common wrong ideas#
- Wrong: a driver is a program you install and run. Right: it is code the operating system loads and calls; you never start it yourself, and it has no window.
- Wrong: more wires means faster, so parallel beats serial. Right: above a few hundred megahertz, skew and crosstalk make wide buses unusable, which is why every fast modern link is narrow and serial.
- Wrong: a USB-C port supports fast data, video and 240 W charging. Right: USB-C is only a connector shape. A USB-C port may be limited to USB 2.0 at 480 Mbit/s and 7.5 W. Only the specification sheet tells you.
- Wrong: a card in an x16 slot always gets sixteen lanes. Right: the connector size and the wired electrical width are separate. A full-length slot may be wired x4, or drop to x8 when another slot is used.
- Wrong: firmware and drivers are the same thing. Right: firmware runs on the device’s own processor and lives in the device’s flash. A driver runs on your processor inside your operating system.
- Wrong: Secure Boot stops malware. Right: it verifies signatures on boot-time executables against firmware key stores. It does nothing about anything that runs after the kernel starts.
- Wrong: interrupts are always better than polling. Right: at very high event rates, interrupt overhead dominates. Fast network and storage paths deliberately poll, using NAPI, DPDK or SPDK.
- Wrong: two devices sharing an interrupt is a conflict. Right: shared level-triggered lines are normal and correct. A conflict is two claims on the same exclusive resource, and message-signalled interrupts removed most of that possibility.
- Wrong: USB 3.2 Gen 2x2 is newer and therefore faster than USB4. Right: Gen 2x2 is 20 Gbit/s. USB4 reaches 40 Gbit/s, and USB4 Version 2.0 reaches 80 Gbit/s. The version numbers do not sort by speed.
- Wrong: signed drivers are safe drivers. Right: a signature proves origin and integrity, not correctness. Signed drivers with serious bugs and exploitable flaws are shipped regularly.
13.99 Chapter summary in 20 lines#
- A motherboard is a fixed set of sockets, slots, chips and printed wires, each with one job.
- Fast parts sit close to the processor because high-speed wires must be short and length-matched.
- A bus carries address, data and control, and a shared bus lets only one talker speak at a time.
- Parallel buses died above a few hundred megahertz because of skew, crosstalk and electrical loading.
- Serial point-to-point links won by moving the hard problem into silicon: scrambling, equalization and clock recovery.
- Bandwidth is transfers per second times width times coding efficiency; PCIe 3.0 x1 is 8 GT/s x 128/130 / 8, about 985 MB/s each way.
- The bus story runs ISA in 1981, VESA Local Bus in 1992, PCI in 1992, AGP in 1997, then PCI Express from 2003 to now.
- Connector size and electrical width are separate; bifurcation splits one wide link into several narrower ones.
- A processor reaches a device through memory-mapped registers or, on x86 only, a separate port space.
- Polling burns cycles, interrupts free them, and direct memory access removes the processor from bulk transfers entirely.
- The IOMMU translates and checks every device memory access, which is what makes Thunderbolt and virtual machine passthrough safe.
- Interrupts run from line or message, through a controller, to a vector, to a short handler, with the slow work deferred to a bottom half.
- USB has one host, a tiered star of hubs, endpoints, pipes and four transfer types, and enumerates in a fixed nine-step sequence.
- USB naming has been rewritten twice; as of 2026 the guidance is speed labels: USB 5Gbps through USB 80Gbps.
- USB-C is a 24-pin connector from 2014, not a protocol and not a speed.
- Thunderbolt tunnels PCI Express and DisplayPort inside one link, reaching 80 Gbit/s in Thunderbolt 5 from 2023.
- A driver translates a general operating system request into one specific chip’s registers, sitting under a class driver and above the hardware.
- Windows uses WDM and WDF with KMDF and UMDF, Linux uses kernel modules with sysfs and udev, macOS is replacing kexts with DriverKit.
- Firmware runs on the device’s own processor from its own flash, before and after your operating system, and a failed update can brick the device.
- Platform firmware, BIOS then UEFI, runs POST, enumerates buses, reads its boot entries and loads a bootloader; Chapter 18 continues from there.