Пользователь
0,0
рейтинг
16 июня 2010 в 16:27

Разработка и модификация прошивки для Android телефонов на примере HTC Hero GSM. Часть 1

Причины по которым люди ставят модифицированные версии прошивок различны. Кому-то хочется удивить друга смешной анимацией загрузки, кому-то не хватает определенного функционала (например vpn), кто-то хочет выжать максимум производительности из своего телефона за счет разгона процессора, а кто-то пять месяцев ждет новую версию операционной системы Android для своего любимого HTC Hero.
На данный момент уже существует превеликое множество самых невообразимых сборок для самых различных телефонов на базе Android. Иногда они даже появляются в той или иной форме на Хабре.
Я же хочу Вам рассказать о процессе и особенностях создания кастомной прошивки на основе официальной. Данные знания были получены в процессе разработки одной из не многих отечественных прошивок на базе Android 2.1 для HTC Hero GSM. И более или менее успешно опробованы на себе и других подвернувшихся пользователях одного крупного российского форума.
Не смотря на то, что все нижеследующее было сделано для HTC Hero, данные правила и особенности имеют полную силу для всех телефонов, особенно тех, которые разработаны компанией HTC и используют фирменную оболочку Sense.
Для экспериментов нам понадобится:
  • Android SDK желательно последней версии
  • Утилита apktool для реинжениринга системных приложений
  • Утилиты smali/baksmali для де-оптимизации системных приложений
  • Утилита unyaffs для извлечения системных файлов из образа
  • Скрипт split_bootimg.pl для извлечения ядра и ramdisk-а
  • Утилита testsign для подписывания пакета обновления и отдельных приложений
  • установленное и настроенное JRE
  • телефон с операционной системой Android
  • права суперпользователя и модифицированная подпрограмма восстановления (recovery rom)

Все вышеперечисленное доступно в версиях как для системы Linux так и для Windows. Но в своих примерах я буду ориентироваться на использование Linux.
Конечно же ни root-права ни recovery нам не нужен для того, чтобы начать разработку, однако если мы захотим опробовать наше творение, они нам понадобятся. Для HTC Hero можно использовать RA-hero-v1.6.2.
Наверное, самое время напомнить, что использование неофициальных прошивок лишает нас гарантии, но где наша не пропадала. И несмотря на то, что большинство операций безопасно — всегда нужно четко понимать что и зачем делается, дабы не причинить необратимый вред своему андроиду

Основа



Существует несколько различных подходов к разработке прошивки.

Несмотря на то, что платформа Android вроде как и является открытой, но в реальных телефонах используются закрытые компоненты. Это и драйверы распространяющиеся в бинарном виде (wifi/gps/fm), и ключевые компоненты системы, такие как Маркет и другие сервисы Google. Также сюда нужно добавить разработки компаний в области интерфейса, такие как HTC Sense, Motoblur, TouchWiz от Sumsung. Это создает местами непреодолимые трудности по разработке прошивки из исходных кодов.
Я предлагаю остановиться на модификации готовых прошивок, предоставляемых вендорами телефонов.
Прошивки для телефонов HTC существуют в двух видах:
  • RUU. Rom Update Utility (Утилита обновления прошивки). Утилита для ОС Windows производящая обновление телефона
  • OTA. Over the Air (Обновление по «воздуху»). Пакет, скачиваемый самим телефоном через wifi/gprs сети, который устанавливается на телефон без какого-либо участия компьютера

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

Извлечение rom.zip



1. Скачиваем подходящую версию RUU для интересующего нас телефона. Найти которую можно либо на сайте HTC, либо в других источниках. Для HTC Hero воспользуемся, вышедшей в начале июня версией Android 2.1 для оператора Chunghwa (Тайвань)
2. RUU утилита при обновлении телефона прошивает сразу несколько областей:
  • загрузчик boot (hboot)
  • ядро linux + ramdisk (boot)
  • прошивка для радио-модуля (radio)
  • подпрограмма восстановления (recovery)
  • системный раздел (/system)
  • пользовательский раздел (/data)

Однако мы не можем позволить RUU-утилите перезаписать наш любовно установленный загрузчик и recovery. Дабы иметь и далее возможность устанавливать не только официальные прошивки. Для этого нам необходимо извлечь радио/boot/system/data.
В сущности RUU является InstallShield-овским инсталлятором, который несет в себе необходимые нам образы в rom.zip.
Запускаем его и попадаем в заглавный приветственный экран. Не заходя дальше, открываем системную папку %TEMP%, в которой мы видим 2 новые папки, в одной из которых мы найдем файл rom.zip. Копируем в уединенное место и закрываем RUU отменой установки.


Распаковка образов



Распаковав полученный архив и удалив не интересные для нас образы, мы увидим:
  1. $ ls -1 rom
  2. boot.img
  3. Radio_Signed_HERO_63.18.55.06O_6.35.15.01.img
  4. system.img
  5. userdata.img
Телефон несет в себе 512Мб NAND Flash, которые разбиты на следующие логические блоки 
  1. $ adb shell cat /proc/mtd
  2. dev:    size   erasesize  name
  3. mtd0: 00040000 00020000 "misc"
  4. mtd1: 00500000 00020000 "recovery"
  5. mtd2: 00280000 00020000 "boot"
  6. mtd3: 0aa00000 00020000 "system"
  7. mtd4: 08200000 00020000 "cache"
  8. mtd5: 0a5c0000 00020000 "userdata"
Как мы видим, данные области памяти непосредственно связаны с полученными нами образами. RUU производит запись образов as-is, но мы хотим ведь изменить наполнение системы, поэтому нам необходимо распаковать их.
В качестве файловой системы для NAND в android используется yaffs2
  1. $ adb shell mount | grep yaffs
  2. /dev/block/mtdblock3 on /system type yaffs2 (ro)
  3. /dev/block/mtdblock5 on /data type yaffs2 (rw,nosuid,nodev)
  4. /dev/block/mtdblock4 on /cache type yaffs2 (rw,nosuid,nodev)
Распакуем system и data (/cache остается пустым)
  1. $ mkdir system && cd system && unyaffs ../../../rom/system.img
  2. $ mkdir ../data && cd ../data && unyaffs ../../../rom/userdata.img
В результате мы получили полноценное корневое дерево, пригодное для прошивки в телефон, которое содержит системные библиотеки, framework, системные приложения, файлы конфигурации и пр.


Стоит учитывать, что в распакованном архиве содержатся символические ссылки, которые будут утеряны на файловых системах не поддерживающих оные (fat/ntfs). Которые мы можем восстановить через скрипт обновления, о чем будет рассказано в другой статье.

Ядро



Также нам понадобиться boot-раздел, который по сути является linux ядром (для выбранной прошивки это 2.6.29 armv6l) с ramdisk-ом и имеет следующий формат:
** +-----------------+
** | boot header     | 1 page
** +-----------------+
** | kernel          | n pages
** +-----------------+
** | ramdisk         | m pages
** +-----------------+
** | second stage    | o pages
** +-----------------+
**
** n = (kernel_size + page_size - 1) / page_size
** m = (ramdisk_size + page_size - 1) / page_size
** o = (second_size + page_size - 1) / page_size

Если мы захотим заменить ядро, либо модифицировать скрипты инициализации, нам необходимо их извлечь из boot-образа. Для этого нам понадобиться замечательный perl-скрипт split_bootimg.pl за авторством William Enck.
  1. $ split_bootimg.pl ../rom/boot.img
  2. $ ls
  3. boot.img-kernel boot.img-ramdisk.gz  data  system

С самим ядром мы ничего не можем сделать, кроме как заменить его другим, а рамдиск можно распаковать для последующего изменения и настройки:
  1. $ mkdir ramdisk && cd ramdisk && gzip -dc ../boot.img-ramdisk.gz | cpio -i
  2. $ ls
  3. data  default.prop  dev  init  init.goldfish.rc  init.hero.rc  init.rc  logo.rle  proc  sbin  sys  system
В данной статье мы не хотим ничего делать ни с ядром ни с ramdisk-ом, а потому запакуем все обратно (либо вернемся на шаг назад и вообще не будем трогать boot)
  1. find . | cpio --quiet -o -H newc | gzip > ../new-ramdisk.gz
  2. $ cd .. && mkbootimg --kernel boot.img-kernel --ramdisk new-ramdisk.gz --cmdline "no_console_suspend=1 console=null" -o newboot --base 0x19200000
Для других телефонов настроки базового смещения могут отличаться. Коммандлайн мы получаем из split_bootimg при распаковке.

Скрипт обновления



Для обновления будем использовать update-скрипт, который пишется на специальном скриптовом языке edify, о синтаксисе которого можно прочитать в исходниках android. Скрипт /META-INF/com/google/android/update-script может быть таким:
  1. show_progress 0.1 0
  2. format CACHE:
  3. format SYSTEM:
  4. copy_dir PACKAGE:system SYSTEM:
  5.  
  6. set_perm_recursive 0 0 0755 0644 SYSTEM:
  7. set_perm_recursive 0 2000 0755 0755 SYSTEM:bin
  8. set_perm 0 3003 02755 SYSTEM:bin/netcfg
  9. set_perm 0 3004 02755 SYSTEM:bin/ping
  10. set_perm_recursive 1002 1002 0755 0440 SYSTEM:etc/bluez
  11. set_perm 0 0 0755 SYSTEM:etc/bluez
  12. set_perm 1002 1002 0440 SYSTEM:etc/dbus.conf
  13. set_perm 1014 2000 0550 SYSTEM:etc/dhcpcd/dhcpcd-run-hooks
  14. set_perm 0 2000 0550 SYSTEM:etc/init.goldfish.sh
  15. set_perm_recursive 0 0 0755 0555 SYSTEM:etc/ppp
  16. set_perm 0 0 04755 SYSTEM:etc/ppp/ip-up-vpn
  17. show_progress 0.1 10
  18.  
  19. show_progress 0.2 0
  20. copy_dir PACKAGE:data DATA:
  21. show_progress 0.2 10
  22.  
  23. show_progress 0.3 0
  24. format BOOT:
  25. write_raw_image PACKAGE:boot.img BOOT:
  26. show_progress 0.3 10
Пока этот скрипт очень примитивен и единственное что он делает — подготавливает соответствующие разделы.

Подпись пакета обновления



Для того, чтобы мы смогли прошить нашу прошивку, нам необходимо подписать пакет обновления. Этот процесс аналогичен процессу подписывания jar-пакетов. К пакету добавляется ваш (либо тестовый) сертификат и сохраняются контрольные суммы для файлов внутри него.
  1. $ zip -r habrarom.zip .
  2. $ java -classpath ../../bin/testsign.jar testsign habrarom.zip habrarom-signed.zip

Прошивка радио модуля



Это самая простая часть в плане создания пакета обновления, но и самая опасная в плане последствий при неудачном обновлении.
Пакет обновления создается абсолютно идентично предыдущему, только содержать он будет бинарный блоб с радио, который мы извлекли из RUU и скрипт для его записи в соответствующий раздел памяти.
Простенький скрипт:
  1. show_progress 0.1 0
  2. write_radio_image PACKAGE:Radio_Signed_HERO_63.18.55.06O_6.35.15.01.img
  3. show_progress 0.1 10
Не многое, что будет включено в данный пакет обновления.
  1. $ ls -1
  2. META-INF
  3. Radio_Signed_HERO_63.18.55.06O_6.35.15.01.img

Всё это упаковывается и подписывается как делалось ранее.

Прошивка



Не смотря на то, что в полученную прошивку мы не добавили пока никакого нового функционала, мы бы хотили попробовать прошить и загрузиться в нее.
Для этого 
  1. Копируем в корень карты наш пакет обновления
  2. Загружаемся в recovery
  3. Делаем nanroid backup
  4. Делаем wipe
  5. Прошиваем
  6. Перегружаемся

