Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Tools & Common Procedures

Shared tools, wiring, and procedures used across all coreboot guides on this site. Individual guides reference sections here rather than duplicating them.


SPI Programmers

Do not use a CH341A unless you have confirmed it uses 3.3V logic on data lines. Many clones output 5V on MOSI/MISO/CLK which can damage the SPI flash and the PCH.

What You Need

ItemNotes
SOIC-8 test clipPomona 5250 is best; generic clips work
Female–female Dupont wires10–15 wires
IPA (isopropyl alcohol)Clean chip legs before clipping
Raspberry Pi 3/4/5 or Raspberry Pi Pico (RP2040)See below for differences

flashprog vs flashrom: Use flashprog (Libreboot’s fork of flashrom). It is more robust in practice — fewer detection failures, better chip support. Commands are identical; just replace flashrom with flashprog in any guide. All examples on this site use flashprog.

Choosing a Programmer

Raspberry Pi 3/4/5 — the more convenient option. Runs headless with SSH, so you can flash from any terminal on your network while the Pi sits next to the open machine with all wires connected. No screen needed. Has two 3.3V pins (physical pins 1 and 17) making multi-wire distribution easy.

Raspberry Pi Pico (RP2040) — cheapest option but requires a host computer physically nearby running flashprog over USB serial. Only one 3.3V output pin (pin 36) which needs multi-way splits or a breadboard. Do not use Pico 2 (RP2350) — serprog stability issues.

Method A — Raspberry Pi 3B / 3B+ / 4

Parts:

ItemNotes
Raspberry Pi 3B, 3B+, or 4Raspberry Pi OS Lite is fine
MicroSD card (8 GB+)With Raspberry Pi OS flashed
5V PSUStable power matters
Ethernet or WiFiSSH in headless

Enable SPI on the Pi

sudo raspi-config

Navigate to Interface Options → SPI and enable it. Reboot.

ls /dev/spidev*
# Should show: /dev/spidev0.0  /dev/spidev0.1

Build flashprog on the Pi

sudo apt install git build-essential libpci-dev libusb-1.0-0-dev libftdi1-dev \
  libgpiod-dev meson ninja-build pkg-config

git clone https://review.sourcearcade.org/flashprog.git
cd flashprog
meson setup builddir
ninja -C builddir
sudo ninja -C builddir install

Verify:

sudo flashprog -p linux_spi:dev=/dev/spidev0.0,spispeed=512
# Expected: "No EEPROM/flash device found." — correct, nothing connected

Pi GPIO → SOIC-8 Wiring

Pi GPIO header:                    SOIC-8 chip:

Pin 24 — GPIO8/SPI0_CE0 ────────── Pin 1  (/CS)
Pin 21 — GPIO9/SPI0_MISO ───────── Pin 2  (MISO/DO)
Pin 17 — 3.3V ──────────┬────────── Pin 8  (VCC)
                        └──────────── (board-specific connections)
Pin 25 — GND ────────────────────── Pin 4  (GND)
Pin 19 — GPIO10/SPI0_MOSI ──────── Pin 5  (MOSI/DI)
Pin 23 — GPIO11/SPI0_SCLK ──────── Pin 6  (CLK)
Pi Physical PinPi SignalSOIC-8 PinSignalRequired?
24GPIO8 / CE01/CSYes
21GPIO9 / MISO2MISO (DO)Yes
173.3V3/WPNo by default — see /WP and /HOLD Troubleshooting
25GND4GNDYes
19GPIO10 / MOSI5MOSI (DI)Yes
23GPIO11 / SCLK6CLKYes
7/HOLDNo by default — see /WP and /HOLD Troubleshooting
173.3V8VCCYes

Verify your wiring against Libreboot’s SPI guide before first use — it covers the Pi 3/4 GPIO pinout in detail and is the authoritative reference: https://libreboot.org/docs/install/spi.html

Pi flashprog command syntax

-p linux_spi:dev=/dev/spidev0.0,spispeed=1000

Method B — Raspberry Pi Pico (RP2040)

Flash serprog Firmware onto the Pico

Use Libreboot’s pico-serprog — it has multi-CS handling and tuned 12 mA drive strength.

git clone https://codeberg.org/libreboot/lbmk
cd lbmk
./mk dependencies debian
./mk -b pico-serprog
# Output: bin/serprog_pico/serprog_pico.uf2

Flash onto the Pico:

  1. Hold BOOTSEL, plug Pico into USB, release BOOTSEL — mounts as RPI-RP2
  2. cp bin/serprog_pico/serprog_pico.uf2 /media/$USER/RPI-RP2/
  3. Pico reboots. Verify: sudo dmesg | grep ttyACMttyACM0: USB ACM device
sudo usermod -aG dialout $USER   # avoid sudo on every flashprog call (re-login after)

Install flashprog on the host machine:

sudo apt install flashprog
# If not available: sudo apt install flashrom  (commands are identical)

Pico GPIO → SOIC-8 Wiring

Critical: GP3 = MOSI and GP5 = /CS. These are commonly documented in reverse. Using the wrong mapping gives garbage reads.

Pico (corner near USB):

Pin 4  — GP2  — SCK  ──────────────── SOIC-8 Pin 6
Pin 5  — GP3  — MOSI ──────────────── SOIC-8 Pin 5
Pin 6  — GP4  — MISO ──────────────── SOIC-8 Pin 2
Pin 7  — GP5  — /CS  ──────────────── SOIC-8 Pin 1
Pin 36 — 3V3(OUT) ──┬──────────────── SOIC-8 Pin 8 (VCC)
                    └───────────────── (board-specific connections)
