A Practical Guide to Designing Open Hardware Boards That Pass a GPL Audit

Most of my working week is spent on the receiving end of other people’s board decisions. On a recent Monday I clipped a Pomona 5250 onto the SOP-8 flash of a consumer router whose vendor had ignored a source request for seven months, read out 16 MiB over SPI with flashrom and a CH341A, and started comparing the extracted bootloader against upstream U-Boot tags. Every obstacle in that workflow — a shield can over the flash, unpopulated and undocumented UART pads, a WP# pin strapped hard to ground — was a schematic-level decision made years earlier, almost certainly without a thought given to GPL compliance. This guide is for the people who make those decisions, because they decide, months before firmware ships, whether a board can be audited at all.

An open hardware board, as I use the term, is a PCB whose design artifacts — schematic, layout, gerbers, bill of materials, and the board-specific device tree sources — are published under a hardware license such as CERN-OHL-S v2.0 or the TAPR Open Hardware License, usually designed in KiCad and optionally listed in OSHWA’s certification registry. That is a separate legal object from the firmware it runs. If the firmware is Linux, U-Boot, and BusyBox, GPL-2.0 obligations attach to it whether or not the schematic is public. The two problems overlap in one KiCad project, and both are far cheaper to solve at layout time than at deposition time.

Engineering team reviewing board schematics and firmware source at a workstation
Open hardware starts at the schematic: every audit trail begins with decisions made in the design files.

What an open hardware board is — and what the GPL actually covers

The CERN-OHL v2 family comes in three variants: CERN-OHL-S-2.0 (weakly reciprocal — modifications to the design files must be shared, but combining the design with other hardware does not open those parts), CERN-OHL-W-2.0 (strongly reciprocal — the share-alike obligation reaches a wider circle of derivatives), and CERN-OHL-P-2.0 (permissive). TAPR’s Open Hardware License 1.0 is the older alternative. OSHWA certification adds a registry entry with a unique ID in the US000123 format that an auditor can verify in seconds; it is a signal, not a legal requirement.

The GPL, meanwhile, covers the software: the kernel, U-Boot, BusyBox, and the device tree blob. The DTB sits on the GPL side of the line because it is compiled from DTS files inside the kernel tree (arch/arm/boot/dts for 32-bit ARM, arch/arm64/boot/dts for 64-bit), which makes it part of a GPL-licensed work whose source must ship under GPL-2.0 §3. The schematic is on the hardware side, and no software license reaches it. When I audit a board, the schematic and the DTS together answer most of my questions in an afternoon; boards that publish neither cost me days and cost their makers credibility they do not get back.

Design for the audit before the audit

Boards that pass audits share observable traits, and none of what follows adds more than a few cents to the BOM. Treat it as the checklist I wish were attached to every board I open.

Physical access: a flash you can clip and a UART you can find

Use a standard SOP-8 footprint for the boot flash — 150-mil or 200-mil body; the usual suspects are the Winbond W25Q128JV, Macronix MX25L12835F, and GigaDevice GD25Q128 — with at least 3 mm of clearance on all sides so a Pomona 5250 clip seats without lifting adjacent passives. Do not place the flash under a shield can. On a recent gateway audit, flashrom reported Found Winbond flash chip "W25Q128.V" (16384 kB, SPI) on ch341a_spi, and the JEDEC ID read back ef 40 18 in seconds because the footprint was reachable. The same job on a board with the flash under a can becomes a rework-bench exercise with a real chance of board damage.

Close-up of a printed circuit board with a surface-mounted SPI flash chip
A reachable SOP-8 flash footprint turns a two-day audit into a two-minute read.

Put a 4-pin, 2.54 mm UART header footprint on the board — populated on development units, at minimum silkscreened on production units — with TX, RX, GND, and 3V3, documented as 115200 8N1. If the SoC is a 1.8 V part, say so in the documentation; I have killed a USB-UART bridge by assuming 3.3 V levels. The boot log is the cheapest compliance evidence in the system. A stock U-Boot banner prints the version and build date, e.g. U-Boot 2020.07 (Oct 12 2023 - 14:22:07 +0000). When the banner instead reads U-Boot 2010.06 with a 2023 build date, I know I am looking at a vendor fork of a thirteen-year-old snapshot — still the most common single finding in the consumer routers and Android TV boxes I examine.