Радуемся тому, что наш больной пережил сложную операцию.


В данный обзор не вошли следующие важные вопросы, которые затрагивают уже непосредственно модификацию подготовленной базовой прошивки. Вопросы с которыми сталкивается любой создатель кастомов, и столкнулся непосредственно я при создании русской версии прошивки 2.1 для HTC Hero GSM
  • Добавление root, busybox
  • Де-оптимизация (deodexing) пакетов. Использование smali/baksmali. Разрешение odex-зависимостей
  • удаленная odex-оптимизация приложений
  • Модификация системных пакетов. Подпись пакетов: когда нужна, и когда можно пренебречь. Упаковка приложений. Обновление ресурсов приложений без пересборки
  • Локализация системы, как пример масштабной модификации системы.
  • Декомпиляция и сборка ресурсов/байткода системных приложений. Исправление ошибок системных приложений
  • zip-align, png оптимизация
  • Подписывание приложений и проблема круговой поруки при использовании shared uid
  • Использование скриптов инициализации на примере переноса данных из одного раздела в другой (dalvik-cache2cache, app2sd)

А тем временем ждем с нетерпением, когда за обновлением FOTA клиента последует обновление самой системы до версии 2.1-update1.

В предыдущих и будущих сериях
  1. Часть 1. Создание прошивки в формате update.zip на основе RUU. Распаковка/запаковка boot. Скрипт обновления. Подпись пакета обновления и приложений.
  2. Часть 2. Добавление busybox. Добавление root. Монтирование на запись. Скрипт инициализации. Редактирование ramdisk.
@stari4ek
карма
33,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое

Комментарии (46)

  • НЛО прилетело и опубликовало эту надпись здесь
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Если бы вдруг, этот топик оказался в соответствующем ему тематическом блоге было бы совсем замечательно.
  • 0
    Наконец-то грамотная статья на эту тему. Огромное спасибо. Интересно еще почитать про apktool и smali.
    • +1
      обязательно будет.
      apktool — одна из самых полезных утилит при работе с кастомами. 1.3.1 версия исключительно хороша, практически идеальна.
  • 0
    Перенесите в блог Android :)
    • 0
      С радостью выполнено!
  • 0
    Просто офигенно! Ещё и на русском
  • +1
    было бы еще интересно как создавать свои прошивки, к примеру для HTC, но который изначально под WM6
  • +1
    Да =) как раз чем-то похожим я и занимаюсь только для читалки нук =)))) Делаем русификацию и портируем FBReader =))))

    Кому интересно, могут почитать анонс mynook.ru/rucifikaciya-nook-uzhe-skoro/ =)
    • 0
      За что вам большое человеческое спасибро!
      • 0
        не за что) всегда приятно сделать что-нибудь для людей) тем более, если мне это легко +)
  • +1
    Вот у меня появились некоторые проблемы и хочется узнать некоторые вещи =)))

    дело в том, что я не могу заменить стандартное приложение, я могу удалить, но вот такое же с таким же пакетом (просто пропатченное через APKTool) переустановить не получается. Вообще не работает adb install проги, которая уже установлена…

    стандартные проги я переустанавливаю просто напросто через adb push, но при таком варианте я не могу менять код (smali/backsmali), иначе после такого adb push у меня вообще все виснет и т.д. =)

    Что-нибудь известно вам по поводу подобных блокировок?
    • 0
      Переподпиши все пакеты из процесса в котором они работают.
      • 0
        процесса? а где посмотреть эти процессы?..
        • 0
          делаете decode всем пакетам из прошивки.
          смотрите какой shared uid у вашего приложения. ищите где он еще используется
        • 0
          Самый простой вариант, когда подпишешь своим ключем, кидай его в /system/apps/ и смотри логкат, он там ругнется что подпись не совпадает, и напишет с какими именно пакетами.
          • 0
            А самое лучшее, берешь прошивку, и переподписываешь ВСЕ пакеты, ключики можно взять тестовые, для media, shared и platform.
            • 0
              хорошо, но там какой-то свой загрузчик и надо его смотреть еще, как разобрать/собрать.

              А где берутся тестовые ключики?
              • 0
                Обратите внимание на раздел статьи, относящийся к подписыванию прошивки.
                Аналогично подписываете и apk-и
                • 0
                  я знаю как подписывать приложения, при чем здесь это?
                • 0
                  спасибо!
                  А можно узнать зачем разделение такое сделано в ключах?
                  • 0
                    Видимо в целях безопасности. Описание по ключам:
                    testkey — a generic key for packages that do not otherwise specify a key.
                    platform — a test key for packages that are part of the core platform.
                    shared — a test key for things that are shared in the home/contacts process.
                    media — a test key for packages that are part of the media/download system.
            • 0
              А потом имеешь проблемы с обновлением маркета (Vending) и прочих гугломапов.
              Но можно и так. Я тоже так сперва делал.
              • +1
                о господи. Вы почитайте мой первый пост. я хакаю читалку =) какой маркет?))))
                • 0
                  ну у меня живого устройства нет. Я не знаю какие там приложения идут в комплекте.
              • 0
                У меня никаких проблем с маркетом не было. Просто не трогаешь все что относится к маркету.
          • 0
            вот в том-то и дело, что в логкат ничего не пишется. у меня такое ощущение, что все было вырезано из логката на этой железке =)
            • 0
              Сравните ваш /system/etc/event-log-tags с другими прошивками
              • 0
                спасибо, посмотрю!)
    • 0
      «Пропатченное через apktool» это очень странное описание. apktool не умеет патчить. Но с его помощью можно разобрать приложение и собрать обратно.
      1. После сборки нужно будет его подписать.
      2. Если данное приложение использует shared uid, то нужно также подписать все другие приложения, его использующие, иначе приложение не будет принято системой из-за несовпадения сертификатов
      3. Если приложение было с .odex-ом, то другие приложения, использовавшие его перестанут работать. Их также необходимо deodex-снуть.
      4. Убедиться что в собранном вами приложении имеется classes.dex

      А вообще adb logcat во push-а очень хорошо показывает какая именно проблема.

      Об этих проблемах и путях обхода я собираюсь рассказать в будущих частях.
      • 0
        1 — подпись не помогает
        3 — нет никаких odex
        4 — все файлы на месте

        пропатченное через apktool — это распакованное, поменянное, собранное +)

        дело в том, что adb lolcat ничего не пишет — все просто виснет. причем adb push проходит и заканчивается успешно. Причем это все происходит только при пересборке classes.dex.

        надо поковыряться с этими shared uid
  • 0
    Спасибо за статью, очень интересно
  • +2
    Очень интересная статья, обязательно пишите 2-ю часть)
  • 0
    Хм. Обрадовали. Пока не сильно хочется шить официал(который может быть на неделе уже будет..). Наслышан, что после обновления нельзя будет шить кастомы. сначала попробую с самопалом поиграться, а там поглядим на поведение htc ;))

    и вот как раз вопрос. не сталкивались с этой защитой от кастомных прошивок? ее обходить можно будет?
    • +1
      «Нельзя будет шиться» это как раз ситуация, если вы воспользовались RUU/OTA прошивкой, которая записала hboot/recovery. Упоминается в статье.
      Новые версии hboot обычно закрывают експлоиты, с помощью которых были изначально получены права суперпользователя на телефоне. И иногда отключают возможность понижения версии прошивки, что закрывает путь к откату на старую версию с известным эксплоитом.
      • +1
        и забыл.
        Я глубоко уверен, что «защита от кастомов» это миф, рожденный от того, что различные разработчики кастомов использовали некорректный fingerprint для телефона, что приводило к тому, что из маркета пропадали платные и drm (не обязательно платные) приложения. Google производит фильтрацию доступных приложений по базе «разрешенных fingerprint». По крайней мере на данном этапе это так. Не исключено, что этот механизм может измениться.
        • 0
          спасибо. буду в курсе. :)
  • +1
    Правильно ли я понимаю, что при перепрошивке на более новую версию, необходимо перенести «драйверы распространяющиеся в бинарном виде (wifi/gps/fm)»? Тогда почему возникают сложности у производителей устройств с новыми версиями Android? В чем именно затык??
    • 0
      С новыми версиями обычно обновляется линукс ядро. Новый abi — значит нужно закрытые драйверы адаптировать под него.
      Также с новыми версиями меняется и сам фреймворк андроидовский. Производителям телефонов нужно адаптировать свои наработки под него. Интегрировать новые фишки системы в свои интефрейсы.
      А когда изменения от производителя масштабные (например HTC Sense) — таких адаптаций много.

      Ну и не исключаем маркетинг. Новые устройства нужно тоже продавать =)
      • 0
        А не подскажите как происходит адаптация драйверов, например с WinMo? Т.е. их дизасемблируют и пишут с нуля непосредственно на Андройд? Можете про это рассказать?
        • 0
          Ух. Не могу рассказать. не имею опыта.
          По сути тут нужен серьезный реверсинжениринг. Есть также малый шанс, что уже существует открытая версия драйвера для самого устройства, либо его архитектурного аналога/предшественника.
  • 0
    Читаю коменты и ужасаюсь — какие нехилые проблемы 'созданы' подписыванием, закрытием кода и не только для модификации приложений. И все это при использовании открытых лицензий. Все никак не соберусь разобрать причины, почему вообще разрешается использовать в готовых устройствах комбинации закрытых блобов (драйвера и приложения) и открытого кода, при условии что лицензия не является аналогом LGPL (ядро GPL2).
    * причины в наличии каких то юридических лазейках лицензии ядра GPL2 (и на 3-тью переводить никто не собирается)? но это для ядра, а что закрытые приложения, которые формально линкуют, а неформально жестко завязаны на открытом коде?
    * что является причиной наличия радиоблоба (драйвера и библиотеки для работы с радиомодулем)? какие то ограничения ОпСоСов? Это как то регулируется на законодательном уровне? Раздолбайство или я просто чего то не знаю и уже давно есть полностью открытый код для работы хоть с какими-либо устройствами — доступными как комплектующие?

    P.S. Все никак не соберусь, хотелось совсем немного 'поправить перевод' и может быть немного способ отображения текста (наименование типа номера в контакте) в диалере, так как в русском переводе это название вместо Call to:work красуется бессмысленное и широкое Позвонить по номеру:... в вертикальной ориентации. Для этой примитивной с точки зрения разработки правки необходимо совершить действия сравнимые по трудоемкости чуть ли не взлому защиты средней программы, начиная от реверсинженеринга и заканчивая изучения десятка утилит по перепаковке, подписывания, и поиска способов исправления появившихся странных глюков вида 'исчезание некоторых приложений из маркета'.

    Кажется что то не то в мире происходит с открытым кодом, linux и мобильными технологиями… не развитие это!
    • 0
      Промазал веткой. Ответ ниже — Вам.
  • 0
    Ну. Производители пытаются работать по старой схеме к которой они привыкли. Все своё — никому не. Не уверен, на сколько там действительно есть что скрывать от конкурентов. Потому и радио-модуль распростроняется в виде бинарника.
    Подписывание пакетов — на самом деле здравый механизм. С одной стороны проверка на валидность и целостность пакета, с другой — защита от подмены источника пакета. Никто ведь не жалуется на сертификаты в ssl.
    Если нужно — можно подписать все тестовыми ключами, или своими — что и будет говорить «поставщик — я». Другое дело, что для пользователя такого кастома это ни разу не удобно ждать вашей перепаковки обновления, когда оно выйдет. Ему удобнее обновиться из оффициального источника, а вот тут конфликт смешивания разных «поставщиков».
    Если вы хотите исправить оригинальный диалер (не HTC) — то ничто не мешает собрать его из исходников и сделать идеальным. Правда, когда я исправлял диалер от Sprint CDMA для GSM, это потянуло на переподписывание 20 пакетов (хотя сейчас мне кажется, что используя один трик можно было бы избежать этого).

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.