U-Boot на Infinix X676B: как я вскрыл MediaTek и он заговорил / How I opened an Infinix and got U-Boot talking

В телефоне стоит Android, а загрузчика, по сути, нет. Ну, есть — но это такая штука, с которой ничего не сделать. Transsion (это Infinix, это TECNO, это всё такое) кладёт в разделы lk_a и lk_b свой Little Kernel. Он умеет ровно две вещи: показать логотип и передать управление ядру. Ни fastboot, ни консоли, ни меню. Всё, что ты можешь — воткнуть UART в тестпойнты рядом со сканером отпечатков и читать, как летит лог.

Мне это надоело. Телефон я покупал не для того, чтобы любоваться анимацией загрузки. Через Android много не узнаешь: adb про загрузчик не расскажет, а переменные ядра про LK молчат как партизаны.

Значит, менять загрузчик. Стоковый LK → U-Boot.

Спойлер: получилось больше, чем я думал. Сейчас телефон грузит U-Boot, который рисует меню прямо на AMOLED, отдаёт консоль по USB-кабелю, умеет fastboot и работает как UMS-накопитель. Не работает SD-карта, об этом в отдельной статье и с подробностями, потому что там самая интересная часть.

Железо, чтобы понимать масштаб

  • Модель: Infinix Note 12 Pro, X676B
  • SoC: MediaTek Helio G99 (MT6789)
  • Экран: AMOLED 1080×2400, панель ILI7835F
  • Память: 8 ГБ RAM, UFS 2.2
  • Android: 12, XOS, разметка A/B

У MediaTek нет документации на MT6789. Вообще. Ни схем, ни описания регистров, ни списка совместимых строк. Отдельная боль — потом.

С чего началось

Заготовка была простая: взять форк U-Boot под MediaTek, добавить устройство, собрать. Форк нашёлся сразу — ellyq/u-boot-mtk-g99, U-Boot 2025.10-rc5, сто тысяч коммитов истории. Осталось придумать две вещи: .dts и defconfig.

Первый device tree я написал за вечер. Он даже запустился: U-Boot грузился, UART показывал меню. Первая победа и первая иллюзия, что дальше будет легко.

Дальше началось интересное.

Три источника правды, и ни один не врёт

Их три, и они между собой не совпадают:

1. Реальный DT телефона. Android грузит ядро с device tree, и этот DT можно достать на живом устройстве:

adb shell su -c 'strings /sys/firmware/fdt'

Это правда. Но не стопроцентная: производитель вправе написать в DT что угодно, и иногда пишет.

2. Формовый mt6789.dtsi от ellyq. Написан для MT6789, но местами для MT8183, местами для MT8781.

3. Драйверы U-Boot в форке. А вот тут начинается настоящая жесть.

Смотрите, что получается:

Что В телефоне В dtsi форка На что биндится драйвер
SD-карта mt6789-mmc mt6789-mmc mt8183-mmc
USB mt6789-usb20 mt8518-musb mt8518-musb
UFS mt8183-ufshci mt6789-ufshci оба
Кнопки mt6779-keypad — ничего

Прочитать это можно так: телефон от Transsion, а форк от постороннего человека, который тоже кое-что дописывал по сходным SoC. Реальное железо отличается от dtsi, и это нормально.

Но третья колонка — это то, из-за чего пришлось потеть. drivers/mmc/mtk-sd.c вообще не содержит строки mt6789-mmc. Вообще. Есть mt7620, mt7621, mt7622, mt7623, mt7981, mt7986, mt7987, mt8512, mt8516 и mt8183. С реальной строкой контроллер SD не поднимется — драйвер просто не забиндится и всё.

Выбора нет. Оставляем mt8183-mmc и дописываем mt8183_compat под MT6789. И да, имя mt8183_compat в коде врёт — но менять его в форке нельзя, это сломает чужие платы.

С USB ровно та же история. Реальный DT говорит mt6789-usb20, а musb-new содержит один-единственный драйвер mt85xx.c, и он биндится на одну строку — mediatek,mt8518-musb. Драйвера под mt6789-usb20 в форке просто нет, это другое семейство. Ядро MUSB общее, обвязка PHY разная.

Весь этот расклад я расписал построчно в docs/compatibility.md — там каждое расхождение с объяснением, почему выбран именно такой вариант.

Что пришлось написать с нуля

Трёх драйверов в форке не было вообще. Каждый писал сам.

Дисплей. 453 строки, drivers/video/mediatek/mtk_disp_g99.c. Отдельная история, ей будет посвящена следующая статья.

Кнопки. drivers/button/button-mtk-kp.c, 204 строки. В U-Boot есть button-adc, button-gpio и button-qcom-pmic, и ни один не подходит к матричной клавиатуре MTK. Взял Linux-драйвер mt6779-keypad.c, повторил раскладку регистров. Заработало с v88, в меню кнопки появились с v89.

Часы. А вот это отдельная история, на целую статью.

# drivers/clk/mediatek/Makefile в форке ellyq
//obj-$(CONFIG_TARGET_MT6789) += clk-mt6789.o

Файл лежит. Три драйвера объявлены. В DTS есть узлы. Файл не собирается. Строка «закомментирована» двойным слэшем — в Makefile комментарий это #, а не // — и привязана к CONFIG_TARGET_MT6789, которого не существует. Плюс в самом файле имя функции mt6789-infracfg_ao_probe с дефисом, а дефис в идентификаторе C не компилируется. Плюс таблицы от другого чипа: 13 PLL, включая ARMPLL, CCIPLL и MPLL, которых на MT6789 в природе нет.

Ни дисплей, ни SD, ни USB без часов не включаются. Так что это было первое настоящее препятствие.

Что работает

Подсистема Состояние
Дисплей текст U-Boot на AMOLED 1080×2400
USB fastboot телефон перечисляется на ПК
Консоль по USB CDC ACM, UART-кабель больше не нужен
UMS память телефона видна как диск
Кнопки Volume Up/Down листают меню
Часы три драйвера, всё тактируется

Меню загрузки теперь появляется на экране телефона без единого провода. Это тот самый момент, когда телефон перестаёт быть чёрным ящиком и становится нормальной железкой.

Что не работает

SD-карта. Контроллер поднимается, mmc info молчит, CMD8 даёт INT=0x400, RSP=0. Сорок попыток с разными подходами. В пятой статье расскажу подробно, потому что там самое интересное: значения регистров уже сведены к живому Android один в один, а ответа всё равно нет.

Загрузка Android. Ядро стартует и паникует Attempted to kill init. Передаётся не тот DTB. До этой работы я не дошёл.


Где всё это лежит

github.com/mnnoee/u-boot-mtk-g99 — исходники, ветка mt6789-stable, 84 коммита поверх форка. Внутри docs/ на двух языках: как устроено железо, почему именно такие решения и что уже проверено.

Готовый образ для прошивки — релиз v219, 2.6 МБ.

Обязательное условие: перед прошивкой сохраните стоковый LK из lk_a и lk_b. Без него отката не будет — сам U-Boot живёт в этих разделах. Это не страшилка, это буквально так.

Остальное по полочкам:
образы и состояние проекта ·
заметки и живые дампы ·
скрипты и разборы

Дальше будет про дисплей: 453 строки, Synchronous Abort и смещение 0xd00, которое едва не стоило мне недели.