Industrial gateways usually pair the Linux SoC with a companion MCU — an STM32F103 or similar — and that firmware is frequently GPL-licensed too, built from vendor SDKs or libopencm3. Leave a 4-pin SWD footprint. OpenOCD and a two-dollar ST-Link clone read the part out in minutes; without the footprint, the companion firmware’s provenance is invisible.

Straps, write-protect, and other one-way decisions

Do not strap WP# to ground through a single 0-ohm resistor with no alternative stuffing option. A jumper or a second stuffing position costs nothing at layout time and keeps in-circuit reads possible. Locking the flash read-only from the running system is legitimate hardening; making the flash physically unreadable to the device owner sends a different signal, and it is the kind of decision I document in an audit report whether or not it proves legally decisive.

Verified boot and GPL compliance can coexist, but the signing story has to let recipients run the source you are obliged to give them. GPL-2.0 §6 bars further restrictions on the rights granted, and whether a locked bootloader that refuses a user-rebuilt kernel violates GPL-2.0 is genuinely contested — the TiVo dispute that motivated GPL-3.0’s installation-information requirement never produced a court ruling, so I flag it as unsettled rather than pretend there is case law. GPL-3.0 §6 is explicit for User Products: installation information, including authorization keys, must accompany the source. My working rule for clients shipping GPL-2.0 firmware with verified boot is to publish a documented unlock path and name the mechanism in the release notes.

The device tree belongs to the board

The DTB is the board’s identity: model string, memory map, pinctrl, LED and button mapping. Because the DTS lives in the kernel tree, it is part of the corresponding source and must be released with it. Decompiling with dtc -I dtb -O dts (I use dtc 1.6.1) recovers the structure but loses the include hierarchy and comments, so I use it to verify published source, not to replace it. Publish the DTS for every hardware revision, pinned to the exact kernel commit it builds against — v5.15.148 in one recent audit — and put the hardware revision in the model string so an extracted DTB can be matched to a board revision unambiguously.

When the DTS is unpublished, I reconstruct board wiring from pinctrl nodes and cross-check against the schematic if one exists. Where neither is published, the only ground truth left is the PCB itself, and that is when an audit stops being an afternoon and starts being a week.

License the design files without ambiguity

My default for design files is CERN-OHL-S-2.0-or-later. Pick CERN-OHL-W-2.0 if you want share-alike terms to follow the board through derivatives; pick CERN-OHL-P-2.0 for permissive terms. State the choice in the repository README, in the schematic, and on the product page — never leave it to be inferred. TAPR OHL 1.0 remains a workable older option, though I see few new projects adopting it in 2024.

State the license per artifact, because hardware and firmware licenses do not mix on their own. A table in the README does the job: schematic, layout, and gerbers under CERN-OHL-S-2.0-or-later; kernel, U-Boot, and BusyBox under GPL-2.0 with their exact upstream terms; DTS files as part of the kernel tree; build scripts under whatever you choose, but say so. KiCad 8.0 added a license field to project and board properties; if you are on an older release, place an SPDX-License-Identifier: CERN-OHL-S-2.0-or-later text block on page one of the schematic.

On the firmware side, generate a machine-readable manifest. Buildroot’s make legal-info target produces a license manifest with the source and license text of every package; Yocto’s create-spdx class emits SPDX documents at build time. SPDX 2.3 remains what most tooling consumes, even though the 3.0 spec landed in April 2024. An SBOM is not a substitute for source, but it is the fastest check I run: when an SBOM lists BusyBox 1.35.0 while the binary on the flash identifies itself as BusyBox v1.31.1, the release process failed somewhere between the manifest and the factory image. The SPDX specification is the format to target.

The release bundle: publish on day one

Per hardware revision, as a single archive on the product page, this is what I expect to find:

  • The KiCad project — schematic and board files — plus a schematic PDF, gerbers, and a BOM with ordering part numbers.
  • The DTS for each hardware revision, pinned to the exact kernel commit, with the kernel .config and the patch series as a branch or mbox.
  • The U-Boot defconfig and patch series against the exact upstream tag (v2022.10 in one recent audit), not a bare tarball.
  • The cross toolchain’s version and origin, with the sha256 of the tarball.
  • A build manifest: a Buildroot defconfig (2023.02.2) or a Yocto layer with its configuration, plus the legal-info or create-spdx output.
  • An SPDX SBOM for the root filesystem.
  • Either complete corresponding source accompanying the product, or the GPL-2.0 §3(b) written offer.

