Как сделать портирование

Добавил пользователь Евгений Кузнецов
Обновлено: 05.10.2024

Мы пообщались с руководителем компании Кириллом Мухиным, а также её сооснователем Дмитрием Ковтуном, чтобы побольше узнать о том, как происходит процесс портирования игр и с какими трудностями он сопряжён.

Для начала, расскажите немного о создании Pingle — как появилась компания, какие цели перед вами стояли?

Компания появилась 14 лет назад, собралась группа инициативных людей, которые любили играть в игры. Хотели своё хобби превратить в работу. Начали мы с создания своего продукта, но, как выяснилось позже, нам не хватало опыта, знаний и понимания в целом как создавать свой продукт и что с ним делать.

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

В общем, как начинается процесс портирования? Разработчик сам приходит к вам с просьбой портировать игру или этим занимается издатель?

Мы работаем с крупными мировыми издателями, они нам доверяют, так как мы совместно выпустили не один продукт. Как правило издатель обращается к нам и мы с ним и с разработчиком обсуждаем возможное сотрудничество.

А на каких обычно условиях заключаются договоры о портировании? Получают ли разработчики порта процент от его продаж?

Зависит от ваших способностей договариваться. Есть бюджет на портирование, он может быть большим, но в таком случае у вас нет процента от роялти. Если бюджет ограничен, вы обсуждаете процент от роялти.

Выдвигает ли разработчик или издатель какие-то требования к порту? Что в нём должно быть?

Разработчик и издатель всегда выдвигают ряд требований к порту. Тут может быть и видение, и вкусовщина. Но на разных платформах, существуют определённые требования от платформадержателя. Главная задача — удовлетворить все сертификационные требования.

А что по поводу неизбежных упрощений для консолей? Существует ли лист графических элементов, которые ни в коем случае нельзя трогать?

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

А все вот эти упрощённые модели и текстуры более низкого разрешения — их делают разработчики игры или порта?

В зависимости от того, как сделаны в проекте LOD, мы либо используем уже готовые упрощённые модели, либо же делаем их сами. С текстурами проще, они упрощаются в автоматическом режиме в специальном софте или посредством игрового движка.

Как в целом проходит работа над портом — можете кратко описать процесс? Сколько человек им занимается, какие задачи ставятся, как решаются?

Всё очень сильно зависит от проекта. Сам процесс зависит от того, на какие платформы планируется портирование. У каждой консоли есть свои требования к проектам. С мобильными платформами в этом плане проще.

Кроме требований платформ, есть ещё два важных аспекта: оптимизация проекта под соответствующую платформу и адаптация игры под контроллеры или тачскрин в случае с мобильными устройствами. По поводу команды всё тоже индивидуально.

К примеру, небольшую инди-игру, написанную для ПК на UE4 или Unity, для консолей Xbox/Xbox Series и PS4/PS5 может портировать команда до 5 человек за 2-3 месяца. Если же мы говорим о большом ПК-проекте, то для его портирования под консоли может потребоваться команда из более 20 человек и значительно больший срок.

С чем чаще всего возникают проблемы при портировании?

Насколько плотно компания, которая занимается портированием, сотрудничает с разработчиками игры? Что необходимо точно согласовывать?

По-разному, но, как правило, не сильно тесно. Бывает и такое, что к нам обращается издатель по поводу портирования игры, которая была выпущена для ПК какое-то время назад, а студия-разработчик уже не существует.

Сейчас практически все игры — даже какие-нибудь изометрические RPG — на старте имеют поддержку геймпада. Значит ли это, что работа по портированию свелась только к оптимизации под консольное железо?

Кроме оптимизации есть ещё большой объём работы по подготовке игры к прохождению сертификации. Если говорить про консоли Xbox, PS и Switch, то у каждой из них есть свои требования к проекту. Полный перечень требований можно найти на специальном портале для разработчиков. Оптимизация сама по себе может в отдельных случая занимать более 6-8 месяцев.

На консолях игры должны проходить сертификацию платформодержателя. Часто случается такое, что какие-то элементы, которые не вызывали нареканий на ПК, в Sony или Microsoft требуют изменить?