Pin 38 — GND ──────────────────────── SOIC-8 Pin 4
SOIC-8 PinSignalPico Physical PinPico GPIORequired?
1/CSPin 7GP5Yes
2MISOPin 6GP4Yes
3/WPNo by default — see /WP and /HOLD Troubleshooting
4GNDPin 38GNDYes
5MOSIPin 5GP3Yes
6SCKPin 4GP2Yes
7/HOLDNo by default — see /WP and /HOLD Troubleshooting
8VCCPin 363V3(OUT)Yes

Pin 37 (3V3_EN) is NOT a power output — do not use it.

Pico flashprog command syntax

-p serprog:dev=/dev/ttyACM0,spispeed=16M

SOIC-8 Pinout Reference

      ┌───────┐
 /CS 1│●      │8 VCC
  DO 2│       │7 /HOLD
 /WP 3│       │6 CLK
 GND 4│       │5 DI
      └───────┘

Pin 1 = dot on IC package. Pin numbering goes anti-clockwise.


Triple-Read Methodology

Always take three reads of every chip. All three SHA256 checksums must match before proceeding. If they don’t, reseat the clip, clean chip legs with IPA, and read again.

# Example (adjust programmer, chip string, and filename per your board)
sudo flashprog -p <programmer> -c "<chip>" -r dump1.bin
sudo flashprog -p <programmer> -c "<chip>" -r dump2.bin
sudo flashprog -p <programmer> -c "<chip>" -r dump3.bin

sha256sum dump*.bin
# All three MUST match

Troubleshooting inconsistent reads:

  • Clean chip legs with IPA
  • Try lower speed: spispeed=512 (Pi) or spispeed=4M (Pico)
  • Specify chip explicitly: flashprog ... -c "<chip_string>"
  • On dual-chip boards: confirm idle chip’s /CS is held high
  • Try different /WP and /HOLD states — see below

/WP and /HOLD Troubleshooting

Rule of thumb: do not hold /WP (pin 3) or /HOLD (pin 7) high by default. Many boards have on-board pull-ups on these lines, and actively driving them can sometimes interfere. Start with only the six core connections (VCC, GND, /CS, MOSI, MISO, CLK) and leave /WP and /HOLD floating.

If reads are inconsistent, writes fail, or the chip is not detected, work through these /WP and /HOLD combinations until one works:

/WP (pin 3)/HOLD (pin 7)Try when
floatingfloatingStart here — default, no extra wires
HIGH (3.3V)floatingWrites fail or chip reports write-protected
floatingHIGH (3.3V)Reads corrupt mid-transfer, chip pauses randomly
HIGH (3.3V)HIGH (3.3V)Both issues, or nothing else works

Both /WP and /HOLD are active-low signals. Driving them high is always electrically safe — it cannot damage the chip. Driving them high simply ensures write-protect is disabled (/WP) and the chip never pauses (/HOLD).

Some boards pull these lines high through on-board resistors and do not need external wiring. Others leave them floating or weakly pulled, and the state becomes marginal — especially with longer clip wires acting as antennas. If you see intermittent failures that cleaning and speed changes don’t fix, /WP and /HOLD state is the next thing to try.

Per-board notes: Individual guides note which /WP and /HOLD wiring is confirmed working for that board. The combinations above are a general fallback when the default doesn’t work or when working with a board not covered by these guides.


ifdtool — Extract Flash Regions

Build ifdtool from the coreboot tree:

git clone https://review.coreboot.org/coreboot.git
cd coreboot
git submodule update --init --checkout

cd util/ifdtool && make && cd ../..

Extract regions from a full flash dump:

util/ifdtool/ifdtool -x <dump.bin>              # Haswell / Broadwell
util/ifdtool/ifdtool -p cnl -x <dump.bin>        # Coffee Lake (Cannon Lake PCH)

Produces:

Output FileContents
flashregion_0_flashdescriptor.binIntel Flash Descriptor
flashregion_1_bios.binBIOS region
flashregion_2_intel_me.binIntel CSME firmware
flashregion_3_gbe.binGigabit Ethernet NVM (contains MAC address)

Build Dependencies (Debian / Ubuntu)

sudo apt install -y \
  build-essential gnat flex bison libncurses-dev wget zlib1g-dev \
  git python3 libelf-dev nasm pkg-config libssl-dev m4 iasl acpica-tools curl

The W541 guide additionally uses: imagemagick gcc-multilib libc6-dev-i386 unifont


Cross-Compiler Toolchain

Build once per coreboot checkout:

cd coreboot
make crossgcc-i386 CPUS=$(nproc)
# Takes 30–90 minutes on first run

Internal Re-Flashing (Subsequent Updates)

Once running coreboot, subsequent updates can be done internally without an external programmer.

Single-chip boards (e.g. T580):

sudo flashrom -p internal -w coreboot.rom

Multi-chip boards writing BIOS region only (e.g. M920q):

sudo flashrom -p internal -N -w coreboot.rom --ifd -i bios

Full ROM write (e.g. W541):

sudo flashprog -p internal -w build/coreboot.rom

If your kernel restricts iomem access:

# Add to GRUB_CMDLINE_LINUX in /etc/default/grub:
GRUB_CMDLINE_LINUX="iomem=relaxed"
sudo update-grub
# Reboot, then retry

Internal flashing uses the full combined ROM — no splitting needed.


Programmer Comparison

Raspberry Pi 3/4Raspberry Pi Pico
Read speed~500 KB/s at 1 MHz~2 MB/s at 16 MHz
3.3V pins2 (pins 1 and 17) — easy multi-wire crimps1 (pin 36) — needs multi-way split or breadboard
flashprog interfacelinux_spi (native kernel driver)serprog (USB serial)
SetupFull OS, raspi-config, build flashprogFlash UF2, done
Remote flashingYes — headless SSH from any terminalNo — host computer must be physically nearby
VerdictMore convenient overallCheapest, fastest reads

References