The written offer is quoted directly in GPL-2.0 §3(b): "a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code." Three years is a floor, not a target; my rule for clients is the product’s support lifetime plus two years. Post the sha256 of the source archive next to the download — a GPL tarball with no hash on a plain-HTTP product page is a supply-chain question mark, and I note it as one in reports.

Printed circuit board under inspection with measurement probes
Publish the release bundle first; an auditor will reconstruct it anyway, and less charitably.

What the case record says about boards that skip this

None of the recurring enforcement anchors involved exotic engineering. gpl-violations.org v. D-Link (Landgericht Frankfurt, judgment of September 2006) concerned a wireless adapter shipped with a modified Linux kernel and no corresponding source; the court found infringement and awarded damages, and the lesson that stuck — distribution triggers the obligation — applies to every board leaving a warehouse. FSF v. Cisco (filed November 2008 in the Southern District of New York, settled 2009) arose from the Linksys line: the FSF alleged repeated failures to provide source for Linux, BusyBox, and other GPL programs, and the settlement included publishing source and appointing a compliance lead. The earlier WRT54G source release that grew out of 2003 enforcement is what seeded OpenWrt, an ecosystem that sold routers for a decade.

The Software Freedom Conservancy’s BusyBox litigation (2007 onward) produced the first US GPL copyright suits; the September 2009 default judgment against Westinghouse in the Southern District of New York — $90,000 in damages and a permanent injunction — went to a defendant that never answered the complaint. SFC v. Vizio, filed in October 2021 in California state court over SmartCast televisions, is the one to watch for anyone designing connected appliances: after removal to federal court, the 2022 remand order treated GPL-2.0 as creating contract rights enforceable by third-party beneficiaries. I could not find a final published judgment as of my last review of the public docket, so the consumer-standing question should be treated as live, not settled.

The common thread is unglamorous: every case turned on a missing, stale, or ignored source offer. No defendant lost because its engineering was too clever. They lost because nobody owned the release process, and designing for auditability costs less than any of those outcomes.

Frequently asked questions

Does the GPL require me to open-source my PCB design?

No. GPL-2.0 §3 covers the corresponding source of the GPL works shipped in firmware: the kernel, U-Boot, BusyBox, the build scripts, and the DTS that compiles into the DTB. A schematic is not the source of a GPL work, and no court has read the GPL to reach hardware design files. Publishing them under CERN-OHL is a voluntary choice — one I recommend for auditability — but it is not a GPL obligation.

Which open hardware license should I pick for a Linux board?

CERN-OHL-S-2.0-or-later as the default for schematic, layout, and gerbers; CERN-OHL-W-2.0 if you want share-alike to follow derivatives of the board; CERN-OHL-P-2.0 for permissive terms. Add OSHWA certification if you want an independently checkable registry entry. Whichever you choose, state it per artifact — ambiguity is worse than any of the options.

Can I ship a locked bootloader and still comply with GPL-2.0?

It is contested. GPL-2.0 §6 prohibits further restrictions on the granted rights, and the TiVo dispute that motivated GPL-3.0’s installation-information clause never reached a court. GPL-3.0 §6 answers the question explicitly for User Products: installation information, including authorization keys, must accompany the source. For GPL-2.0 firmware, my practice is to publish a documented unlock path, because the legal risk sits with the distributor and the case law does not resolve it.

What is the minimum source release for a board running U-Boot, Linux, and BusyBox?

Complete corresponding source at the exact commits shipped: kernel with .config and patches, U-Boot with defconfig and patches, BusyBox with its .config, the board DTS, the cross toolchain version, and the build manifest — plus either source accompanying the product or the §3(b) written offer, valid for at least three years. An SPDX SBOM on top makes the release checkable in minutes instead of hours.

What comes next for this column

The next article in this series covers the extraction side of this checklist: reading SOP-8 flash in-circuit with flashrom, a CH341A, and a Pomona 5250, including the two wiring mistakes that cost me a W25Q128JV early on. I am also building a running reference page of SPI flash parts and their JEDEC IDs — ef 40 18, c2 20 18, c8 40 18 and their kin — because identifying the part is always the first five minutes of an audit. If you ship a Linux-based board and want a pre-release compliance read, send it in; the Board Autopsy series runs on reader submissions, and the boards that arrive with the checklist above already applied are the ones that get written up in a single afternoon.