If you want to run Windows on Raspberry Pi, the direct answer is that you must use a Raspberry Pi 5 (8GB) or Pi 4 (8GB), flash the WoA (Windows on ARM) UEFI firmware, and install a Windows 11 ARM64 ISO. Standard x86 Windows will not boot. For a genuinely usable desktop experience in 2026, the Pi 5 paired with an NVMe SSD via the PCIe HAT is the only viable path; SD cards will bottleneck the OS and cause boot failures.

This guide cuts through the outdated Windows 10 IoT Core tutorials. We will cover the exact hardware stack required, the UEFI flashing process, how to interact with GPIO/I2C using Python on Windows ARM, and how to debug the inevitable boot errors.

The Decision Path: Which Pi and Windows Build?

Not all Raspberry Pi boards can handle a modern Windows desktop environment. The OS requires ARMv8.2 instruction sets, a minimum of 4GB RAM (8GB strongly preferred), and fast block storage. Use this decision matrix to select your hardware stack.

Use Case Board Variant RAM Storage Medium OS Build Target Verdict
Headless IoT Gateway Pi 4 Model B 4GB Industrial microSD Win 11 IoT Enterprise LTSC Viable, but sluggish UI
Light Desktop / Kiosk Pi 4 Model B 8GB USB 3.0 SATA SSD Win 11 Pro ARM64 Acceptable, USB bus bottleneck
Daily Driver / Dev Box Pi 5 8GB NVMe M.2 via PCIe HAT Win 11 Pro ARM64 (26H2) Concrete Pick (Default)
Default Recommendation: Buy the Raspberry Pi 5 (8GB). The Cortex-A76 cores and native PCIe 2.0 interface eliminate the storage I/O bottlenecks that made Windows on the Pi 4 feel like a novelty rather than a tool.

Parts List & Spec Sheet for a Viable Windows Build

Running an OS designed for x86 laptops on a single-board computer requires strict adherence to power and thermal limits. Windows 11 background tasks (Indexing, Defender, Telemetry) will instantly thermal-throttle a passively cooled Pi.

Component Exact Model / Specification Estimated Cost (2026) Why It Matters
Compute Board Raspberry Pi 5 (8GB LPDDR4X) $80 Required for PCIe and sufficient RAM for Win 11.
Power Supply Official 27W USB-C PD Power Supply $12 NVMe drives draw up to 3A on the 5V rail during spin-up. Standard 5V/3A phone chargers will cause brownouts.
Cooling Official Active Cooler (or Argon ONE V3) $5 - $25 Windows Defender scans push all 4 cores to 100%. Passive heatsinks will fail.
Storage HAT Pimoroni NVMe Base or Geekworm X1001 $15 Routes PCIe lanes to M.2 M-key. Avoid USB-to-NVMe enclosures.
Storage Drive 256GB+ M.2 2230/2242 NVMe (e.g., WD SN740) $30 Gen 3 drives work but will run at Gen 2 speeds (500 MB/s) natively on Pi 5.

Flashing UEFI and Installing Windows 11 ARM64

Microsoft does not provide a Raspberry Pi Windows installer. You must rely on the community-driven WoA (Windows on ARM) Project to inject the necessary Broadcom UEFI firmware and ARM64 drivers into a standard Windows ISO.

  1. Download the WoA Installer: Grab the latest WoA Installer for Raspberry Pi from the official WoA Project portal.
  2. Source the Windows ISO: Use the Microsoft Windows Insider Preview portal or UUP Dump to download a Windows 11 ARM64 ISO (Build 26H2 or newer).
  3. Prepare the NVMe Drive: Connect your NVMe drive to a PC via an external USB enclosure. Launch the WoA Installer, select your Pi 5 board variant, and point it to the ARM64 ISO.
  4. Inject Drivers: The installer will format the drive, create the EFI partition, flash the UEFI firmware, and inject the Qualcomm/Broadcom BSP (Board Support Package) drivers for USB, PCIe, and Bluetooth.
  5. Assemble and Boot: Install the NVMe onto the Pi 5 HAT. Connect a keyboard, mouse, and HDMI monitor. Power on. You will see the UEFI Raspberry Pi logo, followed by the Windows OOBE (Out of Box Experience).
