В руках у меня новые часы от Xiaomi, Smart Band 10 Pro, у них есть приличный минус в системе recovery, который устранен в других часах линейки Сяоми, я расскажу об устройстве данной модели, структуре прошивки, пакета OTA и покажу какое решение решение я реализовал, чтобы улучшить механизм восстановления часов. Читать далее
Итак, на руках у меня довольно свежий продукт от компании Xiaomi - Smart Band 10 Pro.
В отличие от Band 9 Pro - апгрейд в основном затронул систему, но и как же без ложки дегтя:
глобальная версия опять со сломанными JerryScript приложениями - зачем делать приложения - а чтобы юзеры не стонали - просто вырежем движок - лол, молодцы, что уж..

SoC BES2700iMP
Что же мы имеем, практически тот же BEST1503 - это внутренний идентификатор SoC, внешне это BES2700iMP, какая то его ревизия - не вскрывал еще данную модель,
только внутренний flash 16Mb, против 8 у 9Pro, и порядка 16Mb PSRAM, внешний SPI флеш на 512Mb (256Mb для обычной глобалки)
В качестве операционной системы, тут опять используется RTOS NuttX OS, очень приятная embedded операционка, здесь неплохой shell, поддержка встроенных и загружаемых приложений.
Ну и классически Xiaomi встраивает 2 движка JerryScript для приложений и LUA для циферблатов, с практически полным сток API Lua 5.4
Именно в этой модели - здесь довольно продвинутый shell, например, позволяет читать в переменную вывод работы команды, что мне не хватало в Redmi Watch 5 с которыми я работал до этого.

system/data nand partitions
внешний SPI Nand flash разбит на следующие сектора, resource - romfs образ системного раздела, nand_data - yaffs RW данные, циферблаты, приложения, данные фитнеса и т.п.

SoC flash partitions
структура внутреннего флеш выглядит вот так, bl2 - secondary bootloader, ap - непосредственно главное приложение, mode/nv - настройки устройства, ну и в данном случае, это данные драйвера ap - не хватает раздела bl - primary bootloader, но он и не нужен.
Запускается устройство в таком порядке:
1. bl - primary bootloader - делает базовую инициализацию, смотрит на флаги загрузки - прописывает ключи setprop параметры загрузки, передает управление bl2
2. bl2 - secondary bootloader - смотрит причину сброса, выбирает режим загрузки - передает управление в app/recovery/factory
3. в обычном режиме запускает app - основное приложение, либо recovery приложение, либо factory mode.
каждый сегмент прошивки - это отдельная NuttX сборка, в каждой сборке в приложение зашит etc romfs, содержащий скрипты инициализации /etc/init.d/rcS и /etc/init.d/rc.sysinit,
первым выполняется rc.sysinit, затем rcS.
Как работает сток механизм рекавери:
любой сбой в приложении перезагружает устройство, которое попадает в bl2 загрузчик, посмотрим как работает его скрипт rcS - именно он отвечает за логику загрузки устройства.
set +e
set -x
echo "you are running bl2"
set resetcause `resetcause`
echo $resetcause
if [ "$resetcause" == "cpu_soft_reset(restore)" -o "$resetcause" == "cpu_soft_reset(factory)" ]
then
echo "recovery reset system" # обработка reboot с флагом restore/factory
sh /etc/recovery_reset.sh # запуск очистки раздела /data
fi
if [ "$resetcause" == "cpu_soft_reset(bootloader)" ]
then
rb -f /dev --skip_prefix vela_ --skip_suffix .bin
reboot
fi
if [ -e /data/ota.zip ] # если нашли /data/ota.zip - запускаем установку OTA
then
echo "mount ota.zip to /ota"
mount -t zipfs -o /data/ota.zip /ota
set errcode $?
if [ $errcode -ne 0 ]
then
echo "mount ota.zip failed!!!"
setprop persist.ota_fail 1
else
set ota_in_progress `getprop persist.ota.inprocess`
echo $ota_in_progress
if [ "$ota_in_progress" == "0" ]
then
setprop persist.bl2.ota.trytimes 0
else # механизм защиты от сбоев при установке OTA обновления
set trytimes `getprop persist.bl2.ota.trytimes`
set trytimes `expr $trytimes + 1`
echo $trytimes
if [ $trytimes -gt 5 ]
then
setprop persist.bl2.ota.trytimes 0
setprop persist.ota.precheck.finished 0
setprop persist.ota.inprocess 0
echo "Tried many times"
rm -r /data/ota_tmp
rm /data/ota.zip
reboot
else
setprop persist.bl2.ota.trytimes $trytimes
fi
fi
if [ "$resetcause" == "cpu_soft_reset(recovery)" -o "$ota_in_progress" == "1" ]
then
avb_verify /ota/vela_ota.bin /etc/key.avb # проверка цифровой подписи установщика
if [ $? -eq 0 ]
then
echo "Recovery Mode (OTA).."
cp -f /ota/vela_ota.bin /data/vela_ota.bin
boot /data/vela_ota.bin
echo "Boot ota failed!"
else
echo "Verify ota failed!"
setprop persist.ota.precheck.finished 0
setprop persist.ota_fail 1
rm /data/ota.zip
reboot
fi
fi
fi
fi
miwear_recovery_boot
set boot_reset `getprop boot_reset_flag`
echo $boot_reset
if [ "$boot_reset" == "1" ]
then
echo "jump boot reset mode"
mount -t romfs /dev/resource /resource
boot /resource/prebuild/vela_recovery.bin # загрузка recovery ELF приложения
echo "Boot recovery failed!"
fi
set factory_finished `getprop ro.factory.finished`
echo $factory_finished
if [ "$factory_finished" != "1" ]
then
echo "Boot factory"
mount -t romfs /dev/resource /resource
boot /resource/prebuild/vela_factory.bin # загрузка factory ELF приложения
echo "Boot factory failed!"
fi
echo "save checkpt"
umount -f /data
echo "System Mode (AP).."
boot
echo "Boot ap failed!"
у режима загрузки - resetcause - как видите есть несколько состояний:
normal
bootloader
restore
factory
Это все параметры команды reboot <param>.
Режимы restore/factory запускают скрипт /etc/recovery_reset.sh, который просто форматирует раздел c данными - пользовательские кривые циферблаты или приложения.
set +e
echo "umount /data"
umount -f /data
echo "force format /data"
mount -t yaffs -o forceformat /dev/nand_data /dataЭто все хорошо, только это нисколько не спасает от сбойного приложения.
В случае когда падает основное приложение - ap, rcS скрипт попадает в строки 68-75 и запускает в RAM ELF приложение boot /resource/prebuild/vela_recovery.bin
задача этого приложения вывести ошибку на экран и дать пользователю одну единственную кнопку - сбросить данные - выполнить команду - reboot restore
В результате этого действия, скрипт rcS попадает в строки 6-9 и происходит очистка внешней флешки, раздела nand_data - идет очистка данных, дальше идет загрузка сбойного ap - и все повторяется по кругу - получаем циклический ребут.
Улучшаем механизм recoveryСамое интересное, что данный механизм реализован не только во флагманских Watch S3/S4/S5 но и в Xiaomi Smart Band 10, ну и в Mi Band 11 (там прошивка 1в1 как у нашего пациента)
Как же он работает?
А очень просто - системный раздел содержит backup OTA пакет, который не содержит ресурсов, а содержит лишь необходимый минимум для функционирования часов. Слава богу, китайцы научились делать независимые от ресурсов сборки и корректно обрабатывают, как отсутствие текстовых ресурсов i18n, так и графических.

