Back to all posts
11 min read

I Became a flashrom Maintainer. Then I Bought Every SPI Flash Chip I Could Find.

I Became a flashrom Maintainer. Then I Bought Every SPI Flash Chip I Could Find.

Years ago I dumped a flash chip with a Bus Pirate and hit a bug. Chasing it upstream led me to flashrom’s mirror and the discovery that anything real gets submitted through Gerrit, not GitHub. I clicked into a review thread and found people arguing over implementation details, signing off with corporate addresses, chromium.org all over the thread. Google maintains their own fork of flashrom, and here they were upstream too, on Gerrit instead of GitHub.

I remember thinking: great, another corporate time sink. I’ll spend 800 hours getting a one-line fix through review, arguing about naming conventions with someone whose job title has “principal” in it.

I closed the tab and left.

Coming Back for a Warning Message

Before any of that, I’d assumed flashrom maintainers like Anastasia already had every programmer worth testing with sitting on a shelf somewhere. Why would they need mine? Then an AliExpress recommendation put a Flashcat in front of me. The product photo looked shady enough that I searched instead of clicking buy, and confirmed it: knockoff. The real thing comes from Michael, who runs his own PCB factory in the US and isn’t about to sell genuine units on AliExpress for less than his own site charges. I ordered directly from him. It took a few weeks to reach Morocco.

In 2025 I started installing coreboot across my fleet. The workflow is simple on paper: read the chip two or three times to make sure the dumps match, then extract the regions you actually need. Simple, until flashrom starts printing the same line on every run: chip not verified, please submit results to the flashrom mailing list.

Ten times. Twenty times. Same warning, different chip.

I compiled flashrom locally just to silence it and immediately hit a different wall: a compiler error. Something like “fixes an uninitialized variable warning (-Werror,-Wsometimes-uninitialized) introduced in commit 182902ee when early exit paths were added before the time(&time_start) call in main().” In fairness, I was building with a GCC 16 release candidate. Compilers are like us: they become less tolerant of bullshit with age. When GCC 17 ships, it will probably find problems in my own code. Fine. If I’m building this thing anyway, I might as well fix it.

Early March, I learned how Gerrit reviews actually work and submitted my first patch, mentally scheduling the merge for sometime around 2030 (just before the world cup). It was approved the next day and merged three days after that, the gap being flashrom’s own rule: three days minimum between approval and merge. No comments, no bikeshedding, just merged.

That broke my assumption. I asked Claude and GPT to sanity-check what I’d seen on that Gerrit thread years earlier, mostly so I wasn’t just talking myself into one model’s vibes. Those corporate addresses belonged to people doing that review work for free, on their own time.

The First Negative Contributor

So I decided to become flashrom’s first negative contributor.

Anyone can be a positive contributor now. It’s trivial: slop out a thousand lines for a feature 0.01% of users will ever touch and hope it gets merged before anyone reads it closely. That’s basically what most software has become. Being a negative contributor is harder, because it means deleting more code than you write.

I started reading the codebase properly, getting déjà vu on the same patterns over and over, and refactoring: extracting helpers, collapsing duplication, documenting what I found along the way. I did this daily for a while.

By then I already owned a genuine Flashcat, one of a family of semi-open-source flash programmers from embeddedcomputers.net, more expensive than a CH347 or a CH341A but with an interesting architecture (the FPGA bitstream is the one piece that isn’t open). The control software is written in Visual Basic. Getting it to compile on Linux or FreeBSD requires a small dance nobody should have to do twice, and I was tired of doing it.

I emailed Michael at EC with a plan: port it to Rust, since I already had crates I could reuse. His reply came back almost instantly: “Sounds like fun, let me know when you have a working version to test.”

I spent the next two months on Flashcat and coreboot work in whatever free time I had. Somewhere in there, Anastasia, one of flashrom’s maintainers, checked in. She wasn’t complaining, she was worried: I had several smaller patches and a handful of larger feature patches sitting open in review at once, and she didn’t want the work to stall out or get lost, or for me to get quietly discouraged and disappear. It was the kind of message you only get from someone who actually tracks the queue by hand.

By that point I’d already shipped a few releases of the flashcat crate and understood the hardware well enough to see the actual problem underneath all of this: every single chip needs to be manually tested. There was no way around it.

Datasheets Lie

Once I saw that, I went looking for something that should already exist: a library or database that maps real, verified chip behavior to JEDEC IDs, voltage variants, and package types. I couldn’t find one.

The silicon doesn’t always follow its own datasheet. Commercial programmers that advertise support for 30,000 chips are usually inflating the number: most of those aren’t SPI parts at all, and a lot of the “support” is really just an auto-detect routine thrown at a wide ID range, hoping for the best. More than once I’ve probed a chip and gotten the electronic equivalent of a shrug: technically present, technically responding, not actually going to cooperate.

That gap, real silicon behavior with no authoritative record of it, is the actual problem. The fix isn’t a side project or a personal spreadsheet. It’s building that database directly into flashrom, so every other tool and library downstream can rely on it instead of re-discovering the same lies chip by chip.

Everything, He Said

To build that database you need chips, so I went back to XXSY Electronics, an AliExpress trader I’d bought from before. I used ChatGPT to translate my request into Chinese and asked if he’d sell me SPI ROMs individually, one unit per part. He agreed and sent over a file.

