Образ Android


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

4. Как используются разделы

Для операций с разделами Android на загрузочной карте (анализ таблицы разделов, чтение, запись и др.) совсем не обязательно иметь под рукой ПК с Linux. Для этого можно воспользоваться самим устройством (платой OpiZero2).

Есть два способа:


Способ 1-й.
Записанная загрузочная SD-карта вставлена в слот устройства, на которое подано питание и система загружена. Для выполнения консольных команд удобно использовать терминал (например, MobaXTerm) на ПК, к USB-порту которого через переходник подключен UART устройства. В этом случае можно безболезненно смотреть таблицу разделов и читать содержимое разделов в файлы (на эту же карту или на подключенную USB-флешку). Записывать таким способом (на живом теле) разделы тоже можно, но не все и очень осторожно. Поскольку при неудачной или ошибочной записи устройство с такой карточкой работать перестанет, и придется её записывать заново. Поэтому такой способ желательно использовать только для бекапа (чтения и сохранения в файлы) разделов.

Для обращения к разделам в первом способе используются пути:

  • /dev/block/mmcblk0 - это вся карта полностью

  • /dev/block/mmcblk0p1 - /dev/block/mmcblk0p17
    где (p1...p17 - порядковые номера разделов) - для обращения к конкретному разделу.

    При этом в командах dd в обоих случаях можно обращаться к части раздела, добавляя в комаду параметры count (количество копируемых блоков) и skip (пропущенных блоков) при чтениии раздела или seek (пропущенных блоков) при записи раздела. Без явного указания параметра bs размер копируемого блока равен 512 байт. Именно в таких блоках (секторах) сделана адресация в таблице разделов GPT, поэтому удобно оставить размер блока по умолчанию, чтобы не заниматься арифметикой пересчета смещений и размеров.


    Способ 2-й.
    Предназначенная для чтения-записи разделов SD-карта вставлена в кардридер, который подключается к USB-порту устройства. При этом система с Андроидом загружается со другой рабочей загрузочной карты, вставленной в слот SD-карты. В этом варианте на "экспериментальной" карте можно делать любые операции с разделами, в т.ч. их очистку и запись, не затрагивая целостности основной рабочей загрузочной карты.

    Для обращения к разделам во втором способе используются пути:

  • /dev/block/sda - это вся карта полностью

  • /dev/block/sda1 - /dev/block/sda17
    где (1...17 - порядковые номера разделов) - для обращения к конкретному разделу.

    Указания об использование других параметров команды dd, приведенные в описании первого способа, остаются справедливыми и для второго способа (карта подключена к USB).

    Заметим, что в случае использования не Андроида, а Линукса пути разделов записываются несколько иначе: /dev/sda и /dev/sda1 - /dev/sda17 , т.е. без block/

    Номера разделов в стоковой версии Android (для использования в командах dd):

  • 1 - bootloader
  • 2 - env
  • 3 - boot
  • 4 - super
  • 5 - misc
  • 6 - recovery
  • 7 - cache
  • 8 - vbmeta
  • 9 - vbmeta_system
  • 10 - vbmeta_vendor
  • 11 - metadata
  • 12 - private
  • 13 - frp
  • 14 - empty
  • 15 - media_data
  • 16 - Reserve0
  • 17 - UDISK

    Для анализа содержимого разделов, созданных на карте, используем описанный выше первый способ, чтобы сохранить разделы в виде файлов с помощью консольной команды DD :


    Вариант 1. Команды копирования карты по смещениям разделов

  • dd if=/dev/block/mmcblk0 of=bootloader-backup.img bs=512 skip=73728 count=65536

  • dd if=/dev/block/mmcblk0 of=env-backup.img bs=512 skip=139264 count=32768

  • dd if=/dev/block/mmcblk0 of=boot-backup.img bs=512 skip=172032 count=65536

  • dd if=/dev/block/mmcblk0 of=super-backup.img bs=512 skip=237568 count=3145728

  • dd if=/dev/block/mmcblk0 of=misc-backup.img bs=512 skip=3383296 count=32768

  • dd if=/dev/block/mmcblk0 of=recovery-backup.img bs=512 skip=3416064 count=65536

  • dd if=/dev/block/mmcblk0 of=cache-backup.img bs=512 skip=3481600 count=1310720

  • dd if=/dev/block/mmcblk0 of=vbmeta-backup.img bs=512 skip=4792320 count=32768

  • dd if=/dev/block/mmcblk0 of=vbmeta_system-backup.img bs=512 skip=4825088 count=32768

  • dd if=/dev/block/mmcblk0 of=vbmeta_vendor-backup.img bs=512 skip=4857856 count=32768

  • dd if=/dev/block/mmcblk0 of=metadata-backup.img bs=512 skip=4890624 count=32768

  • dd if=/dev/block/mmcblk0 of=private-backup.img bs=512 skip=4923392 count=32768

  • dd if=/dev/block/mmcblk0 of=frp-backup.img bs=512 skip=4956160 count=1024

  • dd if=/dev/block/mmcblk0 of=empty-backup.img bs=512 skip=4957184 count=31744

  • dd if=/dev/block/mmcblk0 of=media_data-backup.img bs=512 skip=4988928 count=32768

  • dd if=/dev/block/mmcblk0 of=Reserve0-backup.img bs=512 skip=5021696 count=32768

  • dd if=/dev/block/mmcblk0 of=UDISK-backup.img bs=512 skip=5054464 count=16


    Примечания.

    1. В этом варианте нужно точно указывать (в блоках !) смещения skip и количества count, поэтому для ручной записи команд такой способ неудобен, но для программной генерации списка команд (или даже скрипта) из таблицы GPT вполне приемлем (именно так он здесь и появился).

    2. Выражения bs=512 и bs=1b должны быть эквивалентны, здесь b означает блок (block), т.е. 512 байт.
    Цитата из man dd


    N and BYTES may be followed by the following multiplicative suffixes:
    c=1, w=2, b=512, kB=1000, K=1024, MB=1000*1000, M=1024*1024, xM=M, GB=1000*1000*1000, G=1024*1024*1024, and so on for T, P, E, Z, Y. Binary prefixes can be used, too: KiB=K,MiB=M, and so on.


    Ещё раз подчеркнем, что смещения skip и количества count указываются в блоках (в приведенных выше примерах - в блоках размером 512 байт).

    Хотя, в принципе существует возможность при необходимости всё указывать в байтах (но при этом придётся оперировать с существенно большими числами, что повышает вероятность ошибки).
    Для этого нужно добавить в dd-команду параметры:

  • iflag=count_bytes,skip_bytes
  • oflag=seek_bytes

    Цитата из man dd :


    count_bytes - treat 'count=N' as a byte count (iflag only)
    skip_bytes - treat 'skip=N' as a byte count (iflag only)
    seek_bytes - treat 'seek=N' as a byte count (oflag only)



    Вариант 2. Команды копирования по номерам разделов

  • dd if=/dev/block/mmcblk0p1 of=backup1.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p2 of=backup2.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p3 of=backup3.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p4 of=backup4.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p5 of=backup5.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p6 of=backup6.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p7 of=backup7.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p8 of=backup8.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p9 of=backup9.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p10 of=backup10.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p11 of=backup11.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p12 of=backup12.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p13 of=backup13.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p14 of=backup14.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p15 of=backup15.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p16 of=backup16.img bs=512 conv=fsync

  • dd if=/dev/block/mmcblk0p17 of=backup17.img bs=512 count=16 conv=fsync

    Примечания.

  • 1. На карте должно быть свободное место не менее 2 Гбайт

  • 2. Файлы копируются в предварительно назначенный текущий каталог на карте

  • 3. Значение bs=512 задано равным размеру блока (сектора) для удобства, во 2-м варианте может быть другим.

  • 4. Раздел UDISK (mmcblk0p17), занимающий всё оставшееся свободным место, может оказаться очень большим, поэтому желательно ограничить размер файла принудительно параметром count

  • 5. Разделы Super (mmcblk0p4)и Сache(mmcblk0p7) имеют большие размеры, поэтому для уменьшения файла желательно копировать их с gzip-сжатием, например:

  • dd if=/dev/block/mmcblk0p4 | gzip > backup4.img.gz conv=fsync
  • dd if=/dev/block/mmcblk0p7 | gzip > backup7.img.gz conv=fsync

  • 6. При использовании команд dd в консоли процесс копирования не отображается, поэтому при копировании достаточно болших разделов нужно терпеливо ждать его завершения и появления соответствующих сообщений. Желательно также добавить в dd-команды параметр status=progress.

    В случае копирования бекапов разделов на USB-флешку команды выглядят так:

  • dd if=/dev/block/mmcblk0p4 | gzip > /mnt/media_rw/0000-006F/backup4.img.gz conv=fsync
  • dd if=/dev/block/mmcblk0p7 | gzip > /mnt/media_rw/0000-006F/backup7.img.gz conv=fsync

    Здесь /mnt/media_rw/0000-006F/ - это имя конкретной USB-флешки, подключенной к USB-порту устройства и автоматически монтированной в Андроиде.


    Для восстановления бекапов разделов или их модификации при использовании 2-го способа (карточка подключена к USB-порту) список dd-команд:

  • dd if=bootloader.img of=/dev/block/sda1 conv=fsync

  • dd if=env.img of=/dev/block/sda2 conv=fsync

  • dd if=boot.img of=/dev/block/sda3 conv=fsync

  • dd if=super.img of=/dev/block/sda4 conv=fsync

  • dd if=misc.img of=/dev/block/sda5 conv=fsync

  • dd if=recovery.img of=/dev/block/sda6 conv=fsync

  • dd if=cache.img of=/dev/block/sda7 conv=fsync

  • dd if=vbmeta.img of=/dev/block/sda8 conv=fsync

  • dd if=vbmeta_system.img of=/dev/block/sda9 conv=fsync

  • dd if=vbmeta_vendor.img of=/dev/block/sda10 conv=fsync

  • dd if=metadata.img of=/dev/block/sda11 conv=fsync

  • dd if=private.img of=/dev/block/sda12 conv=fsync

  • dd if=frp.img of=/dev/block/sda13 conv=fsync

  • dd if=empty.img of=/dev/block/sda14 conv=fsync

  • dd if=media_data.img of=/dev/block/sda15 conv=fsync

  • dd if=Reserve0.img of=/dev/block/sda16 conv=fsync

    Примечания.

    1. Файлы, имена которых указаны в левой части команды (if=), должны находиться в текущей папке. Это могут быть файлы предварительно сделанных бекапов разделов или файлы содержимого разделов из образа прошивки (исходные или модифицированные). Имена файлов здесь указаны для удобства по имени соответствующего раздела.

    2. Карта, на которую производится запись разделов, подключена через кардридер к USB-порту устройства.


    Для справки:

  • Продолжительность копирования раздела super на USB-флешку составляет 230 сек (примерно 6 минут)
  • На скорости 6.6 Mb/s скопировано 1610612736 байт (1.5 Gb)
  • Размер полученного файла gz-архива 399933252 байт (400 Mb), т.е. сжатие в 4 раза

    Как ни странно, но разницы в скорости копирования на карту или USB-флешку никакой нет (от слова совсем), для сравнения два результата dd:

  • на USB: 1610612736 bytes (1.5 G) copied, 229.706336 s, 6.6 M/s
  • на карту: 1610612736 bytes (1.5 G) copied, 229.045113 s, 6.7 M/s

    Также на скорость не влияет (даже слегка замедляет) копирование не дефолтными блоками по 512 байт, а большими блоками (например, по 8 Mb):

    if=/dev/block/mmcblk0p4 bs=8M | gzip > backup4.img.gz
    1610612736 bytes (1.5 G) copied, 248.327665 s, 6.1 M/s


    Обратное копирование бекапа gzip-файла super.img.gz в одноименный раздел на карту c USB-флешки выполняется командой :

    gunzip -c /mnt/media_rw/0000-006F/backup4.img.gz | dd of=/dev/block/mmcblk0p4 conv=fsync,noerror bs=8M


    Назначение, использование и содержимое разделов

    Проверка содержимого файлов сохраненых копий разделов показывает:

  • 1. В разделы, помеченные звездочкой, записаны файлы из образа прошивки
  • 2. Разделы misc, private, empty, media_data - пустые (содержат нули)
  • 3. Разделы cache, metadata, frp, Reserve0 содержат какую-то информацию (ненулевые байты)

  • 1. bootloader - *

  • 2. env - *

  • 3. boot - *

  • 4. super - *

  • 5. misc - пусто

  • 6. recovery - *

  • 7. cache - ненулевых байтов: 24876 из 671088640

  • 8. vbmeta - *

  • 9. vbmeta_system - *

  • 10. vbmeta_vendor - *

  • 11. metadata - ненулевых байтов: 12656

  • 12. private - пусто

  • 13. frp - 36 символов в начале файла, дальше все нули

  • 14. empty - пусто

  • 15. media_data - пусто

  • 16. Reserve0 - ненулевых байтов: 203

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

    1. Раздел frp

    FRP - это Factory Reset Protection, поэтому одноименный раздел frp имеет прямое отношение к процедуре защиты Google-аккаунта после сброса на тех устройствах, где установлены сервисы гугля, и создан гугль-аккаунт. После сброса к заводским (Factory Reset) на таких устройствах загрузка Андроида блокируется до ввода сохраненных данных гугль-аккаунта. В разделе FRP хранятся ключи FRP Lock, поэтому его очистка приводит к разблокировке защиты Google-аккаунта.

    Для платы OpiZero2 установка и использование сервисов гугля нецелесообразно и затруднительно из-за недостаточного (1 Гб) объема оперативной памяти. Поэтому здесь раздел FRP не используется, и файл, полученный при его бекап-копировании, практически пуст (за исключением первых 36 байт).

    2. Раздел Reserve0

    Теоретически, в начало этого раздела предполагается запись резервной копия таблицы разделов GPT. Это видно из совпадения адреса начального блока раздела Reserve0 со значением Alternate LBA ( N блока резервного GPT-раздела) в заголовке таблицы GPT. Однако, практически этого не происходит, т.к. об отсутствии резервного GPT сообщают работающие с GPT утилиты.

    Запись резервной копии GPT в раздел Reserve0 возможна, например, командами: (не проверено !)

  • dd if=/dev/block/mmcblk0 of=resgpt.img bs=512 count=16
  • dd if=resgpt.img of=/dev/block/mmcblk0p16 bs=512

    Анализ содержимого бекап-копии этого раздела показывает, что на нём монтируется какой-то пустой диск FAT16.

    3. Раздел metadata

    Из названия раздела видно, что в него предполагается запись каких-то метаданных, но происходит ли это при программировании карты (и какие конкретно данные записываются) - неизвестно.

    4. Раздел cache

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