Как я добавил в QUAD 3 прямой выбор входов: реверс ARM-прошивки, бинарный патч и 64 байта здравого смысла

Есть вещи, которые сложно объяснить рационально. Например, современный интегральный усилитель умеет HDMI ARC, USB Audio, Bluetooth, ЦАП на ESS, MM-фонокорректор, триггеры, хранение настроек и работу с телевизором по CEC. Но выбрать конкретный вход с пульта одной кнопкой не умеет. Именно так устроен мой QUAD 3: нужно нажимать Source, листать входы по кругу — BT, USB, OPT, COAX, ARC, AUX1, AUX2, PHONO — и смотреть на дисплей.
Поначалу я собирался решить вопрос снаружи: ESP32, ИК-передатчик, Home Assistant, отслеживание текущего состояния и вычисление количества Source+ и Source-. Схема вполне рабочая, но слишком сложная для задачи уровня «выбрать USB». Поэтому возник другой вопрос: почему бы не добавить в прошивку QUAD 3 дискретные IR-команды выбора входов? Так началась совершенно необязательная, но увлекательная история с реверс-инжинирингом прошивки усилителя.
Небольшая историческая справка: почему вообще QUAD
QUAD интересен не только тем, что сегодня продаёт красивый компактный усилитель с оранжевым дисплеем. У компании довольно редкая для бытовой электроники родословная: это одна из тех марок, которые десятилетиями строили не столько «модельный ряд», сколько собственную инженерную школу.
Компания была основана Питером Уокером в Лондоне в 1936 году как S.P. Fidelity Sound Systems и в том же году получила название The Acoustical Manufacturing Co. Ltd. Первые годы бизнес был связан прежде всего с усилителями и системами публичного оповещения. В 1941 году производство переехало в Хантингдон, где британская инженерная и сервисная база QUAD находится и сегодня. 1
Аббревиатура QUAD расшифровывается как Quality Unit Amplifier Domestic. В послевоенные годы компания постепенно сместилась от PA-оборудования к домашнему Hi-Fi. QA12/P конца 1940-х, ламповый QUAD II начала 1950-х и особенно электростатическая акустика ESL 1957 года сформировали ту репутацию марки, которая потом десятилетиями позволяла QUAD делать довольно странные вещи и всё равно оставаться QUAD. 1 2
ESL, позднее ставшая известной как ESL-57, была одной из первых действительно массовых полноразмерных электростатических акустических систем. Для своего времени она была почти демонстрацией инженерного упрямства: вместо очередного улучшения динамической головки Уокер фактически пересобрал принцип излучения звука с нуля. QUAD до сих пор считает электростаты одной из центральных частей своего наследия. 3
Но для нашей истории важнее другая линия. В 1967 году появились QUAD 33 и QUAD 303. Это уже был транзисторный комплект: минималистичный 33 control unit и 303 power amplifier. Пара стала одной из самых узнаваемых конструкций QUAD, получила крупную промышленную награду в 1969 году, а дизайн 33 вошёл в коллекцию MoMA. Сама QUAD спустя десятилетия прямо объясняла возвращение 33/303 тем, что оригинальные аппараты продолжали активно жить на вторичном рынке и сохраняли устойчивый спрос. 1 4
В 1975 году Питер Уокер представил идею Current Dumping, а затем появился QUAD 405, одна из самых известных инженерных конструкций компании. В 1978 году QUAD получила Queen’s Award for Technological Achievement. 1 5
Если очень грубо, исторический код QUAD — не делать «эффектный Hi-Fi», а минимизировать собственный вклад электроники, оставить пользователю немного странный, но логичный интерфейс и сделать вещь, которой пользуются 30 лет. Последний пункт, разумеется, производители электроники сегодня читают с некоторым внутренним беспокойством.
QUAD 3: не ремейк одной модели, а современная сборка из ДНК старых QUAD
Тут важна аккуратность формулировок. QUAD 3 не является прямым переизданием какой-то одной исторической модели. Это не «новый QUAD 22» и не «33 с усилителем мощности внутри». What Hi-Fi прямо отмечает, что QUAD 3, в отличие от переизданных 33/303, является новой современной моделью. 7
Но происхождение дизайна абсолютно прозрачное. В 2024 году QUAD вернула 33 и 303 в обновлённом виде. Компания подчёркивала, что это не косметический рестомод, а новая реализация классической пары с современной схемотехникой и производством. 4
А в июне 2025 года появился QUAD 3. Официальная история бренда описывает его как интегральный усилитель, объединяющий классические визуальные мотивы с современной коммутацией и управлением. 1
Внешне QUAD 3 наследует сразу нескольким поколениям. Компактная архитектура и оранжевая индикация роднят его с новым 33, округлая геометрия и часть лицевой панели отсылают к старому QUAD 22, а ряд энкодеров с source, bass, tilt, balance продолжает фирменную идею управления без дисплея размером с iPad. 6 7
Внутри это современный усилитель Class AB с мощностью 65 Вт на канал в 8 Ом и 100 Вт в 4 Ом, тороидальным трансформатором 235 VA и ёмкостью фильтра питания 30 000 мкФ. Цифровая часть построена на ESS9038Q2M: USB Audio поддерживает PCM до 768 кГц и DSD512, а S/PDIF — до 192 кГц. Есть HDMI ARC, Bluetooth 5.1 с aptX/aptX HD, MM-фонокорректор, два линейных аналоговых входа, фирменный Tilt и USB-порт для обновления системной прошивки. 6
То есть идея устройства понятна: взять визуальный и эргономический язык классических QUAD, который люди действительно любят, и посадить его на современную элементную базу.
И, судя по рынку, идея была вполне успешной. What Hi-Fi пишет, что после популярности обновлённых 33/303 пользователи фактически просили интегральную версию, и через два года появился QUAD 3. Hi-Fi News вообще описывает происходящее как «renaissance» марки. 7 8
Получился очень симпатичный инженерный парадокс: аппарат визуально апеллирует к эпохе, когда главным интерфейсом была ручка, но внутри у него есть MCU, USB firmware update, CEC и полноценная цифровая архитектура.
А значит, если тебя бесит UX, теперь его можно не только ругать — его можно дизассемблировать.
Зачем мне это вообще понадобилось
В моей системе три основных сценария. Телевизор подключён к QUAD 3 по HDMI ARC, и здесь всё хорошо: HDMI CEC автоматически выбирает нужный вход. Основной музыкальный тракт — WiiM Ultra, подключённый к усилителю по USB. Для альтернативного аналогового тракта сигнал идёт с Line Out WiiM через Musical Fidelity X-10v3 на AUX1 усилителя.
WiiM умеет менять свои выходы между USB Out и Line Out, но проблема оставалась на стороне QUAD. Если WiiM переключился на USB, усилитель тоже нужно перевести на USB; если выбран Line Out — на AUX1. Прямой команды INPUT_USB у усилителя нет: доступны только SOURCE_NEXT и SOURCE_PREVIOUS.
Для автоматизации это неудобно. Команда Source+ означает не «выбрать USB», а «перейти к следующему входу относительно текущего». Приходится хранить состояние, которое легко сбивается: пользователь повернул ручку Source, телевизор включил ARC через CEC, кто-то воспользовался штатным пультом или усилитель перезагрузился.
Первым вариантом была схема с поиском известной точки через Bluetooth и последующим счётом Source +/-. Она, вероятно, работала бы. Но потом я подумал: если усилитель внутри прекрасно знает, что такое USB, AUX1 и ARC, зачем изображать вокруг него механическую коробку передач?
Получаем официальную прошивку
На сайте QUAD прошивки для QUAD 3 не оказалось, хотя на задней панели есть совершенно недвусмысленный разъём FIRMWARE UPDATE. Я написал в поддержку и через сервисный центр получил официальный бинарник QUAD3_v1.14j_26.7.30.bin размером 55 544 байта. На моём усилителе в тот момент отображались версии SYSTEM VER-102 и PC USB VER-219.
Никакого changelog к 1.14j не было — просто актуальный файл прошивки, присланный производителем. Что именно изменилось между 1.02 и 1.14j, осталось неизвестным. Зато появился бинарник, а он, в отличие от маркетингового отдела, разговаривает довольно честно.
Первый взгляд на бинарник
Первым делом нужно было понять, что это за файл: есть ли контейнер, шифрование или подпись, для какой архитектуры собран код и куда загружается образ. Результат оказался приятным: перед нами практически обычный raw application image для ARM Cortex-M3, с инструкциями Thumb-2 и порядком байтов Little Endian.
База приложения — 0x08010000, в начале находится нормальная ARM vector table. Карта памяти очень похожа на STM32F100. Статический анализ указывал на это семейство как на наиболее вероятное, скорее всего вариант класса xB с минимум 128 КиБ Flash. Отсюда получалась следующая предполагаемая карта:
0x08000000
┌──────────────────────────┐
│ bootloader / updater │
│ ~64 KiB │
│ │
├──────────────────────────┤ 0x08010000
│ application │
│ QUAD 3 │
│ │
│ original EOF │
│ 0x0801D8F8 │
│ │
│ ~10 KiB free │
└──────────────────────────┘ 0x08020000
Позже RC1 закончился по адресу 0x0801D937. Даже для минимального 128-КиБ варианта оставалось 9 928 байт запаса. Для патча, которому нужны десятки байт, это примерно как арендовать ангар, чтобы поставить туда табуретку.
Подпись, CRC и прочие страшные слова
Следующий вопрос был очевидным: примет ли загрузчик изменённую прошивку? В самом application image не обнаружилось RSA- или ECDSA-подписи, отдельного блока подписи либо очевидного hash trailer. Проверили также распространённые варианты CRC16, CRC32, Fletcher16, Fletcher32, аддитивной контрольной суммы, XOR и размещения хеша в начале или конце файла. Очевидного контрольного поля найти не удалось.
Это ещё ничего не говорило о загрузчике: проверка могла находиться там. Но уже было понятно, что само приложение не является зашифрованным контейнером с цепочкой доверия уровня автомобильного ECU. Это обычная прошивка Cortex-M, которую можно анализировать дальше.
Ищем выбор источника
Главный вопрос — как QUAD внутри выбирает вход. Начали со строк B-T, USB, OPT, CO-AX, ARC, AUX-1, AUX-2 и PHONO. Сам по себе их порядок ничего не доказывает, поэтому дальше искали ссылки на строки, RAM-таблицы и код вывода названия текущего источника. В итоге удалось восстановить source enum:
ID | Source |
|---|---|
0 | Bluetooth |
1 | USB |
2 | Optical |
3 | Coax |
4 | ARC |
5 | AUX1 |
6 | AUX2 |
7 | Phono |
Этот порядок подтверждён RAM-таблицей указателей и кодом вывода выбранного источника. Главная переменная requested_source находится по адресу 0x20000ED3. Запрос переключения выполняет процедура 0x08012F64, а применение нового источника — асинхронный worker 0x08012E64.
Нашёлся и удобный штатный хвост обработки по адресу 0x080134D4: он запускает запрос, обновляет интерфейс, организует сохранение состояния и оставляет само переключение worker. То есть внутри прошивки существует ровно то, чего нет снаружи: возможность вызвать условный set_source(source_id). Упрощённо это выглядит так:
requested_source = source_id;
request_source_change();
Дальше родной автомат делает всё остальное. Это существенно, потому что переключение входа в QUAD не сводится к изменению GPIO: оно включает mute, задержки, маршрутизацию сигнала, работу ARC, обновление дисплея и сохранение состояния. Worker использует переменные stage и timer, выполняя переход асинхронно.
Поэтому разбирать управление мультиплексорами, DAC и реле для этой задачи не понадобилось. Достаточно сообщить существующей прошивке, что пользователь попросил source=5, и дать штатному коду выполнить привычную последовательность. Аудиотракт при таком подходе вообще не нужно менять.
Идём от пульта
Следующим объектом стал IR dispatcher. В прошивке удалось найти три нужные точки:
Назначение | Адрес |
|---|---|
IR decoder |
|
IR command table |
|
IR dispatcher |
|
Пульт общий для усилителя QUAD 3 и транспорта 3CDT, с переключателем режима A / CD. Часть кнопок в режиме усилителя фактически не используется, хотя события для них уже существуют в прошивке. Для кастомного патча это почти идеальная ситуация: не нужно придумывать протокол, покупать другой пульт или менять IR decoder. Достаточно дать существующим событиям новый смысл.
QUAD использует NEC-подобный IR-протокол с адресом 32 EE в режиме усилителя. Например, одна из наших команд выглядит как 32 EE 33 CC, где 33 — команда, а CC — её инверсия. При этом внутри decoder представление местами отличается из-за порядка битов: 0x33 = 00110011 после bit reverse превращается в 0xCC = 11001100. Поэтому в дизассемблере можно увидеть 0xCC, хотя переданная NEC-команда равна 0x33. Эта мелочь сначала создаёт впечатление, что таблица состоит из случайных чисел.
Первый патч: SK1
Для первого эксперимента решили ограничиться тремя наиболее полезными входами: USB, AUX1 и ARC. В прошивке уже присутствовали три распознаваемых события, которые в интересующем нас пути не выполняли полезных действий. Для них добавили соответствие event -> source ID, после чего направили исполнение обратно в штатный код. Получилась такая цепочка:
IR frame
↓
decoder 0x0801C5A2
↓
event
↓
dispatcher 0x080132E8
↓
custom handler
↓
0x20000ED3 = source_id
↓
stock tail 0x080134D4
↓
request 0x08012F64
↓
worker 0x08012E64
↓
stock routing / mute / ARC / UI / persistence
Мне особенно нравится размер вмешательства. В существующем коде изменены всего четыре байта по смещениям 0x3346-0x3349: последовательность 20 88 C0 1F заменена на 0A F0 D7 BA. Это инструкция B.W, которая передаёт управление нашему обработчику.
Сам обработчик добавлен после исходного EOF и занимает 64 байта. Остальные 55 540 байт оригинальной прошивки совпадают побайтно, а итоговый размер RC1 составляет 55 608 байт. Рост — 64 байта, или 0.1152%. Мы не переписывали прошивку: добавили небольшой способ вызвать уже существующий механизм.
Стек и повторные команды
LAB-версия сначала использовала PUSH {r1}. Для RC1 решили сохранить 8-байтовое выравнивание стека и заменить сохранение и восстановление регистров на следующую пару:
PUSH {r1, r2}
...
POP {r1, r2}
Совместимость с ABI и вызовами через BL лучше не проверять методом «а вроде обычно работает». После изменения размер payload остался равен 64 байтам, SP восстанавливается, а выравнивание выдержано.
До прошивки хотелось проверить и ситуацию с двумя быстрыми нажатиями. Если новый запрос приходит до завершения предыдущего перехода, source worker записывает последний requested source и возвращает автомат в начало перехода: stage = 1, timer = 0. Например, если отправить USB и почти сразу AUX1 до первого такта worker, в результате применяется AUX1. Дополнительную очередь мы не добавляли — ещё один аргумент в пользу использования штатной логики.
Эмуляция
Прежде чем прошивать усилитель, код прогнали через Unicorn. Эмулировались реальные Thumb-инструкции декодера, диспетчера, изменённого пути исполнения, части штатных процедур и source worker. Аппаратные функции заменялись заглушками.
Проверяли состояние RAM, цели переходов, регистры и стек, вызовы штатных функций, routing image, упаковку и распаковку NVRAM, а также незавершённые переходы. Результат — PASS. Это не гарантирует работу на железе, но позволяет хотя бы не проверять на усилителе очевидно битый машинный код. Разница существенная.
Самая смешная проблема проекта
После всего этого наступил момент истины. Я подготовил флешку на 32 GB с FAT32, положил на неё прошивку и запустил обновление. QUAD показал USB UPDATE, немного подумал и сообщил FILE CAN'T FIND.
Начались поиски подходящего имени файла и структуры каталогов, но ничего не помогало. Причём усилитель не находил даже оригинальный заводской бинарник, так что наш патч был явно ни при чём. После ARM, Thumb-2, NVRAM, автомата состояний и binary patching самым сложным компонентом системы оказался USB-накопитель.
Я нашёл старую флешку на 8 GB, тоже с FAT32. С ней QUAD увидел файл и успешно прошился именно кастомным RC1. Человечество победило embedded bootloader с помощью археологического USB-накопителя.
Что стало понятно про загрузчик
До этого эксперимента оставались вопросы о проверке подписи, скрытой CRC и допустимости увеличения образа. Практический результат оказался важнее предположений: на данном экземпляре QUAD 3 штатный загрузчик принял изменённое приложение с дополнительными 64 байтами, выполнил программирование, после чего устройство успешно перезагрузилось.
Отдельно выяснилось, что строки USB UPDATE и FILE CAN'T FIND вообще отсутствуют в application image. Это согласуется с предположением, что USB updater живёт отдельно от приложения: загрузчик начинается в области 0x08000000, а application — с 0x08010000.
Первый запуск
После прошивки QUAD нормально загрузился. Проверили Power, Volume, Mute, Source, входы USB, AUX1 и ARC, а также HDMI CEC — всё осталось работоспособным. Затем начали нажимать цифровые кнопки штатного пульта и получили то, ради чего всё затевалось:
Кнопка | Вход в RC1 |
|---|---|
0 | USB |
1 | AUX1 |
2 | ARC |
Это прямой выбор входа, а не макрос из нескольких Source+. Нажатие 0 выбирает USB из любого текущего состояния, в том числе из PHONO; нажатие 1 переводит усилитель с Bluetooth на AUX1. Больше не нужно знать, какой вход был выбран до команды.
Зачем тогда ещё SK2
После этого останавливаться на трёх входах стало немного смешно: в QUAD восемь источников, а на пульте десять цифровых кнопок. Поэтому для следующей версии запланирована полная карта:
Кнопка | Планируемый вход в SK2 |
|---|---|
0 | USB |
1 | AUX1 |
2 | AUX2 |
3 | PHONO |
4 | COAX |
5 | OPTICAL |
6 | ARC |
7 | Bluetooth |
8 | Резерв |
9 | Резерв |
Логика простая: на кнопках 1–3 собраны аналоговые входы, на 4–6 — проводные цифровые, на 7 — Bluetooth. USB остаётся на 0, потому что в моей системе это основной музыкальный вход.
Прямой выбор всех источников помещается на кнопках 0–7. Две оставшиеся могут пригодиться, например, для переключения USB/AUX1 или команды Power On + USB, но последняя потребует отдельного изучения power path. Пока лучше не превращать первую рабочую кастомную прошивку в операционную систему.
А исходная задача с WiiM?
С прямыми IR-командами дальнейшая автоматизация становится намного проще. WiiM меняет выход между USB Out и Line Out, Home Assistant видит его состояние и отправляет команду выбора USB или AUX1 на усилитель. Планируемая связь выглядит так:
WiiM output = USB → IR discrete USB → QUAD input = USB
WiiM output = Line Out → IR discrete AUX1 → QUAD input = AUX1
Не требуется считать Source+, хранить текущую позицию, искать опорный вход или синхронизировать автомат с действиями пользователя и HDMI CEC. Получается ровно то, что и должно было быть изначально: команда выбирает состояние, а не относительное движение.
Границы проекта и публичный репозиторий
Важно понимать границы вмешательства. Мы не меняли USB Audio, DAC, DSP, HDMI, CEC, Bluetooth stack, защиту, управление громкостью и питанием или формат NVRAM. Это минимальный бинарный патч штатной прошивки. Чем меньше трогаешь исправно работающий embedded-код, тем ниже вероятность обнаружить, что настройка входа AUX неожиданно сломала thermal protection.
После успешной проверки на железе я создал публичный репозиторий VincentVega73/quad3-custom-firmware. В нём не будет оригинальной прошивки QUAD и готовых модифицированных .bin: это чужой проприетарный код. Вместо этого планируется воспроизводимый patcher, с которым пользователь самостоятельно получает официальный образ и локально строит изменённую версию.
В репозитории планируются firmware_patch.py, исходник обработчика, карта IR-команд, source enum и карта Flash, тесты и проверки Unicorn, binary diff и SHA256, инструкции по установке и результаты проверки на устройстве. Отдельно будет предупреждение о рисках: успешный эксперимент автора не гарантирует работоспособность патча на любом экземпляре QUAD 3.
Любая модификация прошивки выполняется на риск владельца устройства. Можно получить неработающий аппарат, потерять гарантию или столкнуться с другой аппаратной ревизией, загрузчиком, картой Flash и отсутствием штатного восстановления. То, что мой экземпляр успешно принял RC1, означает только результат на моём экземпляре, а не сертификацию для всех QUAD 3.
Несколько выводов из этой истории
Embedded reverse engineering сегодня стал заметно доступнее. Ghidra, Python, Capstone, Unicorn, LLM и некоторое понимание ARM позволяют превратить задачу, которая раньше выглядела как несколько недель работы firmware engineer, в аккуратное техническое расследование. Это не один промпт, но и не археологическая экспедиция на полгода.
Для полезного результата не обязательно понимать устройство целиком. В моём случае хватило небольшого среза: IR, диспетчер, запрос источника, worker и маршрутизация. Изучить этот путь и не трогать остальное оказалось эффективнее, чем пытаться полностью декомпилировать чужую прошивку в красивый C-проект.
Лучший патч часто использует максимум штатного кода. Мы нашли существующий механизм переключения и добавили к нему новый вход управления. Это позволило сохранить проверенную последовательность действий усилителя и ограничить вмешательство несколькими десятками байт.
Наконец, серьёзная инженерная работа легко упирается в бытовую деталь. После анализа Thumb-2, vector table, NVRAM и IR state machine выяснилось, что QUAD просто не любит конкретную 32-гигабайтную флешку, а с восьмигигабайтной всё работает. Это, пожалуй, самая реалистичная часть истории.
Что дальше
Сейчас делается SK2 с прямым выбором всех восьми входов по приведённой выше карте. После этого штатный пульт сможет выбирать нужный источник одной кнопкой — довольно революционная для 2026 года возможность.
Следующий этап уже выходит за рамки реверса усилителя: нужно связать WiiM Smart Preset, Home Assistant и IR-команды QUAD. Конечный сценарий прост: нажал одну кнопку — включилась музыка. На удивление длинный путь для функции, которую производитель мог добавить примерно теми же шестью десятками байт.
Источники по истории QUAD и QUAD 3
Историческая часть статьи опирается на следующие источники:
QUAD, Our Story. История компании, основание в 1936 году, переезд в Huntingdon, происхождение названия QUAD, QUAD II, ESL, 33/303, 405 и современное возвращение линейки.
John Atkinson, Peter J. Walker 1916–2003, Stereophile. Биографическая справка о Питере Уокере, ранней истории Acoustical Manufacturing Company, QA12/Pre, QUAD II и ESL.
QUAD, Electrostatic Speakers / ESL history. Официальная история ESL-57 и последующих поколений электростатической акустики.
QUAD, 33 & 303 Series. Официальное описание возвращения 33/303, причины переиздания и связь новых моделей с оригиналами.
What Hi-Fi?, 7 of the best British hi-fi innovations and technologies. Историческая справка о QUAD, ESL и Current Dumping.
QUAD, QUAD 3. Официальная страница модели: дизайн, связь с QUAD 22 и новым 33, ESS9038Q2M, Class AB, 235VA transformer, USB 768kHz/DSD512, HDMI ARC, Bluetooth, phono и прочие характеристики.
What Hi-Fi?, Quad 3 review: vintage looks, modern features, smooth sound, 25 March 2026. Важная оговорка: QUAD 3 не является прямым revival конкретной старой модели, а представляет собой новый современный integrated amplifier, визуально вдохновлённый 33/303 и 22.
Hi-Fi News, Quad 3 amplifier, September 2025. Обзор QUAD 3 в контексте возвращения 33/303 и современной «ренессансной» линейки QUAD.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.