I assumed it was just his AliExpress listing. It wasn’t. He could source almost anything on a BOM, not just what was posted for sale. A lot of these traders operate this way; the storefront is a fraction of the actual inventory they can reach.

He asked which chips I wanted.

I said everything. Send me every SPI ROM you can obtain.

That was my mistake, not his. “Everything” in a Chinese trader’s supply network isn’t the forty common parts my local shop carries, it’s the world. A few weeks later he confirmed everything had been sourced and packed. The invoice came in at several hundred dollars on top of what I’d already spent. Ghosting him wasn’t an option; the misunderstanding was mine to own.

So I checked the damage against Mouser pricing. His list came in roughly three times cheaper, and it included parts that are already end-of-life everywhere else, out of stock worldwide, the kind of chip someone repairing a fifteen-year-old device will eventually need and find nowhere.

That’s when I decided to actually build the thing.

What It Actually Costs

All in, I’m well into four figures at this point, with quantities of each part ranging from 3 to 10. The trader warned me upfront that with prices moving the way they were, none of it was going to stay static, so I stocked up harder on the parts I’d actually reach for and bought just 3 of the ones I’ll probably never use myself, enough to verify and document without betting on a chip I don’t need.

Take the MX66U2G45GXRI00, a 2Gb industrial-temp NOR flash most hobbyist programmers have never heard of, let alone tested. The part is genuine, not some relabeled reject. It’s just that the trader didn’t gouge me for it. That chip used to cost $19. DigiKey lists it at $61.07 now. Part of that is the flash memory price surge. The rest, I can only assume, is that NOR flash is AI now, and everything with a die inside gets the premium. The trader’s price is close to what it actually cost before the market decided otherwise.

Other people buy a GPU with 48GB of VRAM. I bought about 1Tb of SPI ROM. That’s terabit, not terabyte, because flash chips still get sold in bits like it’s 1998.

The verification itself is manual, on purpose. I write a known pattern to a chip with one programmer, then read it back with a different one. If both agree, the chip is what it says it is. If they don’t, that’s a data point too, and often the more interesting one.

Some of this testing is also destructive, and there’s no undoing it. OTP is the obvious case: the moment I confirm a chip’s one-time-programmable region actually works as advertised, that region is written, permanently. The chip is done being a blank sample the second the assertion succeeds. It’s the closest thing hardware has to a Bitcoin transaction: irreversible the instant it confirms. The miner is flashrom.

A lot of these parts aren’t the SOIC-8 or SOIC-16 packages most flashrom development assumes. Some are parallel flash, which flashrom doesn’t fully support the way it supports SPI, so they’re not the typical case at all. Then there’s voltage. The SPI parts alone span 1.2V, 1.8V, 3.3V, and 3.6V, and I’ve got some rated as low as 0.8V. The parallel chips run at 5V. The goal isn’t to test each chip once at whatever voltage happens to be convenient, it’s to test every part at every voltage it’s actually rated for, and document what changes when you don’t.

The parallel chips are getting set aside for now, not ignored. Once the SPI side of the database is in reasonable shape, the next project is building out a real parallel flash framework in flashrom instead of the patchwork support it has today. Same problem, different bus.

None of this comes out of paid time. It comes out of the hours I’d otherwise spend doomscrolling AI Twitter, arguing about that models hit a plateau and we need to build model + infrastructure. I’d rather spend them doing actual work.

So does everyone else pushing patches through that Gerrit queue. Those corporate email addresses that scared me off years ago belong to people whose actual sponsor, for this work, is themselves.

Every chip verified this way is one less “chip not verified” warning some stranger hits at 2 AM while trying to recover a dead board. If you’ve read The Accidental Maintainer, you already know how this goes: you file one honest bug report or send one email with a plan attached, and a few months later you’re the guy with a spreadsheet of a few thousand dollars in flash chips and a Gerrit queue that never empties.

It’s not just the user hitting the warning who benefits. It’s the reviewer on the other side of a patch. An unverified chip forces a context switch every time it comes up: stop reviewing the code, go ask the submitter for a datasheet, ask them to add this check or that one, ask them to refactor before anyone can even evaluate whether the chip support is correct. A verified entry removes that whole detour. The reviewer gets to read code instead of doing archaeology first.

Working through this many chips changed my mind about one long-standing warning, too. That’s the pitch behind what I want for flashrom 2.0: stop warning about every unverified chip in the tree. Only warn on chips released after the flashrom version doing the warning. Anything older has had years to get flagged by someone; a build that only complains about parts newer than itself stops punishing users for silicon nobody’s gotten around to yet, and the warning actually means something again: this one is new, nobody’s confirmed it, go be the first.

Flashrom itself turned 24 year old this year. Come January, it hits a quarter century, first commit in January 2002. Not many software projects make it to 25 years old still maintaining the same quality, still run by the people who actually use it, never bought out, never sold off to whichever company decided firmware tooling was a good acquisition target that quarter. That’s the thing actually worth protecting here. I didn’t buy my way into any of this: the patches, the refactors, the Flashcat port all came first, on nobody’s payroll. The chips are just what happens when you take “every chip needs manual testing” seriously after you’re already in too deep to walk away again.

Veni, vidi, verified. Repeat across a thousand chips. All chips lead to flashrom.

🔗Interstellar Communications

No transmissions detected yet.Be the first to establish contact!

• Link to this post from your site• Share your thoughts via webmention• Join the IndieWeb conversation

Related Posts