Да, это происходит регулярно. Требования к сертификации у платформ во многом схожие, но есть и отличия. Наша команда QA, начиная с того момента, как появляется играбельная версия для требующихся консолей, наряду с функциональным тестированием также проверяет игру на соответствие требованиям платформодержателей.

Если проблемы на этапе сертификации возникли не с производительностью, а, скажем, с какими-то образами, которые недопустимо показывать, кто занимается переделкой спрайтов и моделей: разработчики игры или порта?

Если нужно просто убрать какие-то объекты со сцены, то этим занимается наша команда. Если переделать — то общаемся с издателем или разработчиками.

При всей вот этой сертификации, как так получается, что и на консоли игры выходят с огромным количеством багов и низкой производительностью? Вот как было с Cyberpunk 2077?

Этот вопрос стоит задать сотрудникам Microsoft и Sony, которые сертифицировали Cyberpunk 2077.

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

Но, наверное, самая большая сложность в плане оптимизации была связана с тем, что разработчики оригинальной игры не планировали, что будет версия для консолей и, соответственно, не сильно заморачивались по поводу использования оперативной памяти, GPU и CPU. При всём при этом, хотим отметить, что команда Ice-Pick Lodge была очень вовлечена в процесс портирования и помогала нам.

Такой совсем дилетантский вопрос: на какую из консолей нынешнего поколения портировать проще? А с консоли на ПК или с ПК на консоль?

Проще всего портировать с консоли на ПК, но в основном у нас проекты, которые нужно с ПК перенести и адаптировать под консоли и мобильные устройства. Чем лучше железо у платформы, на которую нужно портировать игру — тем меньше времени и сил будет потрачено на оптимизацию. Но кроме этого ещё есть сертификационные требования и адаптация управления. В общем однозначного ответа нет, у каждого проекта ведь есть свои особенности.

Инди-студии чаще всего сами занимаются портированием своих игр. Это действительно выгоднее для них, чем обращаться к специализированным компаниям? Какие в целом расценки за порт, если не секрет?

К нам очень часто обращаются издатели именно инди-студий. Это вызвано тем, что инди-студии ограничены в ресурсах и, как правило, не имеют опыта со всеми платформами и не хотят распылять свой фокус.

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

Процесс портирования на консоли нового поколения чем-то отличается от предыдущих? У вас возникли какие-то трудности?

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

На какую платформу сложнее всего портировать игру?

Если выбирать из консолей, то это Nintendo Switch. Она самая слабая среди всех консолей в плане производительности.

На некоторых консолях есть дополнительные функции, которые как-то меняют опыт пользователя. К примеру, адаптивные триггеры на Dual Sense или светящаяся панель на DualShock 4. У вас есть какие-нибудь гайдлайны, которые вы используете при работе с такими особенностями?

Есть определённые гайдлайны и best practices от самих платформодержателей, которые мы используем.

Вы делаете масло?
- да. Мы делаем масло.
Как вы делаете масло?
-зависит от вида масла.
Каковы особенности изготовления масла?
- зависит от вида масла. Каждому виду - свои особенности. Мы их соблюдаем.
Вы сами добавляете что-то в масло?
-обсуждаем с теми, кто выпускает масло, если тестовый вариант масла понравился - делаем на всю партию.
_
Это пиздец. А не интервью.

На некоторых консолях есть дополнительные функции, которые как-то меняют опыт пользователя. К примеру, адаптивные триггеры на Dual Sense или светящаяся панель на DualShock 4. У вас есть какие-нибудь гайдлайны, которые вы используете при работе с такими особенностями?

Есть определённые гайдлайны и best practices от самих платформодержателей, которые мы используем.

Проблема в том, что эти самые гайдлайны — NDA. Если бы не, все бы только об этом и говорили. А тут официальная контора, не может нарушить NDA. Хотя в Сети есть разные пиратики, которые чуть ли не все гайдлайны сливают из кабинетов платформодержателей.

Такие компания полностью под NDA. Ничего особо точного сказать не могут. Увы, но давать при этом интервью – это как-то странно.

