Продолжаю играться со Яндекс Станцией первого поколения. Бэкап всего MMC (mmcblk2 целиком, а не отдельных разделов) есть, FEL включается и работает, так что устройство всегда можно восстановить до первоначального состояния.
При анализе разделов, видно целых четыре копии ядра линукс (с рамдисками, возможно не все), два тома с Андроид и один с Линукс:
major minor #blocks name
179 0 7634944 mmcblk2
179 1 1355266 mmcblk2p1 UDISK /data
179 2 32768 mmcblk2p2 bootloader /bootloader (FAT16)
179 3 1 mmcblk2p3 похоже на MBR
mmcblk2p4 - нет как устройства, там лежит u-boot, есть в образе mmcblk2
179 5 16384 mmcblk2p5 env
179 6 16384 mmcblk2p6 boot
179 7 2097152 mmcblk2p7 system /system
179 8 32768 mmcblk2p8 verity_block
179 9 16384 mmcblk2p9 misc
179 10 32768 mmcblk2p10 recovery
179 11 1572864 mmcblk2p11 cache /cache
179 12 16384 mmcblk2p12 metadata
179 13 16384 mmcblk2p13 private
179 14 512 mmcblk2p14 frp
179 15 2097152 mmcblk2p15 rescue
179 16 65535 mmcblk2p16 tinaos
179 17 32768 mmcblk2p17 rback
179 18 16384 mmcblk2p18 secret /secret
179 19 81920 mmcblk2p19 alog /logger
179 64 4096 mmcblk2boot1 нули
179 32 4096 mmcblk2boot0 и тут нули
(надеюсь, когда-нибудь в дзене появится хотя бы поддержка таблиц)
Раздел mmcblk2p7 - это системный раздел, в который грузится станция при нормальной работе. Ядро Linux находится на mmcblk2p6, verity информация (возможно, что не используется при загрузке - пишут что она с ядра 4.4, а у нас 3.9) на mmcblk2p8.
Раздел mmcblk2p15 - раздел, который записывается в mmcblk2p7 при сбросе до заводских настроек. Его ядро Андроид + ramdisk лежат на mmcblk2p10.
А вот интересное находится в mmcblk2p16 - там Tina Linux (основан на OpenWRT). Это сильно урезанный, но все же Линукс. Его ядро и рамдиск - mmcblk2p15. Нам нужен именно тот репозиторий, который я указал - другие сильно новее.
Осталось понять, как же в него загрузиться.
Если глянуть в раздел env, там увидим интересную строчку:
setargs_mmc=if test "${need_hw_test}" != "1"; then
echo 'Android is running';
setenv bootargs earlyprintk=...;
else
echo 'Linux is running';
setenv bootargs rootwait earlyprintk=... rdinit=/initstub init=/sbin/init;
То есть, при установке переменной need_hw_test в 1 будет загрузка в этот Tina Linux. Осталось установить его в 1.
Внимательные люди при загрузке обратили внимание на строчку:
Но тут 0 секунд, так что any key не срабатывает.
Данный период хранится в переменной bootdelay в env - так что стоит его увеличить. Для этого нам нужна утилита u_boot_env_gen, которая входит в pack-bintools-2016.12.19 (есть в репозитории Tina Linux, о котором я писал выше) и оригинальный env.fex.
Создаем такой файл (чтобы его получить - в оригинальном env.fex символы с кодом 0 меняем на перевод строки):
Я тут заодно поднял loglevel.
Преобразуем его в FEX файл командой
./u_boot_env_gen env-my.cfg env.fex
Загружаем устройство через FEL в мини-Linux, предварительно записав FEL файл куда-нибудь в его initramfs.img, и прошиваем:
dd if=/bin/env.fex of=/dev/mmcblk2p5
После перезагрузки u-boot реагирует на нажатие клавиши.
Note: обновление прошивки Яндекс затрёт раздел env, так что эту переменную придется ставить повторно.
Далее делаем в u-boot:
setenv need_hw_test 1
saveenv
reset
Либо можно было сразу установить need_hw_test=1 в env-my.cfg выше.
И мы загружаемся в Tina Linux.
На экране рисуется QR код (файл /usr/share/hwtest/QCMode.png) с серийником процессора, а по UART можно нажать Enter и увидеть предложение логина.
Пароль рута нам, естественно, неизвестен.
Для сброса - опять же перезагружаемся через FEL в мини-линукс прошлой статьи, монтируем раздел /dev/mmcblk2p16, открываем файл /etc/passwd и в строке:
root:x:0:0:root:/root:/bin/ash
убираем букву x
root::0:0:root:/root:/bin/ash
Так мы получаем рута с пустым паролем. Остальные строки оставляем как есть.
Либо можно подключить Станцию к ПК и там в adb shell увидеть:
Если USB было подключено до загрузки операционной системы - необходимо провод вынуть и повторно вставить.
Обратите внимание на то, что самые нужные разделы уже примонтированы. Модули ядра, кстати, загружаются из раздела /system (mmcblk2p7), так что если этот раздел потёрли, то какие-то устройства могут перестать работать. Но это заодно и еще одна потенциальная точка для дальнейшей эксплуатации.
P.S.
Если захотите собрать ядро Tina Linux или дополнительные модули, то наша версия там r18-v0.9, а устройство зовётся tulip-d1 (см файл /etc/openwrt_release). У Яндекса версия поновее, но я ее особо и не искал.
repo init -u https://github.com/tinalinux/manifest -b r18-v0.9 -m r18/v0.9.xml
И так далее по инструкции из их папки docs. Там же есть u-boot.
R18 - это не номер ревизии, это марка нашего процессора.
А вот что дальше делать с информацией из этой статьи - решать вам.
Обновление:
Tinalinux нормально загружается только после хард резета, до установки свежей прошивки, так как обращается к модулям, которых в свежих андроидах нет.
Загрузить ее после обновления можно таким образом (из uboot):
setenv bootargs "earlyprintk=sunxi-uart,0x01c28000 initcall_debug=0 console=ttyS0,115200 earlycon=sunxi-uart,0x01c28000 loglevel=8 root=/dev/mmcblk0p16 rdinit=/initstub init=/sbin/init "
setenv bootargs ${bootargs} "partitions=bootloader@mmcblk0p2:env@mmcblk0p5:boot@mmcblk0p6:system@mmcblk0p15:verity_block@mmcblk0p8:misc@mmcblk0p9:recovery@mmcblk0p10:cache@mmcblk0p11:metadata@mmcblk0p12:private@mmcblk0p13:"
setenv bootargs ${bootargs}"frp@mmcblk0p14:rescue@mmcblk0p7:tinaos@mmcblk0p16:rback@mmcblk0p17:secret@mmcblk0p18:alog@mmcblk0p19:lback@mmcblk0p20:rboot@mmcblk0p21:media_data@mmcblk0p22:UDISK@mmcblk0p1 cma=232M androidboot.selinux=permissive"
setenv bootargs ${bootargs} "androidboot.serialno=1234567890 androidboot.hardware=sun50iw1p1 boot_type=2 androidboot.lcd_x=1920 androidboot.lcd_y=1080 serialno=1234567890 --"
sunxi_flash read 45000000 rback;boota 45000000 boot
обратите внимание, что тут я поменял номера разделов system и rescue (07 и 15), в таком случае ядру раздела rback будут "подходить" правильные модули ядра из раздела rescue.