Platform index / Digital mixing console
Allen & Heath SQ-5
A 55 MB firmware image that contains none of the mixer. The entire audio path lives in FPGA fabric behind an undocumented AXI register map.
The load-bearing finding. The update package is 55 MB of ARM image and 2.5 MB of bitstream — and the 2.5 MB is the mixer. Most of the 55 MB is uncompressed UI artwork.
Verdict. A poor rehosting target, but not for the usual reasons. There is no secure boot and no signing — yet none of the mixer is in the software you would replace. If it were ever pursued, the correct first move is JTAG, not the USB update path: dump the 64 MB QSPI intact before writing anything.
Method
Static analysis of a single vendor firmware update file. No hardware was inspected. The firmware image was not retained, so the analysis currently cannot be re-derived without obtaining it again.
Artifacts examined
SQ-5UPG_1_6_3r6268.bin— three records, no compression, no encryption
No manufacturer firmware, binaries or documentation are redistributed here. Artifacts are referenced by name and version only. See themethod and legal statement for the basis on which this analysis was performed and the boundaries it observes.
Hardware architecture
| Item | Finding | Confidence |
|---|---|---|
| SoC | Xilinx Zynq-7000 XC7Z020 — proven from the bitstream's IDCODE configuration packet (30018001 → 03727093), not inferred | Verified |
| Corroboration | Linked Xilinx PS drivers: xemacps, xscugic, xdevcfg, xqspips, xiicps, xttcps, xuartps, plus lwIP 2.0.3 (xilinx_modified) | Verified |
| FPGA count | One. xdevcfg with PCAP_FPGA_DONE_FAIL shows the bitstream loading into this same chip's PL over the PCAP bridge — there is no second FPGA | Verified |
| DRAM | ≥1 GB — inferred from CPU1's 0x20100000 load address (513 MB in) against the Zynq-7000 PS ceiling of 1 GB. No memory-controller config was decoded | Inferred |
| Boot flash | Dual-parallel QSPI NOR, ~64 MB (InitQspi2Dual). Dual-parallel means two devices striped — a naive single-chip dump gets every other byte | Verified |
| Surface MCU | A fader/surface MCU flashed over SPI from the ARM (Expected Fader Version %u.%u, updating...) | Verified |
| FX board | Separate board with its own DSPs and SDRAM (FX board ID 0x%02X not recognised, FX[0] failed SDRAM test) | Verified |
Software architecture
| Item | Finding | Confidence |
|---|---|---|
| Operating system | None. Zero FreeRTOS, ThreadX or Linux strings — a bare-metal Xilinx standalone BSP with a custom message-block system and a custom GUI | Verified |
| Core model | AMP across both Cortex-A9s, not SMP. CPU0: sending Start Msg to CPU1 | Verified |
| CPU0 | sQu_Host at 0x00100000 — mixer control, GUI, protocols | Verified |
| CPU1 | sQu_USB at 0x20100000 — SQ-Drive: USB host, FAT, WAV. Directory layout /AHSQ/USBRec, /AHSQ/Scenes, /AHSQ/Shows appears verbatim | Verified |
| Container header | 0x70 (112) bytes, computed as next_offset − this_offset − payload_len and confirmed independently at both gaps. It is not read from any field | Verified |
| Payload format | Despite .elf names the payloads are raw ARM32 images, each with a 16-byte preamble; byte 16 onward is the ARM exception vector table | Verified |
| Code fraction | Only ~10–16 MB of the 55 MB host image is code. From 16 MB on it compresses to 9–27%, i.e. uncompressed artwork and fonts | Verified |
Update path & security model
| Item | Finding | Confidence |
|---|---|---|
| Image signing | None. No RSA, SHA or AES strings anywhere in either image | Verified |
| Update validation | CRC only, and the variant was not identified — Error in firmware header, VerifyFlash Expected CRC to be 0x%lx, but calculated 0x%lx | Verified |
| Bitstream encryption | Not encrypted. The CTL0 write is 0x00001501 with the DEC bit (bit 6) clear and no key-load sequence, so the bitstream is analysable | Verified |
| Recovery | A/B image banks with Zynq multiboot. The update overwrites the inactive bank; the first-stage bootloader is not in the update file and is not protected by the A/B scheme | Verified |
| Entitlement | An entitlement mechanism exists and was identified. Analysis stopped there — see the methodology page | Verified |
These rows describe how a platform validates a firmware image, because that is a structural fact about its architecture. They are not a vulnerability disclosure and no exploit, bypass or circumvention technique is published here. Licensing and entitlement mechanisms are out of scope throughout — seescope boundaries.
What is programmable
- 1Interoperability, not rehosting
The SLink slot takes gigaACE, Dante and Waves cards, and Allen & Heath publish the SQ MIDI/TCP control protocol. Almost anything that motivated looking at the firmware in the first place is better served here, and none of it needs reverse engineering.
- 2The AXI register map — the one thing genuinely worth reversing
Map the PS↔PL interface and the black box becomes documented hardware: you could drive the stock mixing engine from your own software, which is a far better position than replacing either half. It is also reachable non-destructively, with the stock bitstream loaded and nothing written to flash.
- 3The PL bitstream
Unencrypted, and Project X-Ray covers Artix-7 and Zynq-7 fabric, so it is analysable in principle. In practice it is a very large project and it is downstream of understanding the register map anyway. Not step one.
- 4Linux on the PS
Entirely feasible and almost pointless on its own — it gets you Linux wired to a black box you cannot command. Worth doing only as a means of probing the AXI map.
Traps
Mistakes this analysis actually made, or came close to making. They are recorded because each one produces a plausible-looking wrong answer rather than an obvious failure.
- A parser assuming a 0x24 or 0x40 container header parses record 0 plausibly and then lands mid-payload in 55 MB of ARM code and artwork.
- The correct load mapping for the host image is VA = file offset + 0x103DD0, pinned empirically from the GUI string-pointer table — not the 0x100000 the container header implies.
- GUI strings are reached through a master string-pointer table indexed by string ID, so they have no direct LDR-literal cross-reference. Only BSP and system strings are loaded directly.
Open questions
- The PL's AXI register map is entirely undocumented — this is the whole audio path, and it is the single most important missing piece.
- The FX board's DSPs are a genuine gap: not the vendor, not the architecture, not how code reaches them. The `FX[0]` indexing implies more than one.
- The first-stage bootloader is not in the update file and has never been seen. The A/B banks protect the application images, not it.
- The debug UART is near-certainly populated (xuartps is linked and printf diagnostics are everywhere) but has never been located on a board.
Status of this entry. A written teardown exists and its claims carry evidence citations. Unless a row says otherwise, nothing on this page has been verified against physical hardware.