Reproducible recipe for building signed custom firmware for Qualcomm Atheros AR9271 USB WiFi dongles (TP-Link TL-WN722Nv1, Alfa AWUS036NHA, ASUS USB-N13 v1, and others), validated on the live chip with automatic rollback.
This is not a fork of the firmware itself — it's a recipe + tooling that wraps qca/open-ath9k-htc-firmware and solves the modern toolchain bootstrap problem.
Building open-ath9k-htc-firmware on a 2026 Linux system fails immediately:
configure: error: could not find a working compiler
make: *** [Makefile:147: .../gmp-6.2.0/.built] Błąd 1
GMP 6.2.0 (a build dependency of the GCC 10.2 cross-compiler that the repo bootstraps) uses K&R-style function declarations:
void g(){}
/* ... */
g(i, d[i].src, d[i].n, got, d[i].want, 9); /* 6 args to a 0-arg function */Modern GCC (15.x, 16.x) treats this as error, not warning. The toolchain build dies before producing a single xtensa-elf-gcc.
This repo provides:
- A Docker recipe that uses
debian:11(GCC 10.2.1 — matches what the upstream repo was designed against) so patches apply cleanly andmake toolchainsucceeds without modification. - A minimal signature patch demonstrating where and how to inject custom data into the firmware blob, with verification via
strings. - A safe live-test script that loads the custom firmware via the kernel's
use_dev_fw=1mechanism without touching the productionhtc_9271-1.4.0.fw, with automatic rollback on timeout orCtrl+C.
- Reproducible cross-compiler: xtensa-elf-gcc 10.2.0 targeting AR9271's specific Xtensa core (
XCHAL_HAVE_DIV32=0,MUL32_HIGH=1,ABSOLUTE_LITERALS=1) - A signed
htc_9271.fwbinary (51008 bytes — identical slot to vendor) - Live-test confirmation via
dmesgthat the chip enumerates with your firmware - A clean rollback path so production WiFi isn't at risk
- Not a TX power unlock. AR9271 TX power tables live in the EEPROM, not the firmware. Modifying firmware does not change TX dBm. For TX/regulatory changes you need to reflash the external EEPROM (separate hardware project, see "What's next" below).
- Not a LED/retry mod. Those policies live in the kernel driver (
ath9k_htc), not in the firmware. The firmware is a thin layer: USB protocol + low-level MAC + WMI service. - Not a security tool. This is a portfolio-quality reproducibility exercise, not an exploitation framework.
# 1. Clone upstream firmware repo (separate dir):
git clone https://github.com/qca/open-ath9k-htc-firmware.git ~/src/ath9k-htc-firmware
cd ~/src/ath9k-htc-firmware
# 2. Apply this repo's signature patch:
git apply /path/to/ar9271-sovereign-build/patches/0001-sovereign-build-signature.patch
# 3. Bootstrap toolchain inside Debian 11 container (GCC 10 matches repo deps):
docker run --rm -v "$PWD":/work -w /work debian:11 bash -c "
apt-get update -qq &&
apt-get install -y -qq build-essential cmake wget gperf bison flex \
texinfo libtool gawk patch m4 file &&
make toolchain
"
# 4. Build the firmware itself (same container, toolchain on path):
docker run --rm -v "$PWD":/work -w /work debian:11 bash -c "
apt-get update -qq &&
apt-get install -y -qq build-essential cmake perl &&
export PATH=/work/toolchain/inst/bin:\$PATH &&
make -C target_firmware
"
# 5. Verify signature embedded:
strings target_firmware/htc_9271.fw | grep -i sovereign
# → SOVEREIGN-BUILD:...Output: target_firmware/htc_9271.fw — 51008 bytes, with your signature embedded.
sudo scripts/test-sovereign-fw.shThis will:
- Stop any AP using the AR9271 (
hostapd-balkonby default — edit if you use a different unit). - Install your custom build as
/lib/firmware/ath9k_htc/htc_9271-1.dev.0.fw(separate path — the kernel loads this only whenuse_dev_fw=1). rmmod ath9k_htc && modprobe ath9k_htc use_dev_fw=1.- Print
dmesgshowing the loaded firmware path, transfer size, HTC init credits, chip revision, and interface state. - After 30 seconds (or
Ctrl+C), automatically:- Reload the production firmware (
rmmod+modprobewithout param). - Remove the dev firmware file from
/lib/firmware/. - Restart
hostapd-balkon.
- Reload the production firmware (
Verified evidence from a successful live load:
[15767.941398] usb 1-7: ath9k_htc: Firmware ath9k_htc/htc_9271-1.dev.0.fw requested
[15769.028664] usb 1-7: ath9k_htc: Transferred FW: ath9k_htc/htc_9271-1.dev.0.fw, size: 51008
[15769.275417] ath9k_htc 1-7:1.0: ath9k_htc: HTC initialized with 33 credits
[15769.501790] ath9k_htc 1-7:1.0: ath9k_htc: FW Version: 1.4
[15769.505162] ieee80211 phy17: Atheros AR9271 Rev:1
[15769.510881] ath9k_htc 1-7:1.0 wlan_ap: renamed from wlan0
Full provenance in BUILD-CERTIFICATE.txt.
patches/0001-sovereign-build-signature.patch injects an __attribute__((used)) string into wlan/if_ath.c so the linker keeps it in the final binary. After build, strings htc_9271.fw | grep -i sovereign returns your signature.
Why bother? Because it proves the binary came from your build. The SHA256 is also unique per build, but a signature is human-readable and survives recompilation as long as the source is the same. It's the smallest possible portfolio-worthy mod.
For actual capability changes on the AR9271:
- TX power / regulatory unlock → physically open the dongle, identify the SOIC-8 25-series SPI flash and/or 24-series I2C EEPROM, dump with
flashrom -p ch341a_spi(SPI) orch341prog(I2C), modify, reflash. The dongle datasheet (LPCC-68, page 14) confirms both peripherals are typically external. - LED / retry tuning → kernel driver mod in
drivers/net/wireless/ath/ath9k/, not firmware. - Frame injection improvements → that's actually in firmware, see PR #163 for the pattern.
This recipe is intended for security research, education, and reproducible firmware build practice on hardware you own.
- No warranty of any kind, express or implied — see GPL-2.0 sections 11-12.
- Users are responsible for compliance with local regulations (telecommunications law, RF emissions, regulatory domains, EIRP limits).
- This recipe explicitly does not unlock TX power, region locks, or other regulatory controls (those live in the EEPROM, not the firmware — see "What this is NOT" above).
- Do not use against hardware you do not own or have explicit authorization to test.
- The author bears no responsibility for misuse, hardware damage, regulatory violations, or data loss arising from use of this material.
The legitimate primary use cases are: learning how the AR9271 firmware is structured, solving the modern toolchain bootstrap problem (GCC 15+), demonstrating safe live-test methodology with auto-rollback, and contributing to FOSS understanding of Atheros hardware. The included test-sovereign-fw.sh script deliberately uses the kernel's use_dev_fw=1 mechanism so production firmware is never touched.
The signature patch and tooling in this repo are GPL-2.0 to match the upstream firmware repo's licensing of the modified file (wlan/if_ath.c carries ECOS GPLv2 caveats per upstream's NOTICES.TXT). Other build scripts under this repo are also GPL-2.0 for consistency.
Upstream firmware itself is under the ClearBSD license held by Qualcomm Atheros; see qca/open-ath9k-htc-firmware/LICENCE.TXT. This repo distributes no upstream code — only a patch + tooling.
- SyriusM/rtl8188eus-efuse-tool — userspace CLI for OTP EFuse memory on Realtek RTL8188EUS USB WiFi dongles (libusb bypass kernel driver).