В прошлой статье я написал, как вносить изменения в сдампленный образ NAND, пересчитать ECC (в тех местах где требуется) и записать назад.
Включение ADB на устройствах Яндекса (кроме ТВ и устройств с HDMI) происходит скриптом /system/vendor/quasar/activate_adb.sh, который с помощью вспомогательного скрипта adb_options.inc проверяет наличие одного из файлов /data/quasar_activate_adb_* для включения ADB, и файла /data/quasar_activate_network_adb для активации доступа к ADB по сети (иначе будет только по USB). Данный скрипт запускается при каждой перезагрузке, так что нам достаточно создать в папке /data необходимые файлы:
Данный способ работает на всех устройствах Яндекс, где в прошивке есть файл /system/vendor/quasar/maind.
Чтобы создать необходимые нам файлы в разделе /data, нам потребуются:
1. Очищенный дамп,
2. Адреса начала и конца разделов в файле дампа,
3. Компьютер с Linux. Подойдет также и Windows с WSL.
Как сделать очищенный дамп я описал в прошлой статье.
Адреса разделов мы видим при загрузке устройства с установленным silent=0:
Важный момент: смещения, которые вы видите в логе устройства уже включают в себя сдвиг, вызванный наличием bad блоков NAND. То есть на вашем Мини 3 про адреса наверняка будут отличаться от моего скриншота.
Ранее я уже кратко описал, как редактировать UBIFS разделы монтированием с помощью драйвера nandsim. Здесь опишу чуть подробнее.
На Мини 3 про интересно редактировать два раздела: system (там находится корневая система устройства) и data (папка /data на устройстве). Так что я при использовании nandsim создам виртуальную NAND с тремя разделами: в первый попадёт всё, что идет перед system (монтировать его мы не будем), во второй раздел попадет system, в третий - data.
Для использования nandsim сперва требуется вычислить размеры разделов.
Из скриншота выше видим, что system начинается по смещению 0x00000c400000 и идет до 0x000014440000 (то есть его длина 0x000014440000-0x00000c400000=0x8040000 байт). Data начинается с 0x000014440000 и идет до конца устройства.
Драйвер nandsim размеры разделов принимает в erase блоках, так что надо пересчитать байты в блоки. Для TC58NVG2S0HTA00 (Мини 3 Про и Станция 2) размер erase блока 256 Кб (0x40000), для TC58NVG1S3HTA00 (Лайты) размер 128Кб (0x20000). Так как мы работаем с очищенным дампом, то размер erase блока взят без учета OOB и spare.
Пересчитываем:
Все разделы до system: 0x00000c400000/0x40000=784 блока.
Раздел system: 0x8040000/0x40000=513 блоков.
Раздел data идет до конца NAND, так что его размер вычислять не надо.
Далее в Linux загружаем нужные модули:
sudo modprobe -a zstd lzo ubifs
sudo modprobe nandsim first_id_byte=0x98 second_id_byte=0xdc third_id_byte=0x90 fourth_id_byte=0x26 parts=784,513
Параметры first_id_byte, second_id_byte и тд - это ID байты микросхемы. Их можно посмотреть в программаторе:
Цифры в параметре parts= посчитаны выше.
Обязательно проверяем, что у нас появились MTD разделы 0,1,2:
mtd0 - место под стартовые разделы, мы его не используем
mtd1 - будет наш system
mtd2 - и наша data
Теперь своим любимым hex редактором вырезаем нужные нам разделы из очищенного дампа NAND. Напомню, что у меня адреса:
0x00000c400000-0x000014440000 : "system"
0x000014440000-0x000020000000 : "data"
Я их записал в файлы system.bin и data.bin.
И копируем вырезанные файлы в соответствующий раздел виртуального mtd:
sudo dd if=./system.bin of=/dev/mtd1 bs=1024
sudo dd if=./data.bin of=/dev/mtd2 bs=1024
Далее пробуем подключить UBIFS:
sudo ubiattach /dev/ubi_ctrl -m 1
и получаем ошибку:
ubiattach: error!: cannot attach mtd1
error 22 (Invalid argument)
Это нормально, лечится указанием ключа --vid-hdr-offset со значением, которое видим в dmesg:
Выполняем:
sudo ubiattach /dev/ubi_ctrl -m 1 --vid-hdr-offset 4096
sudo ubiattach /dev/ubi_ctrl -m 2 --vid-hdr-offset 4096
Параметры -m 1 и -m 2 означают номера MTD устройств, которые мы подключаем (mtd1 - system, mtd2 - data). Должны появиться устройства /dev/ubi0* и /dev/ubi1*
Создаем папки, куда будем монтировать system и data:
sudo mkdir -p /mnt/ubi/system /mnt/ubi/data
И монтируем их:
sudo mount -t ubifs /dev/ubi0_0 /mnt/ubi/system/
sudo mount -t ubifs /dev/ubi1_0 /mnt/ubi/data/
После ubiattach первое подключенное устройство получило номер ubi0_0, а второе ubi1_0 - их мы и примонтировали.
Теперь создаем файлы-метки для включения ADB:
sudo touch /mnt/ubi/data/quasar_activate_adb_glagol
sudo touch /mnt/ubi/data/quasar_activate_network_adb
И обязательно проверяем через "ls" что они создались:
По желанию можно включить интерактивную консоль Linux на UART. Для этого редактируем файл /system/etc/inittab (у нас он будет по пути /mnt/ubi/system/etc/inittab) и заменяем вызов getty_rabbit_hole на простой getty:
После всех модификаций, размонтируем тома:
sudo umount /mnt/ubi/system
sudo umount /mnt/ubi/data
Делаем ubidetach:
sudo ubidetach /dev/ubi_ctrl -m 1
sudo ubidetach /dev/ubi_ctrl -m 2
И сохраняем модифицированные данные назад в те же файлы:
sudo dd if=/dev/mtd1 of=./system.bin bs=1024
sudo dd if=/dev/mtd2 of=./data.bin bs=1024
Далее кладем файлы system.bin и data.bin на их старое место в очищенном дампе прошивки out.bin:
После чего повторяем действия из раздела 5 прошлой статьи:
file_combine -4 TC58NVG2S0HTA00@TSOP48-fixed.bin out.bin TC58NVG2S0HTA00@TSOP48-edited.bin
ecc_fix -4 fixecc TC58NVG2S0HTA00@TSOP48-edited.bin TC58NVG2S0HTA00@TSOP48-towrite.bin
И записываем образ TC58NVG2S0HTA00@TSOP48-towrite.bin в NAND.
После этого на устройстве видим приглашение залогиниться на UART (Buildroot login). Пароль у root пустой:
Увы, но возможность так логиниться слетает после каждого обновления системы. Что нужно сделать, чтобы доступ через UART к консоли Linux сохранить навсегда - расскажу, когда истечет 90 дней, так как для этого используется одна из нескольких уязвимостей Мини 3 про, сданных в Яндекс по Баг Баунти. Хотя, с большой вероятностью, Яндекс к тому времени эту дырку закроет.
Также нам по сети доступен ADB:
И этот доступ сохраняется даже при обновлении системы. Только сброс к заводским настройкам его уберет. Либо если Яндекс, по аналогии с тем, как они сделали в Яндекс Станции Макс, в system_config добавит параметр принудительного отключения ADB.