Комментарий удален по просьбе пользователя

Вот как было с Cyberpunk 2077?
Почему не спросили как Мор прошел сертификацию. Он-то в отличии от Киберпанка реально был неиграбелен

играл на обеих платформах, все норм

Можно сказать прошел

Абсолютно не одобряю подобное римское приветствие.

Действительно больше вода. Я могу понять, что они подписали nda и особо не хотели отвечать на технические вопросы. Возможно их даже и задавали, но ответ был - это секретная информация.
Если это статья о том, чтобы привлечь внимание инди студии, которым нужен порт, то меня как участника инди это не очень впечатлило.
Я портировал сам с pc под все три консоли, поэтому понимаю о чем речь.
Общаясь со знакомыми по цеху из других студий, могу поделиться вот чем. То ли это из-за нашего менталитета, то ли из-за отсутствия прозрачных процессов, то ли количества историй про то, как могут поиметь и фиг ты что-то докажешь, так как не прекрыл жопу. Короче, народ боится отдавать свое детище, на которое потратил, кто время, а кто и свои кровные. Ведь для порта, компании нужно передать исходный проект. Я понимаю, что возможно полетят санные тряпки в мою сторону, но имеем, что имеем. Как вы думаете?

На самом деле, подавляющее большинство студий, как инди, так и крупных не боятся шерить сорсы. Они ведь заинтересованы больше всех в том, чтобы игра вышла на нескольких платформах и по этой причине обращаются за помощью. Нам как разработчикам критически важно понимать что у игры "под капотом" перед тем как браться за портирование. Бывает, посмотришь на проект на стиме - вроде несложный проект и контент средний по качеству. Может сложиться ложное впечатление, что порт такой игры например на плойку - это вопрос пары месяцев. А по факту, когда открываешь сорсы с командой - то становится понятно, что "пол игры" нужно отрефакторить и контент переделать чтобы влезть в требования Сони :)

Не спорю, что вы правы, про большинство, особенно про интерес выхода на максимум платформ.
Мне кажется, ситуация была бы лучше, если бы доступ к девкитам был проще для нашего брата. Отсутствие возможно получить девкит в какой то мере и провоцирует потребность обращаться за помощью.
На самом деле, порт с ПК на консоль, любую, это простой процесс. Если разработчик уже раз это делал, то следующие игры он будет строить учитывая многие вещи на ранних этапах.
Тем более, ему не нужно разбираться в своем исходнике, он его сделал и ему быстрее будет это портировать.
Ну а сама сертификация, чисто правила, это самый простой этап. Если консоль тянет игру, то остальное это пустяк. Конечно это зависит от игры, если она многопользовательская и ещё и с валютой, то да, придется попотеть с разработкой их сервисов в том числе.

При всей вот этой сертификации, как так получается, что и на консоли игры выходят с огромным количеством багов и низкой производительностью? Вот как было с Cyberpunk 2077?

Наброс есть, ставлю плюс))

Доброго времени суток, уважаемый энтузиаст Android. Я очень долгое время изучал различные языки программирования (в основном HTML, CSS и JavaScript), способы, лазил по американским сайтам профессиональных разработчиков, в том числе XDA, Google developers и т.д., и наконец понял что от чего зависит в этом сложном и ещё не изведанном мире моей любимой операционной системы. На всю эту работу у меня ушло больше 1.5 года. Теперь, я решил передать свои знания, чтобы вам не тратить лишнего времени. Конечно, благодаря этому уроку вы не научитесь языкам программирования, вы просто узнаете “шаблон” , по которому просто можно портировать игры и приложения с ARMv7 на ARMv6, изменять максимальную поддерживаемую версию Android OS и взламывать игры.

Ведь эти крякнутые и портированные игры не из воздуха берутся в Интернете.


Первое о чём я расскажу – просмотр исходного кода *.apk