PCIe Gen 3 Warning: The Pi 5 supports PCIe Gen 3.0 via an override in config.txt, but many NVMe drives fail to initialize under Windows ARM at Gen 3 speeds due to signal integrity issues on the HAT ribbon cables. Stick to the default Gen 2.0 (500 MB/s) for stability unless you have an oscilloscope to verify eye-diagram margins.

GPIO & I2C on Windows ARM: Pin Mapping and Python Code

Standard Linux libraries like RPi.GPIO or gpiozero do not work on Windows. To interact with the 40-pin header on Windows 11 ARM, you must use the Windows Runtime (WinRT) APIs via Python. Below is the pin mapping for a standard setup reading a BME280 I2C sensor and toggling a status LED.

Function BCM Pin Physical Pin Windows API Mapping
I2C SDA 2 3 I2C Bus 1 (via smbus2)
I2C SCL 3 5 I2C Bus 1 (via smbus2)
Status LED 18 12 GpioController (via winrt)
Ground N/A 6, 9, 14, 20 Common Ground

Ensure you install the required packages in your Windows ARM Python environment: pip install winrt-Windows.Devices.Gpio smbus2.

import sys
import time
import asyncio

# --- PIN & BUS DEFINITIONS ---
LED_BCM_PIN = 18        # Physical Pin 12
I2C_BUS_ID = 1          # Physical Pins 3 (SDA) and 5 (SCL)
BME280_I2C_ADDR = 0x76  # BME280 default address

try:
    from winrt.windows.devices.gpio import GpioController, GpioPinDriveMode
    from smbus2 import SMBus
except ImportError as e:
    print(f"[FATAL] Missing dependency: {e}")
    print("Run: pip install winrt-Windows.Devices.Gpio smbus2")
    sys.exit(1)

def init_gpio():
    """Initialize Windows GPIO Controller and configure LED pin."""
    controller = GpioController.get_default()
    if not controller:
        raise RuntimeError("No GPIO controller found. Ensure WoA BSP drivers are loaded.")
    
    pin = controller.open_pin(LED_BCM_PIN)
    pin.set_drive_mode(GpioPinDriveMode.OUTPUT)
    pin.write(0) # Start LOW
    return pin

def read_i2c_temp():
    """Read raw temperature register from BME280 via I2C."""
    with SMBus(I2C_BUS_ID) as bus:
        # BME280 temp register msb is 0xFA
        data = bus.read_i2c_block_data(BME280_I2C_ADDR, 0xFA, 3)
        # Simplified raw conversion for demonstration
        raw_temp = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
        return raw_temp

async def main():
    led_pin = None
    try:
        print("[INFO] Initializing Windows GPIO...")
        led_pin = init_gpio()
        print("[INFO] GPIO Pin 18 configured as OUTPUT.")
        
        print("[INFO] Starting sensor loop (Ctrl+C to exit)...")
        while True:
            led_pin.write(1) # LED ON
            raw_temp = read_i2c_temp()
            print(f"[DATA] BME280 Raw Temp Register: {raw_temp}")
            await asyncio.sleep(1.0)
            
            led_pin.write(0) # LED OFF
            await asyncio.sleep(1.0)
            
    except PermissionError:
        print("[ERROR] Access denied. Run terminal as Administrator to access I2C/GPIO.")
    except OSError as e:
        print(f"[ERROR] I2C Bus communication failed: {e}. Check wiring and pull-ups.")
    except KeyboardInterrupt:
        print("\n[INFO] Halting script.")
    finally:
        if led_pin:
            led_pin.write(0)
            led_pin.close()
            print("[INFO] GPIO resources released.")

if __name__ == "__main__":
    asyncio.run(main())

Debugging: INACCESSIBLE_BOOT_DEVICE and Boot Failures

When Windows on ARM fails to boot on a Raspberry Pi, it rarely gives a helpful GUI error. The most common critical failure during the first boot or after a major Windows Update is the Blue Screen of Death (BSOD) with a specific stop code.

Exact Error String:
Your PC ran into a problem and needs to restart. Stop code: INACCESSIBLE_BOOT_DEVICE (0x0000007B)

This means the Windows kernel loaded, but the storage driver (StorPort) lost communication with the NVMe drive before the registry could be mounted.

Ranked Causes and Fixes

  1. PCIe Link Instability (Most Likely): The WoA UEFI negotiated a PCIe Gen 3 link, but the physical HAT ribbon cable is introducing bit errors at 8 GT/s.
    • Fix: Boot into the UEFI BIOS (mash ESC during the Pi logo), navigate to Device Manager -> Raspberry Pi Configuration -> Advanced, and force PCIe to Gen 2.
  2. Power Supply Brownout: The NVMe drive spiked above 2.5A during Windows initialization, tripping the Pi 5's brownout detection circuit and resetting the PCIe bus.
    • Fix: Verify you are using the official 27W PD supply. Check the vcgencmd get_throttled equivalent in Windows via the WoA PowerShell utilities to confirm undervoltage flags.
  3. Missing NVMe Driver in BSP: You used an outdated WoA installer that lacks the generic Microsoft NVMe driver injection for your specific drive controller (e.g., Phison E27T).
    • Fix: Re-flash the drive using the latest WoA Installer, ensuring the "Inject generic storage drivers" box is checked.

The First Three Things to Check When It Fails

If the board posts to UEFI but hangs before the Windows spinning dots appear:

  1. Check the UEFI Boot Order: Enter UEFI BIOS (ESC key). Ensure the NVMe EFI partition is listed above the USB mass storage devices.
  2. Verify RAM Timing: In the UEFI BIOS, check the reported RAM speed. If it shows 2133MHz instead of 4266MHz, the LPDDR4X training failed. Reseat the board and ensure the Active Cooler is not warping the PCB.
  3. Check the HDMI Port: Windows ARM on Pi 5 defaults to HDMI 0 (the port closest to the power connector). If you are plugged into HDMI 1, you will see a black screen while Windows is actually booting and waiting at the login prompt.

Extending or Simplifying the Build

Once you have a stable Windows 11 ARM64 environment, you will quickly notice the overhead of standard Windows on a 5W board. Here is how to optimize the system for embedded or desktop use.

How to Extend: Adding TPM 2.0 for BitLocker

Windows 11 Pro requires a TPM 2.0 module for BitLocker drive encryption and Windows Hello. The Pi 5 does not have an onboard discrete TPM. The Fix: Purchase an Infineon OPTIGA TPM 2.0 module on a 2x3 SPI header (approx. $15). Plug it into the dedicated TPM header on the Pi 5 (located near the USB-C port). In the UEFI BIOS, enable the SPI TPM interface. Windows will detect it as a discrete TPM on the next boot, allowing you to encrypt your NVMe drive.

How to Simplify: Stripping the OS with NTLite

If you are using the Pi 5 as a dedicated digital signage player or kiosk, the standard Windows 11 Pro image is bloated with Edge, Cortana, and Xbox services that consume 1.5GB of RAM at idle. The Fix: Before flashing, load your Windows 11 ARM64 ISO into NTLite (running on your main PC). Remove the Windows Defender, Edge, and Telemetry components. Inject the WoA drivers into the stripped install.wim file. This reduces idle RAM usage to under 1.2GB and cuts boot time by 40%.

Running Windows on a Raspberry Pi 5 is no longer a hack; with the right NVMe storage, proper thermal management, and WinRT-based Python code, it is a highly capable, low-power ARM workstation. Stick to the Pi 5 8GB variant, respect the PCIe Gen 2 limits, and always verify your power delivery under load.