Mi Band 10 - recovery
благодаря выстроенной системе код рекавери очень простой и краткий.

Стандартный OTA пакет MB10 Pro
вот полный OTA пакет, vela_resource.bin это системый romfs, который монтируется в /resource при старте системы, в случае bl2 он не нужен и не монтируется.

Recovery ota.zip
fac_to_user.zip - это recovery OTA пакет с минимальным содержимым для обновления.
Нам остается только упаковать fac_to_user.zip в romfs - vela_resource.bin
и переписать скрипт загрузчика vela_bl2.bin.
Итоговый код загрузчика
set +e
set -x
echo "you are running bl2"
set resetcause `resetcause`
echo $resetcause
if [ "$resetcause" == "cpu_soft_reset(restore)" ] # здесь идет копирование recovery
then # OTA в стандартный путь обновления
echo "recovery restore system" # система дальше автоматом
mount -t romfs /dev/resource /resource # начинает установку
cp /resource/prebuild/fac_to_user.zip /data/ota.zip
sh /etc/recovery_reset.sh
fi
if [ "$resetcause" == "cpu_soft_reset(factory)" ]
then
echo "recovery reset system"
sh /etc/recovery_reset.sh
fi
if [ "$resetcause" == "cpu_soft_reset(bootloader)" ]
then
rb -f /dev --skip_prefix vela_ --skip_suffix .bin
reboot
fi
if [ -e /data/ota.zip ]
then
echo "mount ota.zip to /ota"
mount -t zipfs -o /data/ota.zip /ota
set errcode $?
...Самое интересное код Secondary bootloader разработчики включили в пакет OTA, т.е. даже стараться не нужно его достать, вот вам пример как не нужно делать прошивки господа.
Обход цифровой подписи и запись OTA настолько банальны, что даже не буду рассказывать, чтобы не поломать чуткое китайское самолюбие.
Всем добра и интересных гаджетов.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Реверс-инжиниринг Xiaomi Smart Band 10 | 0 | 15.41 | 24-05-2026 |
| 2 | Представлены Jaye Band — миниатюрные умные часы только для самых важных уведомлений | 0 | 5 | 18-06-2026 |
| 3 | Рендеры смарт-часов Samsung Galaxy Watch 9 и Galaxy Watch Ultra 2 утекли в Сеть | 0 | 5 | 24-06-2026 |
| 4 | Xiaomi Haylou Smart Watch 2 Xiaomi Haylou Smart Watch 2 ... | 5 | 7 | 09-07-2026 |
| 5 | В России стартуют продажи Xiaomi Mi Band 4 с бесконтактной оплатой по NFC | 0 | 0 | 18-06-2020 |
| 6 | Новый видеорегистратор 70mai A810 Lite от дочернего бренда Xiaomi. В ... | 5 | 6 | 29-06-2026 |
| 7 | Как PVS-Studio улучшает качество embedded-проектов | 0 | 15.82 | 05-08-2026 |
| 8 | Добавили потоков, стало медленнее: разбираемся с ложным разделением кеш‑линии | 0 | 9.26 | 10-08-2026 |
| 9 | Сонар из Музыкальной Колонки | 0 | 7.48 | 30-07-2026 |