Образ Android


  Образ     Файлы     GPT     Разделы       RAW    

5. Как сделать RAW-образ прошивки Android

Для того, чтобы определить, какая именно информация должна содержаться в таком образе-копии посмотрим на стандартный способ программирования карты с помощью утилиты PhoenixCard, которая распаковывает inagewty-образ, как-то обрабатывает содержащиеся в нём файлы и записывает на карту.

Процесс записи (burning) образа прошивки на карту с помощью PhoenixCard отображается в окне этой программы, которое в результате успешной записи выглядит следующим образом:

Эти строки (предположительно) означают следующее:

Строки [xxx] Burn Sucess сообщают об успешной записи какого-либо раздела (xxx) или файла

  • Start Burning - это начало процесса записи

  • [Pheonix card_00] - запись Boot0 (т.е. файла boot0_sdcard.fex)

  • [Pheonix card_10] - запись Boot1 (т.е. файла boot_package.fex)

  • [MBR] - запись таблицы разделов GPT (т.е. модифицированного файла sunxi_gpt.fex)

  • [bootloader] - запись файла boot-resource.fex в раздел bootloader

  • [env] - запись файла env.fex в раздел env

  • [boot] - запись файла boote.fex в раздел boot

  • [super] - запись файла super.fex в раздел super

  • [misc] - запись чего-то в раздел misc (или его очистка)

  • [recovery] - запись файла recovery.fex в раздел recovery

  • [cache] - запись файла чего-то в раздел cache (или его очистка)

  • [vbmeta] - запись файла vbmeta.fex в раздел vbmeta

  • [DATA file] - запись чего-то в раздел media_data(?) или в UDISK (?)

  • Magic complete - возможно, это какое-то действие с файлом split_xxxx.fex, являющегося копией массива magic.bin, записанного в раздел bootloader

  • Burn end - конец процесса записи

    Поскольку в образе прошивки для разделов misc и cache файлов не предусмотрено, то, вероятно, здесь происходит их очистка (запись нулей).

    Ещё раз подчеркнем, что сказанное выше - это лишь предположения, сделанные на основе анализа, но не подтвержденные документально или ссылками на источник этого утверждения.

    Таким образом, теоретически, для создания RAW-образа прошивки требуется открыть бинарный файл и записать в него содержимое файлов с соответствующими смещениями, при этом повторив действия (возможно, е все из них), зафиксированные в логе утилиты PhoenixCard.

    Такой файл будет представлять собой копию загрузочного носителя (SD-карты), поэтому он может быть записан в неё любой утилитой, умеющей работать с RAW-образами, например, DiskImager.exe под Windows (или аналогичными под Windows или Linux).

    Для практической проверки сделанных предположений проведем ряд экспериментов. В качестве исходной информации доля них будут использованы файлы, извлеченные из IMAGEWTY-образа прошивки Android 10 версии Ver 1.1 (файл OrangePi Zer02 Android10 V1_1.img. с сайта производителя).


    Эксперимент 1-й

    Создадим простейший RAW-образ прошивки для проверки начальных этапов загрузки. Для этого откроем новый файл образа fopen('имя_файла', 'wb+') и запишем в него с соответствующими смещениями содержимое файлов gpt.img, boot0_sdcard.fex, boot_package.fex, boot-resource.fex, env.fex, twrp.img При этом для файла рекавери twrp.img установим смещение, соответствующее boot.fex

    Полученный таким способом файл записываем на SD-карту под Windows утилитой DiskImager.exe (это занимает всего несколько секунд). Теперь вставим эту карту в устройство и подадим питание, контролируя процесс загрузки на терминале через UART. Плата успешно стартует, запускается U-Boot, который мы тормозим клавишей пробел, на экране появляется начальная заставка (bootlogo.bmp). И по введенной в интерфейсе U-Boot команде boot благополучно запускается TWRP, интерфейс которого появляется на экране монитора.

    Из этого следует (проверено и подтверждено на практике), что для нормального запуска устройства в режим командного интерфейса вторичного загрузчика U-Boot достаточно иметь RAW-образ, в котором записано с нужными смещениями содержимое пяти файлов:

  • gpt.img
  • boot0_sdcard.fex
  • boot_package.fex
  • boot-resource.fex
  • env.fex,
  • recovery.img (или twrp.img)

    Файл такого мини-образа имеет размер примерно 120 Мбайт.

    На SD-карту этот образ можно записать под Windows за несколько секунд утилитами Win32diskimager.exe или usbimager.exe (ссылки в конце страницы).

    При включении платы сразу загружается TWRP или, если подключен UART, то можно тормознуть и остаться в U-Boot. Образ крохотный (в распакованном виде 120 Mb, zip-архив 20 Mb. Такую загрузочную карту можно использовать, чтобы поиграть с U-Boot и с TWRP. Или для быстрой первичной (или альтернативной) проверки работоспособности платы. Образ пишется на карточку несколько секунд, воткнул, включил питание - и на мониторе картинка интерфейса.

    Скачать этот файл можно по ссылке: rawtwrp.zip .

    Эксперимент 2-й.

    Повторяем все предыдущие действия, но при этом используем не файл twrp.img, а файл boot.fex, который занимает в образе свое законное место, т.е. одноименный раздел boot.

    Карта с таким образом стартует, происходит нормальная загрузка U-Boot, однако по команде boot вместо загрузки ядра системы происходит рестарт загрузчика. И если его не останавливать с клавиатуры, то процесс зацикливается, т.е. наблюдается хорошо известный "бутлуп" (boot loop). Это говорит о том, что одного ядра недостаточно для загрузки в какое-то статическое состояние. Обязательно нужен ещё и super, т.е. три содержащихся в нём системных раздела.


    Эксперимент 3-й.

    Создаем файл, в котором записано с нужными смещениями содержимое следующих файлов:

  • 1) gpt.img
  • 2) boot0_sdcard.fex
  • 3) boot_package.fex
  • 4) boot-resource.fex
  • 5) env.fex
  • 6) boot.fex
  • 7) recovery.fex
  • 8) super.img

    Файл super.img - это распакованный sparse-файл super.fex.

    В результате получаем файл v11z.raw размером 1740800 Kb (1 782 579 200 байт).

    После записи этого raw-файла утилитой Win32diskimager.exe получаем SD-карту с полной системой. Включение устройства с установленной картой приводит к нормальной загрузке Андроида, которая завершается появлением рабочего стола с ярлыками приложений. Т.е. процесс загрузки и дальнейшее функционирование системы не отличается от загрузки карты с системой, на которую записан IMAGEWTY-образ, записанный фениксом.


    Для получения полного лога загрузки (с loglevel=8) нужно выполнить действия, указанные в инструкции по ссылке: Как сделать полный лог загрузки Android на OrangePi Zero2

    Полный лог загрузки raw-образа выглядит так: Лог загрузки raw-образа


    Таким образом, можно сделать вывод, что для получения рабочего образа достаточно записать на карту перечисленные выше восемь файлов. По крайней мере, для варианта загрузки и работы системы с SD-карты. Будет ли подобный образ нормально работать на ТВ-боксах с nand-памятью - вопрос открытый, требующий специальной проверки.

    Сейчас проверка проведена только на одном устройстве OrangePi Zero2 в его фиксированной конфигурации и на картах SanDisk емкостью 8, 16 и 32 Гбайт. Поэтому нет никакой гарантии работоспособности этого образа (учитывая его экспериментальный характер) в других ситуациях или с другими картами.

    Необходимо отметить, что в данном raw-образе три раздела VBMETA оставлены пустыми, соответствующие файлы в них не записаны (это сделано для уменьшения размера файла). Однако их отсутствие как-будто бы не мешает нормальной загрузке и функционированию системы, по крайней мере в существующем режиме работы. Учитывая, что здесь не используются возможности OTA-обновления или какие-либо специальные режимы работы. Но в случае возникновения проблем эти файлы можно записать с помощью DD-команд.


    Как влияет размер карты

    Наш инструмент для создания файлов RAW-образов для записи на SD-карту позволяет выбрать размер самой карты: 8, 16 или 32 Gb. От выбора размера зависит конкретное содержимое таблицы разделов GPT в таком файле. В остальном все три варианта образа идентичны.

    Для проверки влияния этого параметра проведем эксперименты. В которых будут фиксироваться результаты загрузки карты с записанным образом, а также показаны (частично) логи консольной команды sgdisk.

    Проверка 1.
    Файл, собранный под размер 8 Gb, записан на две карты разной емкости: 8Gb и 32GB.

  • 1. Результат загрузки карты 8 Gb с образом 8 Gb - загрузка прошла успешно, размер /storage/emulated/0 = 4.9 Gb

    console:/ # sgdisk --print /dev/block/mmcblk0
    Disk /dev/block/mmcblk0: 15523840 sectors, 7.4 GiB
    Logical sector size: 512 bytes
    Disk identifier (GUID): AB6F3888-569A-4926-9668-80941DCB40BC
    Partition table holds up to 17 entries
    First usable sector is 73728, last usable sector is 15523838
    Partitions will be aligned on 1024-sector boundaries
    Total free space is 33 sectors (16.5 KiB)
    ....
    17 5054464 15523805 5.0 GiB 0700 UDISK

    Примечание. Оказалось, что настройки лаунчера и набор пользовательских приложений соответствует предыдущему образу, записанному на эту карту. Это произошло из-за совпадения таблицы разделов с GPT записанной ранее на эту карту системы. Поэтому содержимое разделов, которые отсутствуют в новом образе, осталось от предыдущей системы и было благополучно использовано новой системой. После сброса к заводским через меню настроек система перегружается принимает вид, соответствующий записанному образу, т.е. без оставшихся хвостов от предыдущей прошивки.

    Это означает, что перед записью карты (если она не новая) требуется не просто отформатировать её, но также очистить первые 3 Gb, например, с помощью команды (карта вставлена в USB через кардридер)


    dd if=/dev/zero of=/dev/block/sda bs=10M count=300
    а ещё лучше сделать полное форматирование утилитой форматирования с перезаписью (overwrite), хотя это достаточно долгая процедура для карты 32 Gb. Если этого не делать, то нет никакой гарантии нормальной и полной загрузки системы.

  • 2. Результат загрузки карты 32 Gb с образом 8 Gb (образ записан на абсолютно новую карту) - загрузка прошла успешно, размер storage (внутреннего хранилища) = 5.4 Gb


    console:/ # sgdisk --print /dev/block/mmcblk0
    Disk /dev/block/mmcblk0: 62357504 sectors, 29.7 GiB
    Logical sector size: 512 bytes
    Disk identifier (GUID): AB6F3888-569A-4926-9668-80941DCB40BC
    Partition table holds up to 17 entries
    First usable sector is 73728, last usable sector is 15523838
    Partitions will be aligned on 1024-sector boundaries
    Total free space is 33 sectors (16.5 KiB)
    .....
    17 5054464 15523805 5.0 GiB 0700 UDISK

    Выводы. Образ 8 Gb можно записать на любую карту, и такая карта нормально загрузится, однако для карт емкостью больше 8 Gb размер хранилища (storage) и диска Udisk останутся равными примерно 5 Gb.


    Проверка 2.

    Файл, собранный под размер 32 Gb, записан на две карты разной емкости: 8Gb и 32GB. На самом деле, пересобирать файл образа и заново записывать карту не требуется. Достаточно просто заменить на каждой из записанных карте её начало (8192 байта = 16 блоков), т.е. просто заменить GPT.


    dd if=gpt32.img of=/dev/block/sda bs=512 count=16

  • 1. Результат загрузки карты 32Gb - загрузка прошла успешно


    sgdisk --print /dev/block/mmcblk0
    Disk /dev/block/mmcblk0: 62357504 sectors, 29.7 GiB
    Logical sector size: 512 bytes
    Disk identifier (GUID): AB6F3888-569A-4926-9668-80941DCB40BC
    Partition table holds up to 17 entries
    First usable sector is 73728, last usable sector is 62333950
    Partitions will be aligned on 1024-sector boundaries
    Total free space is 33 sectors (16.5 KiB)
    .....
    17 5054464 62333917 27.3 GiB 0700 UDISK

    Однако размер storage (внутреннего хранилища) = 5.4 Gb - это странно, видимо это значение осталось где-то на карте от предыдущей прошивки 8 Gb.

    Попробуем сделать сброс к заводским. Во время сброса (после нескольких подтверждений) на мониторе появляется сообщение "Erasing" и анимированное кольцо с переливами цвета.

    После перезагрузки размер storage (внутреннего хранилища) стал равным 28.9 Gb, что и требовалось доказать. Причина этого - отсутствие полной очистки карты.

  • 2. Результат загрузки карты 8 Gb с образом 32 Gb - не загружается нормально даже U-Boot !
    Лог загрузки (появление ошибок):


    sunxi flash init ok
    Loading Environment from SUNXI_FLASH... GPT: last_usable_lba incorrect: 3B723FE > ece000
    part_get_info_efi: *** ERROR: Invalid GPT ***
    GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
    part_get_info_efi: *** ERROR: Invalid Backup GPT ***
    *** Warning - no device, using default environment

    Failed (-19)
    Item0 (Map) magic is bad
    the secure storage item0 copy0 is bad
    Item0 (Map) magic is bad
    Item0 (Map) magic is bad
    usb burn from boot
    delay time 0
    weak: otg_phy_config
    usb prepare ok
    overtime
    do_burn_from_boot usb : no usb exist
    boot_gui_init: start
    GPT: last_usable_lba incorrect: 3B723FE > ece000
    part_get_info_efi: *** ERROR: Invalid GPT ***
    GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
    part_get_info_efi: *** ERROR: Invalid Backup GPT ***
    partno erro : can't find partition Reserve0
    Get Reserve0 partition number fail!
    boot_gui_init: finish
    bmp_name=bootlogo.bmp
    GPT: last_usable_lba incorrect: 3B723FE > ece000
    part_get_info_efi: *** ERROR: Invalid GPT ***
    GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
    part_get_info_efi: *** ERROR: Invalid Backup GPT ***
    partno erro : can't find partition bootloader
    GPT: last_usable_lba incorrect: 3B723FE > ece000
    part_get_info_efi: *** ERROR: Invalid GPT ***
    GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
    part_get_info_efi: *** ERROR: Invalid Backup GPT ***
    partno erro : can't find partition boot-resource
    Get bootloader and boot-resource partition number fail!
    update dts
    cann't get the boot_base from the env
    GPT: last_usable_lba incorrect: 3B723FE > ece000
    part_get_info_efi: *** ERROR: Invalid GPT ***
    GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
    part_get_info_efi: *** ERROR: Invalid Backup GPT ***
    update part info
    GPT: last_usable_lba incorrect: 3B723FE > ece000
    part_get_info_efi: *** ERROR: Invalid GPT ***
    GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
    part_get_info_efi: *** ERROR: Invalid Backup GPT ***
    update bootcmd
    No ethernet found.
    Hit any key to stop autoboot: 0
    =>

    Из лога следует, что U-Boot обнаруживает несоответствие фактического размера карты и размера в GPT:


    GPT: last_usable_lba incorrect: 3B723FE > ece000

    Более наглядно представление в десятичном виде:
    62 333 950 больше, чем 15 523 840 (и это чистая правда).

    Отсюда следует, что U-Boot знает реальный размер загрузочного носителя и проверяет его на соответствие с таблицей разделов.

    Поэтому записывать образ с таблицей большего размера на карту меньшего размера - это совсем неудачная идея.

    Кстати, в подобной ситуации U-Boot пытается продвинуться дальше, он формирует дефолтный ENV, и по пробелу остается в командном режиме. Но этот ENV не спасает из-за отсутствия distro_bootcmd.



    => printenv
    baudrate=115200
    bootcmd=run distro_bootcmd
    bootdelay=2
    bootreason=unknow
    fdtcontroladdr=7be855c0
    snum=9c00141511d0481230e

    Environment size: 135/131068 bytes
    =>

    => boot ## Error: "distro_bootcmd" not defined
    =>


    Как загрузить инструменты и готовые образы

    ZIP-архив с файлом RAW-образа v11zero2-32.zip имеет размер 424 837 223 байт и содержит файл v11raw32gb.img, предназначенный для записи только на SD-карту емкостью 32 Gb.

    Размер файла: 1740800 Kb.

    ВНИМАНИЕ ! Перед записью рекомендуется очистить карту в режиме overwrite утилитой SDcardFormatter (если карта не новая и уже использовалась для записи образа).

    Скачать этот zip-архив можно по ссылкам (на разных облаках):

  • Mega

  • MailRu

  • Yandex

  • Google


    Ссылки для загрузки инструментов записи образа на карту:

  • usbimager.zip
  • UsbImager Manual
  • USBImager (все версии)
  • diskimager.zip
  • SDcardFormatter