- C 53%
- Shell 29%
- Python 16.3%
- PowerShell 1.5%
- Makefile 0.2%
Correcting this project and myself. The failure has been described
throughout as a core-count threshold - "1-2 busy A15 cores clean, 3 hard
resets, 4 corrupts". That is wrong, for a boring reason: every test step
was 45 seconds long, and 2 cores take about 45 seconds to kill the board.
Re-measured with 5 s heartbeats written to disk with sync, so the last
line before the log stops is the survival time:
1 A15 busy, A7 idle reset ~85 s zone3 81 C
2 A15 busy, A7 idle reset ~40 s zone3 80 C
2 A15 busy, 4 A7 busy reset ~60 s zone3 81 C
3 A15 busy reset in seconds
0 A15 busy, 4 A7 busy, 7 min never zone3 59-60 C, flat
Load does not decide whether the board dies, only how fast. One busy A15
core is enough, given ninety seconds.
Every reset lands at 77-81 C on thermal_zone3 and every survival at 77 or
below - four independent failures, one number - while the SoC's own trip
is 95 C and pstore stays empty. 52-a15-not-dram.md ruled thermal out on a
run that peaked at 69 C, below this line, which is why it never showed up.
That dismissal was right for its run and wrong in general; a banner now
says so on that note.
The A7 control is the sharpest number: four busy A7 cores at 1008 MHz do
not move the temperature at all over seven minutes, while one A15 core at
1608 MHz adds ~20 C in 85 s.
Two readings remain, and a free test separates them: if the external
DC-DC's over-temperature protection is tripping, airflow fixes it; if it
is a current limit and temperature is only a proxy for dissipated power,
airflow changes nothing. Point a fan at it. That is now cheaper and more
decisive than the larger power supply.
Consequence for workarounds, which is how this came up: there is no N for
which "at most N busy A15 cores" is safe, because N=1 fails. No cpufreq
governor gates core count anyway, and mainline's idle injection is worse
than useless here - it idles a cooling domain in sync, preserving the peak
concurrency while lowering the average.
Documentation brought current alongside this:
- README "State of the port" is now the live status and says so; the
A15, S/PDIF, HDMI-audio, cpufreq and thermal rows were stale, and
there was no row for Docker.
- 18-current-state.md was still the README's "start here" while
asserting that nothing had ever been written to the board and that
all 8 cores come up. Marked as a 2026-08-27 snapshot, with the three
false claims called out; the start-here pointer now goes to the
README table.
|
||
|---|---|---|
| ar100-re | ||
| ar100-re80 | ||
| boot-images | ||
| bsp | ||
| firmware | ||
| kicad | ||
| linux-sunxi.org | ||
| logs | ||
| patches | ||
| probe | ||
| tools | ||
| usb3-re | ||
| .gitattributes | ||
| .gitignore | ||
| 01-hardware.md | ||
| 02-mainline-status.md | ||
| 03-gaps-analysis.md | ||
| 04-build-plan.md | ||
| 05-references.md | ||
| 06-boot-log-findings.md | ||
| 07-live-system-dump.md | ||
| 08-dvfs-tables.md | ||
| 09-build-setup.md | ||
| 10-cpufreq-implementation.md | ||
| 11-board-gpio-map.md | ||
| 12-boot-attempts.md | ||
| 13-first-mainline-boot.md | ||
| 14-boot-debugging.md | ||
| 15-SUCCESS-userspace.md | ||
| 16-ethernet-broken.md | ||
| 17-mmc1-investigation.md | ||
| 18-current-state.md | ||
| 19-STANDALONE-BOOT.md | ||
| 20-usb-topology.md | ||
| 21-ETHERNET-WORKING.md | ||
| 22-dram-4gb.md | ||
| 23-sd-boot.md | ||
| 24-thermal-sensor.md | ||
| 25-usb3-feasibility.md | ||
| 26-a15-cluster.md | ||
| 27-ar100-protocol.md | ||
| 28-ar100-firmware-re.md | ||
| 29-arisc-driver-spec.md | ||
| 30-ar100-dvfs-blocked.md | ||
| 31-power-topology.md | ||
| 32-USB3-WORKING.md | ||
| 33-REAL-PINMAP.md | ||
| 34-ethernet-cold-boot.md | ||
| 35-a15-rail-enable.md | ||
| 36-rescue-sd.md | ||
| 37-arisc-driver.md | ||
| 38-userspace-hardening.md | ||
| 39-ir-and-leds.md | ||
| 40-bluetooth.md | ||
| 41-production-plan.md | ||
| 42-upstreaming.md | ||
| 43-audio-and-dma.md | ||
| 44-hdmi.md | ||
| 45-a15-cluster-solved.md | ||
| 46-hdmi-picture.md | ||
| 47-hdmi-audio-cec.md | ||
| 48-a15-memory-corruption.md | ||
| 49-audio-clock-wrong.md | ||
| 50-uboot-resilience.md | ||
| 51-audio-pll-vco-ceiling.md | ||
| 52-a15-not-dram.md | ||
| 53-vendor-firmware-archive.md | ||
| 54-powervr-feasibility.md | ||
| 55-gpu-linux-plan.md | ||
| 56-uboot-gmac-and-pmic.md | ||
| 57-4gb-reclaimed.md | ||
| 58-docker.md | ||
| 59-spdif-txim.md | ||
| 60-a15-power-budget.md | ||
| 61-a15-eighty-degrees.md | ||
| AI-ASSISTANCE.md | ||
| ARCHIVE.md | ||
| README.md | ||
| TODO.md | ||
Allwinner A80 (sun9i) — Tronsmart Draco AW80 Telos
Bringing mainline Linux up on a Tronsmart Draco AW80 Telos Android TV box
(Allwinner A80 / sun9i, 4 GiB DDR3, 32 GB eMMC).
Start here: the State of the port table below — that is the live status, kept current. Then 41-production-plan.md for where this is going, and Picking this up cold below for the practical details. (18-current-state.md used to be the entry point; it is now a 2026-08-27 snapshot and is marked as such.)
Open work is tracked as issues on this repository, labelled by type and priority.
TODO.mdholds longer-form deferred items and the history of what was already resolved.
Provenance: this port was done with AI assistance. What that means for how much to trust any given claim here is set out in AI-ASSISTANCE.md — worth reading before relying on anything load-bearing.
State of the port
| Subsystem | Status |
|---|---|
| Boot, U-Boot, eMMC, SD | working; boots standalone from eMMC, extlinux menu with known-good fallback; SD hotplug on PH17 |
| DRAM | 3.5 GiB by default; all 4 GiB reachable via mem= + a CMA cap, verified by holding 3680 MiB resident with 0 errors, see 57. Geometry validated by full-range mtest, see 22 |
| Ethernet | 1 Gbps, cold boot fixed in-kernel (40 ms MDIO settle) |
| WiFi | working — AP6335/BCM4339, associates, DHCP, survives reboot; regulatory domain now resolves (was stuck in world/country 00) |
| USB 2.0 / 3.0 | both black ports + 5 Gbps xHCI (80 MB/s measured) |
| Thermal | 4 zones + hwmon, trip points. Idle ~59 °C; full A7 load does not raise it measurably, one A15 core raises it ~20 °C in 85 s |
| A7 cluster (4 cores) | working |
| Containers | Docker works — cgroup v2, overlayfs, seccomp, AppArmor, and a scoped nftables ruleset that does not break container networking, see 58 |
| A15 cluster (4 cores) | 🔴 not usable under any sustained load — the board hard-resets: 1 busy core ~85 s, 2 cores ~40 s, 3 cores in seconds. Load sets only how fast, not whether. Every failure lands at ~80 °C on thermal_zone3 (the SoC's own trip is 95 °C), while 4 busy A7 cores do not move the temperature at all. Not DRAM, not voltage, and not supply quality — two different 12 V / 2 A bricks behave identically. At 1800 MHz it also silently corrupts memory. See 52, 60. Board boots A7-only by default |
| cpufreq / DVFS | still open — the clk driver does not track what the AR100 does to PLL_C1. ⚠️ clk_summary reports c1cpux at 408 MHz while the cluster is really at 1608; time a loop instead of reading the clock tree |
| Recovery | watchdog + ramoops proven in Linux; U-Boot now self-recovers too — armed watchdog, 60 s boot-retry, unattended known-good fallback, see 50 |
| Crypto engine | working — AES/3DES ECB+CBC offload, kernel self-tests pass |
| IR receiver | decodes NEC — 11 scancodes off the stock remote; needs irclk.ko, see 39 |
| Bluetooth | working — BCM4339 on uart2, firmware patched, scans, unique BD address |
| DMA engine | working — 16 channels, 74 MB/s, 0 failures over 83k transfers |
| Audio (S/PDIF) | working and audible — LPCM at S16_LE/S24_LE/S32_LE, plus AC-3 passthrough (receiver shows Dolby Digital). The last fault was one bit, FCTL.TXIM, which must follow the sample width, see 59. DTS passthrough is untested, for a reason outside the board (#78) |
| Audio (HDMI) | working and audible; both the 48 kHz and 44.1 kHz families are exact — the last fault was a PLL VCO ceiling, fixed with sigma-delta, see 51. AC-3 passthrough works here too, with a fuller channel status than the S/PDIF path carries, see 59 |
| Audio (analog) | not started — needs an AC100 codec driver, see 43 |
| HDMI | working — console on the TV at boot and a SMPTE pattern under DRM, 1920x1080@60, see 46 |
| Display engine | working — four mainline faults fixed; frontend/scaler still has no sun9i driver |
| HDMI-CEC | working — logical address claimed and the TV answers, see 47 |
Three independent ways in: ethernet 192.0.2.44, WiFi 192.0.2.45,
serial on the build host. A bootable rescue SD card carries all three.
Notes
Numbered in the order they were written; later notes correct earlier ones where they disagree, and say so explicitly.
| File | Contents |
|---|---|
| 01-hardware.md | Hardware Inventory — Tronsmart Draco AW80 Telos |
| 02-mainline-status.md | Mainline Support Status — sun9i / A80 |
| 03-gaps-analysis.md | Gap Analysis — Where Digging Pays Off |
| 04-build-plan.md | Bring-Up Plan — Draco AW80 Telos |
| 05-references.md | References |
| 06-boot-log-findings.md | Boot Log Findings — first capture, 2026-08-26 |
| 07-live-system-dump.md | Live System Dump — root shell over serial, 2026-08-26 |
| 08-dvfs-tables.md | DVFS: the vendor V/F tables, and why the sweep read flat |
| 09-build-setup.md | Build Environment |
| 10-cpufreq-implementation.md | cpufreq for sun9i — implementation |
| 11-board-gpio-map.md | Board GPIO map — from the vendor sys_config.fex |
| 12-boot-attempts.md | Boot attempts — what has been tried and what happened |
| 13-first-mainline-boot.md | First mainline boot — 2026-08-26 ✅ |
| 14-boot-debugging.md | Boot debugging — chasing the console death |
| 15-SUCCESS-userspace.md | ✅ Mainline Linux booting to userspace with a root shell |
| 16-ethernet-broken.md | Ethernet on sun9i mainline — root cause found, needs driver work |
| 17-mmc1-investigation.md | mmc1 (SDIO WiFi) — the boot killer |
| 18-current-state.md | Current state — what works and what doesn't |
| 19-STANDALONE-BOOT.md | ✅ Standalone boot from eMMC — FEL retired |
| 20-usb-topology.md | USB topology — what this board actually has |
| 21-ETHERNET-WORKING.md | ✅ Ethernet works — 1 Gbps, DHCP, SSH |
| 22-dram-4gb.md | ✅ 3.5 GiB DRAM — three bugs fixed, verified, installed |
| 23-sd-boot.md | ✅ SD boot — FEL retired from the workflow |
| 24-thermal-sensor.md | ✅ A80 thermal sensors working — full bring-up sequence |
| 25-usb3-feasibility.md | USB 3.0 on the A80 - feasible, and smaller than expected |
| 26-a15-cluster.md | 🔑 A15 cluster: root cause found — inverted power-clamp polarity |
| 27-ar100-protocol.md | AR100 coprocessor — complete protocol specification |
| 28-ar100-firmware-re.md | AR100 firmware — reverse engineering the blob |
| 29-arisc-driver-spec.md | drivers/arisc/ — the vendor ARM-side driver, read |
| 30-ar100-dvfs-blocked.md | 0x30 reaches its handler and fails inside the AR100's voltage path |
| 31-power-topology.md | Power topology — what is actually on this board |
| 32-USB3-WORKING.md | ✅ USB 3.0 works — xHCI SuperSpeed on mainline |
| 33-REAL-PINMAP.md | ✅ The real pin map — the black USB ports work, and the A15 rail is found |
| 34-ethernet-cold-boot.md | Ethernet: works warm, fails cold — the PHY wakes up ~40 s late |
| 35-a15-rail-enable.md | Enabling the A15 rail — PL02 confirmed, and why it takes the board down |
| 36-rescue-sd.md | The rescue SD card |
| 37-arisc-driver.md | A mainline AR100 driver — working, with the A15 hand-off still refused |
| 38-userspace-hardening.md | Watchdog, ramoops, time sync, module workflow — making the board survivable |
| 39-ir-and-leds.md | IR receiver works; the LEDs were never where the fex said |
| 40-bluetooth.md | Bluetooth works — AP6335 BT over uart2, scanning |
| 41-production-plan.md | Audit + phased plan to make this a headless production host |
| 42-upstreaming.md | How this work should be submitted upstream — nothing has been |
| 43-audio-and-dma.md | S/PDIF, the missing DMA engine behind it, and a mainline bug |
| 44-hdmi.md | HDMI works — it is a DesignWare TX. The display engine does not yet |
| 45-a15-cluster-solved.md | Eight cores — the clamp polarity is only inverted on rev A silicon |
| 46-hdmi-picture.md | A picture on the TV: four faults, and a probe that lied for hours |
| 47-hdmi-audio-cec.md | HDMI audio and CEC — CEC works; audio plays but nobody has listened |
| 48-a15-memory-corruption.md | 🔴 The A15 cluster corrupts memory under load, silently |
| 49-audio-clock-wrong.md | 🔑 Every audio clock was wrong; the instrument that said so was ignored |
| 50-uboot-resilience.md | The bootloader recovers from four things that used to need a physical visit |
| 51-audio-pll-vco-ceiling.md | The last audio fault: the PLL's VCO ceiling, and the sigma-delta table sun9i never got |
| 52-a15-not-dram.md | 🔑 The A15 corruption is not DRAM, not heat, not voltage — and not cured |
| 53-vendor-firmware-archive.md | Nine vendor images recovered, and what they do not tell us |
| 54-powervr-feasibility.md | 🔑 The GPU is reachable after all — we hold the kernel-mode DDK source |
| 55-gpu-linux-plan.md | Implementation plan for accelerated GLES under mainline Linux |
| 56-uboot-gmac-and-pmic.md | U-Boot: the GMAC builds; the PMIC sits behind a clock nobody had written |
| 57-4gb-reclaimed.md | 🔑 The last 512 MiB, reclaimed — and U-Boot was never the blocker |
| 58-docker.md | Docker on the board end to end, and the 8 MiB bootm ceiling that hid behind it |
| 59-spdif-txim.md | 🔑 S/PDIF: one bit, and why no instrument on the board could find it |
| 60-a15-power-budget.md | 🔑 The A15 rail's ceiling is 1.1 V, the box's is 24 W - and the missing datasheet was the wrong question |
| 61-a15-eighty-degrees.md | 🔑 The A15 has no core-count threshold - it has ~80 °C, and one busy core is enough |
| AI-ASSISTANCE.md | Provenance, verification standard, and where the AI got it wrong |
| ARCHIVE.md | Every artifact: what is in git, what is too big, what is re-fetchable |
Also: TODO.md — deferred items with enough context to pick up cold.
Layout
| Path | Contents |
|---|---|
logs/ |
serial captures, boot logs, command transcripts |
tools/ |
host-side helper scripts (serial capture and shell) |
ar100-re/ |
AR100 firmware v0.0.37 reverse engineering — disassembly and tooling |
usb3-re/ |
USB3 work, plus the board's real script.bin and decoded fex |
patches/ |
the kernel and U-Boot work, exported as per-maintainer series |
boot-images/ |
eMMC boot-area snapshots (1 MiB each, gzipped) |
ar100-re80/ |
AR100 firmware v0.0.80 disassembly |
bsp/ |
vendor driver sources used as reference |
probe/ |
out-of-tree test-module template — poke registers without /dev/mem |
The recovered
usb3-re/draco-real-script.fexis the authority for this board's pin map and rails. Asys_config.fexthat saysmachine = "cubieboard4"was treated as ground truth for a long time and was wrong about USB, the SD slot, WiFi, and the A15 power rail. Check provenance before trusting a config file.
Picking this up cold
Everything needed to resume without reconstructing context.
Machines
Addresses and identifiers here are placeholders, and will not work as written. This repository is public, so lab-specific values were genericised on 2026-08-29 (issue #6).
192.0.2.xis the RFC 5737 documentation range and keeps the real last octet,builderstands in for the build-host account,HomeNetfor the WiFi SSID, and MAC addresses keep their real OUI and their relationships to one another but not their device-unique bytes. Substitute your own throughout. The mapping is deliberately not recorded here.
| build host | ssh builder@192.0.2.46 (ouranos). Kernel ~/a80/linux, U-Boot ~/a80/u-boot |
| board, ethernet | ssh root@192.0.2.44 from ouranos — not reachable from elsewhere |
| board, WiFi | ssh root@192.0.2.45 — an independent path, and it has already saved a session |
| board, serial | /dev/ttyUSB0 on ouranos, 115200, needs sudo. The black box; keep it capturing |
Build and deploy
# on ouranos - always -j4, the host is shared
cd ~/a80/linux && export ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
make -j4 uImage dtbs LOADADDR=0x20008000 # NOT 0x40008000 - costs 512 MiB silently
~/a80/deploy-kernel.sh --build --reboot # md5-verifies both ends, rotates uImage.prev
~/a80/deploy-kernel.sh --known-good # only after it has proven it boots
When it will not boot
- Interrupt on serial and pick known-good from the extlinux menu (3 s timeout).
- Or over SSH:
cp /boot/uImage.known-good /boot/uImageand reboot. - Or insert the SD rescue card — BROM tries SD before eMMC, so it boots regardless of
how broken
/booton the eMMC is. See 36-rescue-sd.md. - If the SoC is wedged before any of that, it needs a power cycle — there is currently no remote way to do it, which is the point of the open issue on remote power control.
hostname tells you which system answered: a80-debian is the eMMC, a80-rescue is the card.
After a crash
The dmesg tail survives a reset in ramoops. Look in /var/lib/systemd/pstore/, not
/sys/fs/pstore — systemd-pstore moves the records out on boot, so pstore itself looks
empty and misleadingly healthy.
Poking registers
Build an out-of-tree module on ouranos and insmod it. Do not use /dev/mem from
userspace — it hung the SoC twice.
cd ~/a80/linux && make -j4 M=$HOME/a80/probe modules
scp ~/a80/probe/a80probe.ko root@192.0.2.44:/tmp/ && ssh root@192.0.2.44 insmod /tmp/a80probe.ko
Conventions
- Notes are numbered in the order written; later notes correct earlier ones and say so.
- Measurements are quoted verbatim from the board; explanations are reasoning. ⚠️ marks things believed but not verified.
- The authority for pins and rails is
usb3-re/draco-real-script.fex, and even then only where the owning section is_used = 1and no other section claims the same pin.