From power rail
to prompt.
+ Before we start
There is a gap between pressing the power button and the existence of an operating system. That gap is where this guide lives.
Most explanations of computers begin after the operating system is running. That is a fair simplification for most purposes, but it makes a whole class of problems unintelligible. If a machine freezes before Windows has executed a single instruction, no amount of knowledge about Windows will help.
So we start earlier — at the power supply — and work up through the chips that wake first, follow the boot chain stage by stage, and reach the operating system near the end. Along the way we look hard at one thing that matters enormously and is rarely discussed: the small amount of writable non-volatile memory that firmware keeps for itself, and what happens when it fills.
Every concept here has a direct counterpart on a microcontroller. A PC boot chain and an STM32 boot chain are the same idea at different scales. Part VI makes the mappings explicit, and the green-edged boxes flag the connection as it arises.
+ Part I
The physical layer.
Before any code runs there is a board with chips on it and voltage arriving from a wall socket. This part establishes what is physically present, what powers it, and in what order things come alive.
What firmware is, and why it has to exist.
A processor coming out of reset can do exactly one thing: fetch an instruction from a fixed address and execute it. It has no concept of a disk, a file, a partition, or an operating system. Those are abstractions built by software, and at power-on no software has run.
This creates a bootstrapping problem. The operating system lives on an SSD. To read the SSD you need a driver. Drivers are part of the operating system. To load the operating system you must read the SSD. Something has to break the circle.
Firmware is the code that breaks it. It lives in a memory chip the processor can address directly at power-on, needing no driver and no filesystem to reach. Its job is to bring up enough of the machine — memory, buses, storage controllers — that a real operating system can be located and loaded.
On a modern PC this firmware implements a specification called UEFI, which replaced the older BIOS design. People still say "the BIOS," and vendors still label the setup screen that way, so this guide uses both terms where no confusion results.
Firmware is not the operating system, and the boundary is sharp
It is worth being precise about the handover, because many troubleshooting mistakes come from blurring it. Firmware and the operating system do not run together. Firmware runs, does its work, loads the OS loader, and then — at a specific call named ExitBootServices — surrenders control and tears down most of its own machinery.
The consequence is practical. If a machine fails before that handover, nothing the operating system can do will change the outcome. Reinstalling Windows, repairing the bootloader, running sfc /scannow — all of these operate on the far side of a boundary the machine never reached.
The flash chip: where firmware physically lives.
Firmware is stored on a dedicated chip on the motherboard, typically an SPI NOR flash device of 16 or 32 megabytes — a small eight-pin package, socketed on some enthusiast boards and soldered on consumer ones.
Two properties of NOR flash shape everything that follows.
It is byte-addressable for reads. The processor can fetch instructions directly from it, which is precisely what is needed at reset. This distinguishes it from the NAND flash in an SSD, which reads only in large pages and needs a controller and a driver.
Writes are asymmetric and destructive. A bit can be cleared from 1 to 0 by programming. A bit cannot be set from 0 back to 1 individually — you can only erase an entire block, typically 4 KB, which returns every bit in it to 1. This asymmetry shapes the design of everything stored on the chip, and it is the root cause of the fault studied in Part V.
The one writable region
Everything on that chip other than the magenta band is written once, at manufacture or during a firmware update, and read thereafter. The NVRAM region is different: it is written during normal operation, by the firmware itself and by the operating system, potentially many times per boot.
It is also small — a few hundred kilobytes against a 32 MB chip. Chapters 10 to 13 are devoted to it, because a region that is small, writable, subject to erase-block constraints, and written by two independent parties is exactly the kind of thing that fails in interesting ways.
Power rails, and what "off" actually means.
A desktop power supply does not produce one voltage. It produces several, and it does not produce them all at the same times. Knowing which rails are live when is the single piece of knowledge that explains the fault in Part V.
| Rail | Voltage | Powers | Live when |
|---|---|---|---|
+12V | 12 V | CPU, GPU, motors, fans | System running only |
+5V, +3.3V | 5 V, 3.3 V | Logic, drives, most chips | System running only |
+5VSB | 5 V standby | Embedded controller, power button logic, wake circuits, some USB ports | Whenever mains is connected |
VBAT | ~3 V coin cell | Real-time clock, a small amount of CMOS state | Always, even unplugged |
The standby rail is the important one. When you shut a desktop down, it is not off. Mains is still connected, the supply is still producing 5 V standby, and enough circuitry remains energised to watch the power button, listen for wake-on-LAN packets, charge a phone on some USB ports, and hold state.
+5VSB — before any other diagnostic step is taken.
The power button is a request, not a switch
On any machine built since the late 1990s the front power button is a momentary contact wired into standby-powered logic. Pressing it connects and disconnects nothing. It asserts a signal the embedded controller reads, and the controller decides what to do.
A short press is a request the operating system can handle gracefully. A four-second hold is an override: the controller drops the main rails regardless of what software wants. Even the override leaves +5VSB untouched, because the controller itself runs on that rail — cutting it would be cutting its own power.
VBAT keeps the RTC and backup registers alive across a full VDD loss, and a system reset does not clear them. If you have ever chased a bug where state survived what you thought was a full reset, you have met this problem. Multi-domain power is why "reset" is an ambiguous word in hardware, and why you must always ask which reset.
Who is actually on the board.
A modern PC is not one processor. It is several independent processors that boot in sequence, and the main CPU is not the first of them.
| Component | Role | Wakes |
|---|---|---|
| EC — embedded controller | Small microcontroller. Watches the power button, sequences the rails, controls fans and thermals | First — runs on standby |
| PCH — chipset | Owns SPI flash access, USB, SATA, PCIe lanes, the real-time clock | Second |
| ME — Management Engine | Independent processor inside the PCH with its own firmware | Before the main CPU |
| CPU | Runs UEFI, then the operating system | Last |
That ordering has a consequence worth sitting with. By the time your CPU executes its first instruction, at least two other processors on the board have already booted and are running their own code. If one of them is stuck, the CPU may never be released from reset — and the screen shows nothing, or a logo, indefinitely.
+ Part II
The boot chain.
Now we follow the machine forward in time, from the instant mains voltage is applied to the moment the operating system takes over. This is a strict sequence, and each stage depends on the one before it.
Power-on sequencing.
Before any instruction executes, a choreography of signals has to complete. Rails must come up in a defined order, settle within tolerance, and be confirmed stable — and only then is the CPU released from reset. Rushing this would mean executing instructions on unstable voltage, which produces failures that look random and are nearly impossible to debug.
| Signal | Meaning |
|---|---|
PS_ON# | Asserted by the EC to tell the supply to bring up the main rails. The # means active-low: pulling it to ground turns the supply on. |
PWR_OK | Asserted by the supply once the main rails are in tolerance. The supply's own statement that it is ready. |
RSMRST# | Resume reset. Releases the standby-powered portion of the chipset. De-asserts once +5VSB is stable. |
PLTRST# | Platform reset. The big one. When this de-asserts, the CPU begins fetching instructions. |
+5VSB and RSMRST# come up as soon as mains is applied and stay up through a soft-off, any state established in that window persists across a power-button hold. Removing mains forces the whole sequence to restart from the left edge of plate 05.
The reset vector, and running without memory.
When PLTRST# de-asserts, the CPU begins executing at a hardwired address called the reset vector. On x86 this is 0xFFFFFFF0 — sixteen bytes below the top of the 32-bit address space. That address is not RAM. The chipset maps it onto the top of the SPI flash chip, so the very first fetch lands in the boot block shown in amber in plate 02.
There is an immediate problem: DRAM does not work yet. Memory controllers need configuration, and DDR5 needs elaborate calibration before a single byte can be reliably stored. So the earliest firmware code runs with no usable RAM — no stack, no heap, no variables in the ordinary sense.
The solution is a trick called Cache-as-RAM. The CPU's own cache is placed in a mode where it behaves as a small block of ordinary memory, disconnected from the DRAM behind it. That gives early firmware a few hundred kilobytes of scratch space — enough to run a stack and get the memory controller working.
The UEFI phase model
UEFI organises all of this into named phases. These abbreviations appear in any firmware documentation, so they are worth learning.
Memory training, and why it is cached.
DDR5 runs at signalling rates where the electrical delay along a circuit-board trace is a significant fraction of a clock period. Making it work is not a matter of setting a frequency register. The memory controller must empirically determine, for every data lane, the exact timing at which signals should be sampled — sweeping delays, writing test patterns, reading them back, and building a map of what works.
This is memory training, run by the Memory Reference Code during the PEI phase. On a DDR5 system with several ranks it can take from a few seconds to well over half a minute.
Half a minute of black screen on every boot would be unacceptable, so firmware caches the result. The trained timings are written to non-volatile storage, and on later boots the firmware checks whether the configuration still matches — same modules, same slots, same settings — and if so loads the saved values instead of retraining.
DXE and BDS: building a working machine.
With real memory available, firmware can behave like ordinary software. The DXE phase — Driver Execution Environment — loads a large collection of drivers from the flash chip and executes them. These enumerate the PCIe bus, initialise USB controllers, bring up the storage controllers, set up graphics output, and start the TPM.
This is where the vendor logo appears, because it is the first point at which a display exists to draw on.
DXE is also where the largest number of things can go wrong, precisely because it is where the machine touches the outside world. Every USB device is enumerated. Every PCIe device is probed. A device that responds incorrectly, or does not respond at all, can stall the enumeration loop — and since the logo is already on screen, the symptom is a frozen logo.
The BDS phase — Boot Device Selection — then decides what to boot. It reads a list of boot options from the NVRAM variable store, tries them in order, and hands control to the first that works.
The handoff, and warm versus cold.
The bootloader loads the kernel, then calls ExitBootServices. At that moment firmware tears down its own drivers and memory allocations and hands ownership of the hardware to the operating system. A small residue called runtime services survives — and one of the things it provides is the interface through which the operating system reads and writes UEFI variables. That becomes important in chapter 13.
Not all restarts are equal
This distinction is essential for understanding the fault in Part V.
| Type | What happens | Device state |
|---|---|---|
| Warm reset a normal restart | PLTRST# is asserted and released. Rails stay up throughout. | Devices are not power-cycled. Many retain internal state. |
| Cold boot shutdown, then start | Main rails drop, then return. Standby stays up. | Most devices re-initialise. Standby-powered ones do not. |
| Mechanical off mains removed | Every rail except the coin cell collapses. | Everything re-initialises from scratch. |
A device or controller that mishandles a warm reset — that does not correctly re-initialise when its power was never interrupted — will fail on restarts while working perfectly on cold boots. This is a real and common class of fault, and it produces exactly the selective symptom pattern we are investigating.
+ Part III
The store that fills up.
This part is the heart of the guide. Everything so far has been context for one small region of flash that firmware and the operating system both write to — and that behaves in ways neither of them entirely controls.
What a UEFI variable actually is.
A UEFI variable is a named blob of bytes that survives power loss. It is the firmware's equivalent of a configuration file, except there is no filesystem — just a region of flash and a set of conventions for carving it up.
Each variable has four parts.
| Part | Purpose |
|---|---|
| Namespace GUID | A 128-bit identifier that scopes the name. Two vendors can both define a variable called Config without collision, because their GUIDs differ. |
| Name | A UTF-16 string — BootOrder, Boot0003, SecureBoot, dbx. |
| Attributes | A bitfield. The important flag is NON_VOLATILE: set, the variable is written to flash; clear, it lives only in RAM until reset. Others control whether the operating system can access it after ExitBootServices, and whether writes must be cryptographically authenticated. |
| Data | The payload. Anywhere from four bytes to tens of kilobytes. |
Who writes these
Two independent parties write to the same store, and neither has full visibility of the other.
The firmware writes boot entries, boot order, setup options, memory training results, error records, and Secure Boot key databases.
The operating system writes through the runtime services interface that survived ExitBootServices. On Windows this happens through SetFirmwareEnvironmentVariable. The operating system creates and updates boot entries, stages firmware update requests, and — depending on platform and version — records diagnostic and event data.
Inside the store: an append-only log.
Because flash cannot rewrite a byte in place, the variable store is not organised as a table that gets edited. It is organised as an append-only log.
Updating a variable does not modify the existing record. It writes a complete new record at the end of the used space, then clears bits in the old record's state byte to mark it superseded. The old record stays exactly where it is, consuming exactly as much room as before.
The consequence is direct and slightly alarming: every write to a UEFI variable consumes free space, including writes that merely change a value that already exists. Update BootOrder a thousand times and you have a thousand records, of which one is live.
Fault-tolerant write
There is a further constraint. Power can be lost at any instant, including halfway through updating a variable. If that left the store in an inconsistent state, the machine might never boot again.
Firmware therefore uses a fault-tolerant write protocol: the new record is staged in a dedicated working block, a marker is set, the record is committed to the main store, and only then is the working block released. If power fails mid-sequence, the next boot inspects the marker and either completes or discards the operation.
This is correct and necessary. It also means every write touches more than one flash block, and consumes more room and more time than the size of the data would suggest.
Garbage collection, and when it does not run.
Debris cannot accumulate forever, so firmware implements reclaim — a garbage collection pass. It walks the store, copies every live record into a clean area, erases the old blocks, and starts again with the dead records gone.
The question that matters is not how reclaim works. It is when it runs, and reclaim is typically triggered only when free space falls below a threshold and a write is attempted. It is not scheduled, not periodic, and not something the user can invoke.
How the store actually fails.
Four distinct failure modes, with different symptoms.
| Mode | Mechanism | Typical symptom |
|---|---|---|
| Exhaustion | Superseded records fill the region; reclaim cannot free enough | Firmware updates fail; boot hangs at the splash; settings do not persist |
| Fragmentation | Total free space is adequate but no contiguous run is large enough for a big record | Large writes fail while small ones succeed — appears intermittent |
| Corruption | Power lost at the wrong instant, or a bad block, leaves an inconsistent header | Firmware refuses to parse; may fall back to defaults or hang |
| Stale transaction | A fault-tolerant write marker left set from an operation that never completed | Every boot retries the same operation and stalls the same way |
The last two share a defining property, and it is the one that matters for Part V. They persist across resets, because the flawed state is stored in non-volatile memory. A reset does not clear them; the machine reads the same bad state back on the next boot and fails identically. Only rewriting the store fixes it.
+ Part IV
Updating firmware.
Firmware updates are the one routine operation that rewrites the flash chip. Understanding what they touch — and what they quietly reset as a side effect — is necessary to interpret the case in Part V.
Capsule updates: the two-phase handshake.
The modern way to update firmware from a running operating system is the UEFI capsule. The operating system cannot write the flash chip directly — that region is locked while the OS runs, deliberately, because unrestricted write access would be a catastrophic security hole.
Instead the update is handed over in two phases across a reboot.
In phase one the operating system writes the new firmware image, wrapped in a signed capsule, to the EFI System Partition, and sets a UEFI variable telling firmware that an update is pending. In phase two, on the next boot, firmware sees the variable, locates the capsule, verifies its signature, and performs the flash before the operating system loads.
What a flash actually resets.
There is a second update path. Vendor tools can flash the chip directly from Windows using a utility such as AMI's AFUWIN, driven by command-line switches that select which regions to program. A typical vendor invocation looks like this:
AFUWINx64.EXE image.cap /p /b /n /r /sp
The switches matter more than they appear to. /p programs the main firmware body, /b the boot block, and — the significant one — /n programs the NVRAM region.
That last switch means the variable store is not preserved across the update. It is rewritten. Every superseded record, every stale transaction marker, every accumulated fragment is erased and replaced with a clean store.
+ Part V
Reading a real fault.
Everything so far has been machinery. Here we use it. The case is a consumer desktop tower that has behaved the same way since it was delivered, and the reasoning below is the reasoning any competent diagnosis follows: constrain first, hypothesise second.
Symptoms as evidence.
The observed behaviour, stated without interpretation:
| Observation | What it rules out |
|---|---|
| Halts at the vendor splash screen; no operating system progress indicator | Everything after ExitBootServices. This is firmware, not the OS. |
| Occurs only on restarts triggered by an operating system update | Generic hardware failure. A failing component would not select for one restart type. |
| Ordinary restarts and cold boots complete normally | Persistent damage to code or storage. The same firmware executes fine most of the time. |
| A power-button hold does not recover it | Anything cleared by dropping the main rails. |
| Removing mains supply does recover it | Anything that survives loss of standby power — narrowing to one region of plate 14. |
| Present since the machine was delivered | Degradation, wear, and user-induced causes. |
Read together, those six lines are more diagnostic than any tool. They place the fault after firmware has started executing and drawn a logo, before the operating system loads, in a domain powered by standby, triggered by a mechanism specific to operating system updates, and present from day one.
Only one thing described anywhere in this guide satisfies all six constraints at once.
Why two ways of switching off give different answers.
The recovery asymmetry is the strongest single piece of evidence, and it is worth stating precisely why.
A power-button hold takes the machine to S5. The main rails collapse; +5VSB stays energised because the embedded controller that performed the shutdown runs on it. Switching off at the wall takes the machine to G3, where standby collapses too.
If the fault survived the first and not the second, the flawed state must live somewhere that standby power maintains. Two candidates fit: volatile state inside a standby-powered device — the embedded controller's own RAM, or a USB controller on an always-on port — and non-volatile state in the flash chip, which survives everything but is re-read on each boot and can be corrected by a full power cycle only if the firmware's recovery path is itself reached.
The trigger discriminates between them. A fault that occurs specifically after operating system updates, and not on ordinary restarts, points at the mechanism that operating system updates use and ordinary restarts do not: a variable written into NVRAM to request work at the next boot.
That hypothesis is testable, which is what makes it worth stating. It predicts recurrence on a timescale of weeks. A hypothesis that predicted nothing would be a story, not an analysis.
Testing it, and the honest limits.
In this case a firmware update was applied, and the next operating system update restart completed normally. It would be easy to record that as a fix. It is not one, for two reasons drawn directly from Part IV.
First, the changelog for that release listed security patches only, with nothing under problem fixes. There was no documented change capable of correcting a boot hang.
Second, the flash was performed with the /n switch, which rewrites the variable store. The bottom row of plate 14 applies: the update cleared exactly the state the hypothesis blames, whether or not the new firmware differed in any relevant way.
One clean boot after an intervention that resets the suspected cause is not evidence that the cause was addressed. It is the outcome both explanations predict. Only recurrence, or its sustained absence over many update cycles, separates them.
| If this happens | Conclude |
|---|---|
| Fault returns within weeks or a few months | Accumulation confirmed. The flash reset a counter, not a defect. |
| Fault absent across many update cycles and a feature update | Hypothesis weakened. Consider a genuine firmware fix or an unrelated coincidence. |
| Fault returns immediately | Something is regenerating the condition quickly — a repeatedly failing update, not slow accumulation. |
+ Part VI
The same chain, one scale down.
Everything in this guide has a microcontroller equivalent. Not an analogy — the same engineering problem, solved with the same structures, at a size you can hold in your head and inspect with a debugger. This part makes the mapping explicit.
Boot ROM, bootloader, application.
An STM32 coming out of reset does exactly what an x86 does: fetch from a fixed address. The address differs, and the mechanism for choosing what sits there differs, but the shape is identical.
On Cortex-M the vector table sits at the base of the boot region. The first word is the initial stack pointer, the second is the reset handler's address. The core loads the stack pointer, jumps to the handler, and execution begins. Where that boot region maps — internal flash, system memory containing the mask-programmed boot ROM, or SRAM — is selected by BOOT pins or option bytes sampled at reset.
One asymmetry is worth naming. The MCU has no memory training stage, because on-chip SRAM works from the instant power is valid. That single difference removes the longest and most fragile step in the PC boot chain — and it is why an MCU can be running application code microseconds after reset while a PC takes twenty seconds.
EEPROM emulation: the identical bug.
Most modern microcontrollers have no real EEPROM. They have flash, with the same constraint the PC has: bits clear individually, but set only by erasing a whole page. To store configuration that changes at runtime, you emulate EEPROM in flash — and every vendor library that does this converges on the same design as the UEFI variable store, because the constraint forces it.
Two pages. Writes append a record to the active page. Superseded records are marked dead, not removed. When the active page fills, live records are transferred to the spare page, the old page is erased, and the roles swap.
Power domains and reset sources.
Chapter 3 established that a PC has several power domains and that "off" is ambiguous. An MCU has exactly the same structure, exposed more honestly.
| PC concept | MCU equivalent | Shared consequence |
|---|---|---|
+5VSB standby rail | VBAT backup domain | State survives what looks like a full power-off |
| Embedded controller | POR/BOR supervisor circuit | Something always-on decides when the main core may run |
PLTRST# platform reset | System reset (NRST) | Resets the core; does not reset the backup domain |
| CMOS clear jumper | Backup domain reset (BDRST) | The only way to clear persistent state deliberately |
| Warm versus cold restart | RCC_CSR reset flags | How you arrived determines what you may assume |
The right-hand column is the transferable lesson. Reset is not one operation, and "the device restarted" is not a complete description of what happened. An MCU tells you which reset occurred if you read the flag register before clearing it. Firmware that skips this is firmware that will eventually make an assumption that is false exactly once, on one customer's unit, in a way you cannot reproduce.
What to carry into your own designs.
Eight lessons, each earned by something in this guide.
Budget non-volatile writes as a resource. Every write consumes erase-cycle life and free space. Decide at design time how often each item may be written, and enforce it. Unbounded write frequency is the root cause of most field failures in this class.
Make the garbage collector run early, not late. Reclaim triggered only at exhaustion is exercised least in testing and most in the field. Trigger at a comfortable threshold, and provide a way to force it.
Instrument the store. Expose free space, record count, and dead-record ratio through a diagnostic interface. The PC platform's inability to report this is precisely why the fault in Part V is hard to diagnose. Do not reproduce that limitation.
Never let a stored request become unclearable. If a flag says "do this work at next boot," the code that clears it must not depend on the work succeeding, or on there being room to write. Bound the retries and record the failure.
Ask which reset, always. Read the reset cause, branch on it, and never assume peripheral state after a warm start.
Separate power domains deliberately, and document them. Anything on an always-on rail is state that survives what your users will call "switching it off."
Distinguish a fix from a reset. When an intervention that clears accumulated state makes a symptom vanish, you have learned nothing yet. Look for what the change actually contained before concluding.
Make the diagnosis falsifiable. The hypothesis in Part V is worth stating only because it predicts recurrence. State what would prove you wrong, then wait for it. An explanation compatible with every outcome is not an explanation.
Let's Talk