Для начала установите Java Машину , и зайдите в Apk Manager Multi Tool, при помощи файла Script.bat, что находится в папке APK Manager. Программа рабочая. От нас требуется выбрать файл, который мы будем распаковывать. Пишем в открывшейся консоли 25 и жмём Enter, и выбираем .apk файл (изначально кладите их в папку place-apk-here-for-modding, имя файла делайте коротким, и без всяких знаков, нужно чтоб имя файла не было Horn&^%,q~`.apk, лучший вариант – сократить до Horn.apk)

После того, как мы выбрали файл, с которым будем работать в консоли пишем цифру 9 и жмём Enter. Видим как идёт процесс декомпиляции.

После этого идём в папку Projects (в папке с APK менеджером). Видим папку Horn.apk (Имя Horn я использую как пример). В этой папке и лежат заветные исходники. Точно так же мы заходим в менеджер и нажимаем 11 (компиляция/сборка *.apk). Apk запаковывается. Вот и весь способ распаковки и запаковки приложений. Далее мы будем применять этот способ для портирования и изменения поддерживаемой версии Android OS.

Изменение максимально поддерживаемой версии Android OS.

Допустим, игра требует высокую версию Android, например 4.1, но ведь далеко не все ещё обновились на эту версию, и многие вряд ли когда-нибудь смогут обновиться. Для этого и предназначен следующий способ.

Распаковываем .apk и заходим в файл AndroidManifest.xml и ищем строчку:

“Число” здесь играет роль поддерживаемой версии Android, но не саму версию, а код этой версии, точнее сказать – уровень API. Все они указаны в этой таблице ниже:

Версия Android OS

Android 4.0.3, 4.0.4

Android 4.0, 4.0.1, 4.0.2

Подставляем нужное нам число, НО сразу предупреждаю – не ставьте слишком низкое число, например для очень классной игры, иначе приложение не откроется, и вы увидите на экране телефона весёлую надпись “Приложение не отвечает. Подождать ?” . Чтобы такой ошибки не возникло вполне хватит цифры от 8 до 10.


Дополнительно, для тех, кто хоть что-то понимает в HTML.

Если в атрибуты дописать android:maxSdkVersion=”11″, то мы сможем установить максимальную версию Android для этого приложения. Это уменьшит качество приложения, и будет более работоспособнее. В конечном итоге должно быть, например, так :

(Тем самым мы установили минимальную версию APi – 8,и максимальную – 11)

Далее сохраняем файл, и компилируем .apk. ГОТОВО ! Одно мы научились делать.

Приступим к изменению Видео ускорителя (Nvidia Tegra, Mali, Adreno, PowerVR)

Таким же способом, что и выше декомпилируем .apk, заходим в AndroidManifest.xml и ищём строчку

Я в этот раз не стану нагружать Вас разными цифрами, и рассказывать, что к чему. Просто вместо числа напишите слово integer (Поддержка всех видео ускорителей). То есть в конечном результате получается так :

Специально для Adreno 200-205 и слабых устройств – пишем число 65537 или 65536.

Эту тему изучили.

Ещё хотелось бы рассказать о постоянной проблеме – это когда файлы не перемещаются на sdcard.

Заходим в AndroidManifest.xml и находим строку или двустрочную надпись (обычно в самом верху)

Следует вместо Куда устанавливать ?! прописать одно из следующих значений :

Приложение будет устанавливать только на внутреннюю память, и не даст разрешения на перенос на внешний носитель

По умолчанию установит на внутреннюю память, но есть возможность перемещения на sdcard

Функция переводится как “предпочитать внешнюю память”. То есть приложение будет устанавливать сразу на внешний носитель, но нет гарантии, что оно будет это выполнять на 100%

То есть, если мы хотим, чтобы приложение установилось на внутреннюю память, но была возможность перемещения на sdcard, то пишем auto. В итоге получается :

Запаковываем, и вуаля ! Всё переноситься.

Далее самое интересное – как портировать игры с ARMv7 на ARMv6 !

Каждое приложение содержит библиотеки + реестр (в одном, или нескольких файлах) для использовании его на сильных устройствах. Также бывает графические библиотеки, будем называть их “Либы”(от англ. Libs)

В графических библиотеках содержаться только те текстуры, которые должны воспроизводиться только на ARMv7. В основном это mpg текстуры (libmpg.so или что-то похожее). Ещё есть звуковые файлы высокого качества, работают по такому же принципу как и графические. В основном это .vorbis формат (libvorbisidec.so или что-то похожее)

Приступим к делу,

Декомпилируем .apk и заходим в папку lib / libs ищем папку armeabi-v7a, и просто изменяем её название на armeabi. И просто запаковываем. Это самый ленивый способ и самый малоработоспособный.

Только если ты не опустил руки. Значит ты действительно хочешь узнать как это делается, что даже не поленился пролистать 4 страницы, то вот инструкция

P.S. Я же не корыстный человек, всё только для Вас, чтобы вы продолжили моё дело.

Как написано выше папку armeabi-v7a копируете в текущую папку (lib)

И переименуйте её в armeabi. В итоге у Вас получается две папки – armeabi и armeabi-v7a.

После этого папку lib переименуйте в libs – для тех, кто знает английский – мы поменяли единственное число (библиотека) на множественное (библиотеки).

У Вас должно быть 4 готовых варианта .apk для ARMv6 и все должны быть разные. Сейчас объясню.

Первый .apk – Всё как написано выше и запаковываем. (без доп. действий)

Второй .apk – Если в папке armeabi у Вас есть графический lib, то удалите его и запаковывайте

Третий .apk – Если в папке armeabi у Вас есть звуковой lib, то удалите его и запаковывайте

Четвёртый .apk – Если в папке armeabi у Вас есть графический и звуковой lib, то удалите их обоих и запаковывайте.

Если ни один из них не идёт на 800mhz + ARMv6, то либо вы что-то не правильно сделали, либо игра НЕ портируется на ARMv6.

Поделись статьей с друзьями

Отказ от ответственности: Автор или издатель не публиковали эту статью для вредоносных целей. Вся размещенная информация была взята из открытых источников и представлена исключительно в ознакомительных целях а также не несет призыва к действию. Создано лишь в образовательных и развлекательных целях. Вся информация направлена на то, чтобы уберечь читателей от противозаконных действий. Все причиненные возможные убытки посетитель берет на себя. Автор проделывает все действия лишь на собственном оборудовании и в собственной сети. Не повторяйте ничего из прочитанного в реальной жизни. | Так же, если вы являетесь правообладателем размещенного на страницах портала материала, просьба написать нам через контактную форму жалобу на удаление определенной страницы, а также ознакомиться с инструкцией для правообладателей материалов. Спасибо за понимание.

УРОКИ ПО СОЗДАНИЮ ПРОШИВОК НА АНДРОИД

ВНИМАНИЕ: ТЕЛЕФОНЫ ДОЛЖНЫ БЫТЬ СХОЖИ ПРОЦЕССОРАМИ И ОПЕРАТИВНОЙ ПАМЯТЬЮ. ЭТО ВАЖНО

Итак мы всё скачали.
На рабочем столе создаём две папки (чтобы было проще).
Первую папку назовём "БАЗА",в неё распаковываем с помощью архиватора официальную(для вашего аппарата)прошивку.
Вторую назовём "ПОРТ",в неё распаковываем вторую прошивку (с другого аппарата)

Теперь сам процесс портирования:

ВСЕ ФАЙЛЫ КОТОРЫЕ БУДЕМ МЕНЯТЬ БЕРЁМ ИЗ БАЗЫ И ЗАМЕНЯЕМ В ПОРТ.

1. Берём из папки "БАЗА" boot.img и копируем его в папку "ПОРТ" с заменой.
(ПО ПОВОДУ РАЗБОРКИ И РЕДАКТИРОВАНИЯ ЯДРА(boot.img)РАССКАЖУ В ДРУГОМ УРОКЕ.может это сделает кто-нибудь другогй)
2. Открываем файл update-script с помощью Notepad++ (в папке "ПОРТ")который находиться по пути META-INF>com>google>android и в нём меняем следующее:
1) в строчках
symlink("wlan_mt6628.ko", "/system/lib/modules/wlan.ko");
symlink("wlan_mt6628.ko", "/system/lib/modules/wlan.ko");
выставляем радиочип который стоит на вашем аппарате mt66** .
2) далее после строчки show_progress(0.050000, 2); прописываем
assert(package_extract_file("boot.img", "/tmp/boot.img"),
write_raw_image("/tmp/boot.img", "bootimg"),
delete("/tmp/boot.img"));
сохраняем и выходим.
3)приступаем к папке system
идём по пути system>bin: здесь заменяем файлы из "БАЗА" в "ПОРТ" 6620_launcher,mtkbt и linker.
далее идем по пути system>usr. Здесь заменяем папки keychars и keylayout в них лежат файлы с описанием кнопок.
далее по пути system>ets заменяем папку firmware. В ней содержаться файлы радиочипа. Тут же заменяем папку permissions,wifi(для работы WI-FI),bluetooth(соответственно для работы bluetoot).
далее по пути system>lib заменяем папку modules, и отдельно либы libbluetooth_mtk.so,libbluetooth_relayer.so,libcameraprofile.so,libcameraservice.so,libcameracustom.so,libcamera_client.so,libcamalgo.so,
далее в файле build.prop в строках:
ro.build.host
ro.product.model
ro.build.tags
ro.product.brand
ro.product.name
ro.product.device
ro.build.type
mediatek.wlan.module.postfix
mediatek.wlan.chip
прописываем как в "БАЗА"

Теперь всёзакрываем и запаковываем в zip архив.
После того как архив создан его нужно подписать программой signscript.
готово. ставим через cwm либо twrp.
в дальнейшем расскажу об устранении ошибок и не рабочих приложений.

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


Для портирования понадобятся такие программы, как Notepad++ (или любой другой качественный текстовый редактор), WinRar (или другая программа-архиватор), персональный компьютер (с операционной системой Windows или другой), а также хотя бы базовый уровень познаний в структуре операционной системы Android и здравый смысл (например, нет смысла портировать HDPI-ROM напрямую на MDPI и так далее).

Также потребуются два ROM`а – портируемый и CM7/GB/Stock в качестве базы для создаваемого порта. Вы также должны быть обознаны в том, на основе какой ревизии платформы ARM создан ваш девайс (ARMv5, ARMv6 или ARMv7), так как ROM-основа и ROM-порт обязательно должны быть под один и тот же тип процессора.

По факту, работа проводится с тремя основными папками – портируемым ROM’ом, из которого извлекаем всё необходимое; базовым ROM’ом – то есть, куда производит портирование, и где собираем уже новую версию ROM`а; резервными копиями, создаваемыми по ходу дела.

Для начала, создадим резервную копию из папки базового ROM, а именно файлов, которые находятся в директории /system/app:

stk.apk
vpnservices.apk
camera.apk
bluetooth.apk

Backup можно поместить куда душе угодно, даже на рабочий стол.

Удаляем нижеуказанные папки из базового ROM и заменяем их портируемым:

/data
/system/app
/system/framework
/system/fonts
/system/media

Не забываем скопировать из портируемого ROM в базовый библиотеку libandroid_runtime.so в папку /system/lib, поскольку без неё новый ROM с высокой долей вероятности не запустится вовсе. Впрочем, если при условии замены устройство уходит в циклический ребут, то есть безостановочно и безрезультатно перезагружается – стоит попробовать использовать libandroid_runtime.so из базового ROM’а.

Копируем файлы, резервные копии который создали, в базовый ROM. Далее, копируем все библиотеки и папки, находящиеся в system/lib базового ROM, в соответствующую директорию портируемого. Заменяем все файлы в случае совпадения имен. В базе удаляем директорию lib полностью, перемещаем такую же папку из портируемого в базовый ROM.

В build.prop портируемого ROM`а были такими же, как в базового, иначе созданная прошивка не будет работать вовсе. Сохраняем build.prop и закрываем Notepad++, после чего копируем Build.prop из портируемого ROM в базовый.

Вот, в принципе, и всё. Финальная прошивка получилась в папке базового ROM. Также в неё можно добавить по вкусу разные приложения, патчи, скрипты и так далее.

Читайте также: