Как распаковать и отредактировать boot.img для портирования ROM?

Недавно я загрузил это ПЗУ для своего Allview P5 (Allview P5 является эквивалентом Gionee GN700W/FLY IQ441/QMobile Noir A8). Он называется Primonex ROM и предназначен для версии телефона Gionee.

  • Во-первых, я попытался установить его как есть, но он застрял на экране загрузки.
  • После некоторых исследований я обнаружил, что это может быть проблема с boot.imgфайлом, и я не знаю, как его извлечь или отредактировать...

Может ли кто-нибудь сказать мне, как это сделать?

Если вы используете ядро ​​​​Linux, вы можете использовать abootimg

Ответы (2)

Выбор инструментов

Представленный здесь метод основан на исходном коде CyanogenMod для Android.

В то время как AOSP от Google предоставляет инструмент только для создания файла boot.img, CyanogenMod также добавляет unpackbootimgинструмент, позволяющий его распаковать . Этот инструмент никоим образом не предназначен специально для CyanogenMod, поэтому, скорее всего, он будет работать и для других ПЗУ.

Однако существует относительно большое количество альтернатив для распаковки boot.imgфайла, и все они работают более или менее одинаково.

По сути, такой инструмент распаковки извлечет содержимое boot.imgфайла и отобразит набор параметров, которые вам нужно будет передать mkbootimgинструменту Google для создания файла, конфигурация которого (в основном параметры ядра и адреса памяти) будет соответствовать исходной.

Вот несколько примеров, я не проверял их лично, поэтому не могу их рекомендовать и привожу их только для справки:

  • Некоторые из них имеют открытый исходный код или основаны на скриптах:

    • Android Kitchen , по-видимому, должен был стать чем-то вроде швейцарского армейского ножа для разработчиков Android. Первоначальный автор официально прекратил поддержку проекта, несколько других пользователей разветвили его, например, javilonas или cmotc .
    • szym нацелен на простоту, добавляя в свой набор инструментов оболочки скриптов, чтобы упростить весь процесс распаковки и переупаковки.
    • osm0sis предлагает форк инструментов CyanogenMod, «разветвленный и обновленный» в соответствии с собственным описанием проекта. Этот проект, кажется, действительно все еще поддерживается, что не очень распространено в этой области, однако фактическое преимущество над оригинальными инструментами CyanogenMod остается для меня неясным.
  • Некоторые из них являются бесплатными проприетарными двоичными файлами с закрытым исходным кодом:

    • Kuismaunmkbootimg довольно часто появляется на справочных форумах и, кажется, хорошо справляется со странными случаями, выводя «удобочитаемую» английскую рекомендацию, когда в mkbootimgисходном коде требуются некоторые изменения, и отображая точную командную строку для использования для восстановления образа.
    • Xiaolu,mkbootimg_tools кажется, также упоминается довольно часто и позволяет распаковывать и перепаковывать boot.imgфайл дерева устройств dt.img. Не обманывайтесь тем фактом, что он размещен на GitHub: это проприетарный двоичный файл с закрытым исходным кодом, и в их репозитории доступны только скомпилированные двоичные файлы (на самом деле я даже задаюсь вопросом о точном интересе использования репозитория исходного кода для хранения бинарные капли, но разные люди, разные умы...).
    • CNexus на форуме XDA предоставляет архив с подборкой инструментов.
    • Этот ответ в Unix.SE рекомендует некоторые инструменты из ныне несуществующего проекта Android Serial Port. Однако имена файлов наводят меня на мысль, что это должны быть старые готовые версии инструментов CyanogenMod (проект закрыт, нет ни документации, ни поддержки).

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

Некоторые производители выпускают ПЗУ, более или менее далекие от стандарта AOSP (необычные адреса, заголовки, формат файла и т. д.). Если приведенная ниже стандартная процедура не работает, возможно, вам поможет одно из этих альтернативных программ. В противном случае вам придется проверить наличие проблем, характерных для вашего устройства: для некоторых, похоже, требуется определенная процедура или даже определенные инструменты (например, задайте этот вопрос , относящийся к устройствам MediaTek).

Установка инструментов

Компилировать набор инструментов CyanogenMod для boot.imgупаковки и распаковки довольно просто.

  • Если вы уже установили полное дерево исходного кода Android (вы можете проверить мой другой ответ , чтобы получить больше информации об этом), перейдите в system/core/mkbootimg/каталог (напоминаем, что исходный код Google AOSP предоставляет только инструмент для создания boot.imgфайла, они не предоставить любой инструмент для распаковки),

  • Если у вас этого нет и вам это не нужно для каких-либо других целей, более простым и быстрым решением будет клонировать только репозиторий CyanogenMod android_system_core :

      git clone https://github.com/CyanogenMod/android_system_core.git
      cd android_system_core/mkbootimg/
    

Оказавшись в нужном каталоге, скомпилируйте и установите:

gcc -o ./mkbootimg -I ../include ../libmincrypt/*.c ./mkbootimg.c
gcc -o ./unpackbootimg -I ../include ../libmincrypt/*.c ./unpackbootimg.c
sudo cp ./mkbootimg ./unpackbootimg /usr/bin/

Обратите внимание, что Google заменяет C mkbootimgверсией Python , поэтому в будущих версиях для этой команды может больше не потребоваться компиляция.

Вам также потребуется установить инструменты Android на свой компьютер, чтобы он мог взаимодействовать с вашим телефоном. Вам понадобится adb(Android Debug Bridge, утилита оболочки, позволяющая взаимодействовать с подсистемой отладки Android), adbd(соответствующий демон) и fastboot(утилита оболочки, позволяющая взаимодействовать с системой загрузчика вашего телефона).

Ваш любимый дистрибутив Linux может предоставлять их в одном или отдельных пакетах, но обычно они всегда называются «android-tools»:

  • Дебиан/Убунту:sudo apt-get install android-tools-{adb,adbd,fastboot}
  • Федора/ЦентОС:sudo yum install android-tools
  • openSUSE:sudo zypper install android-tools

Получить boot.imgфайл

Извлеките boot.img либо из ZIP-файла ПЗУ, либо непосредственно с устройства:

  • Из .zip-файла стокового ПЗУ: некоторые приложения, такие как SuperSU, могут изменять boot.img непосредственно на устройстве, заменяя его стоковым, что может привести к поломке таких приложений.
  • Непосредственно с устройства: некоторые люди сообщают о проблемах чтения, приводящих к повреждению файлов boot.img. IMO, эти проблемы, скорее всего, связаны с использованием некачественных USB-кабелей или USB-концентраторов, и их можно просто избежать, используя качественные кабели, напрямую соединяющие телефон с компьютером. Вам также нужна возможность запуска ADB в корневом режиме (в зависимости от используемого ПЗУ это может быть тривиально или нет).

Первый способ очень очевиден: распакуйте ZIP-файл с помощью любой ZIP-программы, boot.imgфайл должен быть прямо в корне архива.

Для второго метода вам сначала нужно будет определить (к сожалению, зависящий от устройства) путь к устройству хранения, откуда boot.imgможно получить содержимое . Я знаю два метода для этого:

  • ls /dev/block/platform/*/by-name/(где *охватывает еще одно имя папки для конкретного устройства, скорее всего, это единственный каталог ниже platform/), точное имя для поиска также зависит от платформы, но имеет обычный смысл (некоторые примеры: boot, LNX(аббревиатура от «Linux»)). Файлы в этом каталоге на самом деле являются символическими ссылками, и некоторые люди пытаются вручную перейти к цели, но я рекомендую придерживаться пути на основе имени более высокого уровня, который, хотя и длиннее, остается менее подверженным ошибкам. Таким образом, вы получите путь вроде /dev/block/platform/sdhci-tegra.3/by-name/LNX.
  • На некоторых (старых?) устройствах нужное устройство можно было найти, изучив выходные данные cat /proc/mtd. Если вы видите устройство, mtd2связанное с "boot"меткой, вы будете использовать путь /dev/mtd2.

Сейчас:

  • В меню разработчика телефона:
    • Включите отладку на телефоне,
    • Разрешить корневой доступ к ADB (этот шаг относится к телефонам с CynogenMod, для других устройств может потребоваться более сложная процедура),
  • Подключите его к своему компьютеру (а оттуда к гостевой виртуальной машине, если вы запускаете инструменты Android из виртуальной машины).

Если это еще не сделано, я рекомендую вручную запустить сервер ADB на стороне компьютера, это позволит вам напрямую проверить ключ RSA на стороне устройства, не влияя на поведение следующих команд ADB:

adb start-server

Затем переключите ADB в корневой режим:

adb root

Наконец, вы должны иметь возможность напрямую извлечь boot.imgфайл с устройства с помощью такой команды (путь и имена источника и назначения приведены в качестве примеров, адаптируйте их к вашим потребностям и предпочтениям):

adb pull /dev/block/platform/sdhci-tegra.3/by-name/LNX ./boot.img

Команда скопирует весь раздел, как занятое, так и свободное пространство, поэтому не удивляйтесь, что полученный boot.imgфайл будет больше, чем исходный boot.imgфайл, поставляемый со стандартным ROM-файлом .zip, само содержимое остается аналогичным.

После завершения передачи отключите телефон и не забудьте отключить как отладку, так и root-доступ в меню разработчика.

Распаковать исходный boot.imgфайл

Распакуйте сам boot.imgфайл с помощью скомпилированной ранее команды:

unpackbootimg -i ./boot.img

Это выведет некоторую информацию, необходимую для того, чтобы вы могли восстановить новую boot.imgструктуру с правильной структурой по отношению к запасу boot.img. Однако не торопитесь с блокнотом, так как CyanogenMod upackbootimgтакже сохраняет ту же информацию в нескольких файлах, которые мы будем использовать позже.

Эта команда создает несколько файлов с определенными суффиксами, добавленными к имени входного файла:

  • *-second: это загрузчик второго уровня, необязательный и редко используемый на телефонах конечных пользователей. Если этот файл пустой (наиболее распространенный случай), то загрузчик телефона будет напрямую вызывать ядро ​​Linux.
  • *-zImage: Это ядро ​​Linux.
  • *-ramdisk.gzили *-ramdisk.lz4: RAM-диск, используемый для заполнения корневого каталога устройства. Расширение отличается в зависимости от используемого алгоритма сжатия.
  • *-dt: Дерево устройств, заполняющее /dev.
  • Остальные представляют собой небольшие файлы, в каждом из которых хранится одно из значений, отображаемых в unpackbootimgвыводе. Эти значения определяют параметр командной строки для передачи ядру Linux и адреса, по которым загрузчик должен будет загружать каждый объект во время загрузки.

Чаще всего распаковывают, boot.imgчтобы иметь возможность редактировать содержимое корневого каталога телефона. Как видно выше, это содержимое хранится в файле *-ramdisk.gzили *-ramdisk.lz4и может быть извлечено с помощью следующих команд:

mkdir ./ramdisk
cd ./ramdisk/
gzip -dc ../boot.img-ramdisk.gz | cpio -imd

Для сжатого RAM-диска LZ4 замените последний шаг на lz4 -d ../boot.img-ramdisk.lz4 | cpio -imd.

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

Пересоберите, чтобы получить новый new-boot.imgфайл

Процесс сборки CyanogenMod ROM зависит от внутреннего инструмента mkbootfsдля создания boot.imgфайла (это происходит в build/tools/releasetools/common.py ). Тем не менее, шаги по созданию этого инструмента кажутся мне бесполезно сложными, в то время как использование предоставленного системой, cpioпохоже, работает так же хорошо. Основное различие между ними, как я понял после (очень) быстрой проверки mkbootfsисходного кода, похоже, заключается в том, что последний применяет некоторые меры здравомыслия, не включая точечные файлы и /rootкаталог в результирующий архив, в то время как cpioпроцедура на основе ниже просто слепо поместит все выбранное дерево каталогов в архив.

Вывод: излишне сложный для компиляции с очень небольшим количеством преимуществ, так что давайте придерживаться системных инструментов!

Начните с создания нового RAM-диска из ramdiskсозданного выше каталога, введите:

find . ! -name . | LC_ALL=C sort | cpio -o -H newc -R root:root | gzip > ../new-boot.img-ramdisk.gz

Или, если вам нужно создать архив LZ4:

find . ! -name . | LC_ALL=C sort | cpio -o -H newc -R root:root | lz4 > ../new-boot.img-ramdisk.lz4

Цель здесь состоит в том, чтобы создать новый файл RAM-диска со свойствами, максимально близкими к исходному (например, настройка владельца часто отсутствует в процедурах, которыми делятся на форумах и в блогах, однако это требовалось на моем устройстве).

Теперь перейдите в родительский каталог, чтобы сгенерировать сам new-boot.imgфайл.

cd ..

Как видно выше, unpackbootimgкоманда CyanogenMod создает файл, соответствующий каждому параметру, ожидаемому mkbootimg. Поэтому все, что вам нужно сделать, это ввести a, mkbootimg -hчтобы получить список всех параметров, а затем установить для каждого из них соответствующее значение, используя соответствующий файл. Обратите внимание, что некоторые параметры предполагают путь к файлу, в то время как другие ожидают получить содержимое файла в качестве значения. См. пример полученной команды ниже:

mkbootimg                                           \
--kernel ./boot.img-zImage                          \
--ramdisk ./new-boot.img-ramdisk.gz                 \
--second ./boot.img-second                          \
--cmdline "$(cat ./boot.img-cmdline)"               \
--base "$(cat ./boot.img-base)"                     \
--pagesize "$(cat ./boot.img-pagesize)"             \
--dt ./boot.img-dt                                  \
--ramdisk_offset "$(cat ./boot.img-ramdisk_offset)" \
--second_offset "$(cat ./boot.img-second_offset)"   \
--tags_offset "$(cat ./boot.img-tags_offset)"       \
--output ./new-boot.img

Здесь не заданы только два параметра:

  • --board: Насколько я понимаю, это просто информационное поле, позволяющее вставить название модели в полученное изображение.
  • --id: этот не ожидает никакого значения, он просто выводит уникальный идентификатор после того, как изображение было построено (сочетая временную метку и контрольную сумму).

Прошить new-boot.imgфайл на устройство

  • Запустите устройство в режиме быстрой загрузки (он же режим загрузчика, обычно удерживая кнопки питания и увеличения громкости).

  • Подсоедините USB-кабель.

  • Убедитесь, что устройство правильно определяется:

      sudo fastboot devices
    
  • Попробуйте загрузиться с новым ПЗУ (еще не прошивая его, поэтому в случае возникновения проблем вам просто нужно перезагрузить телефон, чтобы он вернулся на следы, замените ./new-boot.imgимя файла на свое):

      sudo fastboot boot ./new-boot.img
    
  • Если телефон успешно работает с новым загрузочным образом, вернитесь в режим fastboot и прошейте его навсегда:

      sudo fastboot flash boot ./new-boot.img
      sudo fastboot reboot
    

Заключение

Сначала эта процедура может показаться сложной, но как только вы ее освоите, вы увидите, что на самом деле это не так.

«Устрашающий» аспект связан с тем, что не существует единой «системы Android»: многие производители и поставщики ПЗУ вносят изменения, которые могут варьироваться от незначительной разницы в пути до совершенно нестандартной среды.

Что вам нужно сделать, так это определить положение вашего конкретного устройства, а затем какие несколько команд подходят для вашего случая. Как только вы их получите, вы можете придерживаться их и даже легко создавать сценарии, если они вам часто нужны.

Иногда я добровольно вдавался в детали относительно низкого уровня, потому что это облегчит вам устранение неполадок. Если бы вы использовали какую-нибудь «более простую» непрозрачную утилиту для создания и прошивки вашего нового boot.imgфайла и увидели, что ваше устройство не может запуститься с ним, вам было бы сложнее определить, какой шаг пошел не так. Здесь на каждом шаге вы сможете сравнить данные, которыми вы манипулируете, с данными, поступающими из исходного boot.imgфайла или данными, которые видны на телефоне, или попытаться, например, восстановить boot.imgфайл либо с исходным, либо с вновь сгенерированным Файл RAM-диска, чтобы проверить, имеет ли это какое-либо значение (это позволяет точно определить, связана ли проблема с boot.imgпроцедурой создания файла RAM-диска).

Используйте Android-кухню. Там есть возможность распаковать/перепаковать boot.img, в папку Advanced options.

К сожалению, первоначальный автор официально прекратил поддержку Android Kitchen: « Этот проект закрыт в 2013 году, так как я был перегружен количеством поддерживаемых устройств, спросом, плохим здоровьем и постоянными просьбами о помощи ». Хотя было сделано несколько форков (я даю некоторые ссылки в своем ответе), но я не знаю, насколько они поддерживаются (например, я не нашел очевидного общедоступного способа поднять проблемы или запросить эволюцию).