Entrada fija

lunes, 7 de septiembre de 2015

Compilar MIUI v6 desde Source

Muy buenas a todos! Hoy vamos a trabajar con una ROM distinta a las demás ya que usa un sistema diferente para ser compilada: patchrom.
Al usar este sistema no necesitaremos un Device Tree, ya que extraeremos los archivos necesarios para compilar desde nuestro propio dispositivo usando ADB.
Puede resultarte más fácil o difícil este método. En mi opinión, es bastante denso el trabajo que hay que hacer, y os recomiendo saber qué cosas tenéis del entorno de compilación y cuáles no antes de comenzar.

*Este tutorial también es aplicable a Miui v7*

1. Preparar Entorno de Compilación

Lo primero será preparar todo lo necesario para portar Miui a nuestro dispositivo. Habrá que instalar varias cosas que a lo mejor algunas ya tendréis instaladas; os recomiendo borrarlas y configurarlas desde cero.

Java 7 OpenJKD

Evidentemente, esta no hará falta que la borres si ya la tienes. Si no, la instalamos así:

                                             

Si tienes instalada otra versión de Java, cambiamos a usar el JDK7 por deecto con este comando:

                                                

Ejecutamos cada comando por separado, y cuando aparezca la pantalla de selección, escribimos el número que corresponda a JDK7 y damos a enter.

Te preguntarás cómo es que usamos Java 7 si es para compilar KiKat. Yo la primera vez que fui a compilar tenía Java 6, y en un paso del proceso de compilación me dio un error. Tuve la corazonada de instalar Java 7 y el problema desapareció.

Hecho esto ya tendremos la versión de Java más adecuada para trabajar en esta ROM.


Android-SDK // ADB & Fastboot

Si has hecho el tutorial de tomar LogCat ya lo tendrás, así como el ADB y Fastboot. Recomiendo borrarlas y empezar de cero. Para configurarlo haremos lo siguiente:

Descargamos el archivo comprimido de su página oficial. Estará en la carpeta "Downloads"
*Para descargarlo vete al final de la página donde dice "SDK Tools Only" y elige la versión para Linux.

Una vez descargado lo descomprimimos y copiamos la carpeta "android-sdk-linux" y la pegamos en el directorio "home" en una carpeta nueva con el nombre "android".

Entonces instalamos unos paquetes de compatibilidad necesarios:

                        

Una vez ejecutados los tres comandos, abrimos el mánager de SDK:

                                             

Se abrirá una interfaz. Entonces elegiremos instalar todos los paquetes que aparezcan debajo del paquete "Tools" y aceptamos.
Una vez descargado dirígete al directorio "home" con el explorador de archivos. Presiona Ctrl+h (mostrar archivos ocultos) e identifica el archivo ".bashrc" (si no existe lo creamos). A continuación lo abrimos y pegamos lo siguiente:


                          

Guardamos y salimos. Ahora instalamos ADB & Fastboot:

                          

Y con esto ya habremos instalado las herramientas necesarias para compilar esta ROM.

*ADB lo configuraremos posteriormente*


2. Crear Directorio de Trabajo

Ahora crearemos la carpeta donde descargaremos las sources de Miui. Para ello ejecutamos en Terminal:

                                        

Con ello crearemos la carpeta de trabajo. Ahora nos situamos en ella:

                                        

Con esto ya habremos creado la carpeta de trabajo y nos habremos situado en ella en Terminal.


3. Descargar las Sources

En este paso inicializaremos los archivos de código abierto de la ROM que vayamos a compilar, en este caso Miui v6, y las sincronizaremos a nuestra carpeta de trabajo. Para este paso es necesario el binario repo que ya instalamos al inicializar el entorno de trabajo.
Estando situados en la carpeta "patchrom", ejecutamos el siguiente comando:

                         

Si todo ha ido bien, se iniciará tu repositorio local usando las sources de MIUI v6. Para asegurarse de que se ha descargado, vete a la carpeta patchrom con el explorador de archivos, y pulsa Ctrl+h y deberá aparecer una carpeta llamada ".repo"
Al finalizar la descarga, Terminal dirá que tienes que registrarte con una cuenta de GitHub. Id a su página oficial y os creáis una cuenta. Una vez creada y comprobada por correo, volver a Terminal y ejecutáis estos dos comandos por separado:
    
                                      
*Reemplaza "tu@correo.com" y "Tu Nombre" por los que hayas usado al crear la cuenta. Ojo, sin las comillas pero con el espacio después de "user.email" y "user.name" respectivamente*

Una vez registrado recomiendo ejecutar otra vez el comando de descarga de sources y veréis que os aparecerá que estáis identificados al terminar el proceso. Por otro lado, cuando el Terminal os pida si queréis visualización de colores en vuestra cuenta (Enable colour display) escribe una N y le dais a enter.

Hecho esto ya tendremos nuestra carpeta de trabajo lista para obtener las sources de la ROM con la que vamos a trabajar.


4. Sincronizar Repositorio

Como sabéis, en este paso se descargarán todos los archivos necesarios del repositorio de la ROM con la que vayamos a trabajar. Lo bueno de Miui es que sus sources pesan menos de la mitad que las de otras ROMs, por lo que no tardará más de dos horas en sincronizar.
Para sincronizar los repositorios ejecutamos (Estando situados en "patchrom" con Terminal"):

                                           

El # indica el número de trabajos que se usarán para descargar los archivos. Depende de tu velocidad de Internet cuánto ponerle. Yo recomiendo usar de 2 a 4. Por lo tanto, si usas dos el comando quedaría así: repo sync -j2

Tras ejecutar el comando empezará la descarga. Cuando termine la sincronización, ya tendremos las sources en nuestra carpeta de trabajo.


5. Preparar Dispositivo 

En esta parte lo que haremos será preparar nuestro dispositivo (móvil, tablet) para que el PC extraiga los archivos necesarios para compilar Miui. Lo primero de todo será saber qué condiciones debe tener nuestro dispositivo:

Recovery-ROM

Lo primero será aclarar dos conceptos: ROM y Recovery-ROM. Cuando nos referimos a "Recovery-ROM", hablamos sobre una ROM que es flashebale (que se instala) mediante el modo recovery de tu dispositivo (CWM/TWRP). Es un archivo comprimido (zip) que contiene todos los archivos de sistema que serán instalados.
Y por otro lado, una ROM es aquel archivo que se instala en tu dispositivo para actualizar el sistema, y su método de instalación varía. Por ejemplo, las Stock ROMs de los Samsung vienen en formato ".tar" y se instalan por medio de un programa de ordenador llamado "Odin".

Teniendo esto claro, hay que saber que al compilar Miui se creará una Recovery-ROM, por lo que sobra decir que tu dispositivo necesita acceso a modo recovery, además de tener instalado un Custom Recovery como ClockWorkMod o TeamWinRecoveryProject.


Elegir una ROM Adecuada

Como he dicho, para compilar Miui tendremos que extraer los archivos necesarios desde nuestro dispositivo. Por ello, necesitamos tener instalada una ROM adecuada para la versión de Miui que vayamos a compilar. Para elegir bien tu ROM base, debes tener en cuenta la siguiente:

  • Versión de Android: Si vamos a compilar Miui v6 (Android KitKat), deberemos estar en una ROM que tenga Android 4.4.x. Es decir, debemos estar en la misma versión Android que vayamos a compilar, o con diferencia mínima.
  • ROM: Se recomienda estar usando la Stock ROM (la que viene por defecto) ya que es la más estable. Sin embargo, se puede usar CyanogenMod u otra ROM, recomendando que sea estable. En mi caso, usaré CyanogenMod 11 de base ya que en mi Ace 3 la Stock ROM trae Android 4.2.2.
  • Root: Debemos tener rooteado el dispositivo. Hay dos tipos de root: privilegio root y kernel root. El primero es mediante una app (Superuser) que maneja el acceso root. El segundo, es root que viene por defecto en el kernel; este tipo de root es más recomendable. Por ejemplo, CyanogenMod ya trae root en el kernel; mientras que si usas OmniRom (por ejemplo) la deberás rootear.
  • Recovery: Como dije antes, necesitas que tu dispositivo tenga acceso a un custom recovery.
Si cumplimos todos los requisitos, estaremos listos para el siguiente paso.

*Recomendación: Usad siempre que podáis CyanogenMod de base. Si usáis por ejemplo una Stock ROM tendréis que seguir antes este tutorial*

*CONSEJO: Recomiendo que para cuando vayamos a extraer los archivos, tengamos la ROM que usaremos de base recién instalada y limpia.*


6. Crear ROM Base

Si miras dentro de la carpeta "patchrom" verás varias carpetas, y una de ellas se llama "nexus5". Esa carpeta contiene los archivos necesarios para compilar Miui v6 para el Nexus 5. Pues en este paso, crearemos la misma carpeta pero para nuestro dispositivo. Para ello haremos en Terminal:

                                         
                                         
*Sustituimos  "codename" por el correspondiente a nuestro dispositivo. Recuerdo que lo podemos ver en la línea "ro.product.name" en el Build.prop de tu dispositivo*

Creada la carpeta nos situamos en ella:

                                         

Ahora iniciaremos una herramienta que generará automáticamente una recovery-ROM desde nuestro dispositivo. Te preguntarás por qué debemos hacer este paso si ya hemos encontrado una recovery-ROM para nuestro dispositivo y es adecuada para compilar. Hay dos razones:

  • La mayoría de Stock ROMs no vienen en formato recovery-ROM, así que si actualmente estás en una Stock, tendrás que usar esta herramienta.
  • Usar esta función es vital para  generar automáticamente la Miui recovery-ROM y su versión OTA, que hace a Miui tan especial.
Para que el programa extraiga los archivos, deberemos asegurarnos de configurar bien el Android Debug Bridge (ADB). Para ello:

Primero ejecutaremos un comando en Terminal para que el PC reconozca los dispositivos conectados:

                                                           
Verás algo así:

                           

Ahora deberás identificar tu dispositivo. En mi caso, será el último que aparece. Tendremos que quedarnos con los dos códigos que aparecen después de ID (04e8 y 685e) ya que son los identificadores del vendor y product para tu dispositivo.
Ahora ejecutaremos lo siguiente el Terminal:

                                        

Se abrirá un archivo de texto. Añadiremos la siguiente línea:

                     
*Es una sola línea; no me cabe entera*

Sustituimos los ID por los correspondientes a tu dispositivo. Guardamos los cambios y cerramos. Seguidamente ejecuta en Terminal:

                                     
Y luego:

                                             

Y reconectamos nuestro dispositivo. Asegúrate de que tiene habilitada la opción "Depuración USB" en ajustes del teléfono.

Ahora reiniciaremos nuestro dispositivo en modo recovery. Puedes hacerlo manualmente o con este comando:

                                            

Ahora nos dirigimos al directorio de trabajo con Terminal:

                                            

Y ejecutamos la herramienta de extracción de archivos:

                                           
*Si ese comando no funciona prueba con "../tools/releasetools/ota_target_from_phone -r"*

Al terminar se habrá creado un "stockrom.zip" y un directorio "metadata" en la carpeta de nuestro dispositivo, que serán usadas para compilar Miui v6. Ya habremos creado la ROM base.

*Si usáis una ROM que ya esté en formato zip, puedes saltarte este paso de extraer la ROM desde el dispositivo Entonces tienes que extraer la carpeta "system" y el "boot.img" del zip de la ROM que vayas a usar de base, y lo copias en la ruta /patchrom/codename/stockrom (creamos la carpeta). Luego sigue con los pasos de abajo*

7. Compilar ROM

Llegamos al "último" paso de este tutorial. Lo primero que haremos será crear un "makefile" que especificará varios parámetros necesarios para compilar.
Podrás encontrar el archivo en la carpeta "nexus5" dentro de patchrom. Cópialo en la carpeta de tu dispositivo, ábrelo con Gedit y borra todo lo que aparezca (es mejor hacerlo de cero).
La estructura que seguiremos para ese archivo será la siguiente:




Para adaptarlo a nuestro dispositivo lo primero que haremos será cambiar "codename" por el correspondiente a nuestro dispositivo.
Luego habrá que añadir valores a los parámetros. Significan lo siguiente:

  • local-zip-file: nombre del zip extraído como rom base. Si no has editado el nombre, será "stockrom.zip"
  • local-out-zip-file: nombre que tendrá el archivo zip al terminar de compilar la ROM. Recomiendo dejarlo como aparece arriba cambiando el codename.
  • local-modified-apps: aquí especificamos las apps de la ROM original que hayamos modificado. Si no has modificado ninguna, la dejamos en blanco.
  • local-modified-jars: lo mismo que la línea de arriba, pero con archivos ".jar" en vez de ".apk"
  • local-miui-removed-apps: especificamos apps de Miui que no queramos incluir en la ROM final porque no son compatibles. Recomiendo dejarlo la primera vez en blanco, y al haber compilado ya la ROM e instalarla, sabrás qué apps poner porque darán forzar cierre.
  • local-miui-modified-apps: todas las apps de Miui aparecén listadas en el archivo patchrom/build/miuiapps.mk. Si hemos modificado alguna, la especificamos.
  • local-phone-apps: esta variable define qué apps de la ROM base queremos mantener en la ROM final. Por ejemplo, si la cámara nativa de Miui da forzar cierre, la ponemos en miui-removed-apps y añadiríamos en esta línea la cámara de la ROM base.
  • local-phone-priv-apps: lo mismo que la línea de arriba, pero con aquellas apps que en la ROM base estuvieran en system/priv-app y no en system/app.
  • local-density: la densidad/resolución de tu pantalla (MDPI. HDPI, XHDPI, o XXHDPI)
  • local-pre-zip: define la inclusión de local-zip-misc. Es decir, deja la línea como en el ejemplo.
  • local-after-zip: lo dejamos en blanco (o no la ponemos). Tampoco sé para qué sirve.
  • local-zip-misc: este comando te permite definir modificaciones locales a incluir en la build. Por ejemplo, incluir apps de Google o un build.prop modificado. En mi caso la he dejado en blanco.
Para mi Galaxy Ace 3 (loganreltexx) hice un makefile así:




*Como he dicho, necesitarás probar la ROM primero para saber qué incluir en varias de las líneas*
*Recomiendo la primera vez dejar las líneas de apps a incluir y eliminar en blanco, y así al probar la build veremos qué apps no funcionan, cuáles faltan, etc*


Una vez creado el archivo y guardado, habremos hecho una parte complicada del trabajo. Ahora ejecutamos lo siguiente en Terminal:
*Debemos estar situados en la carpeta "patchrom/codename"*

                                         

Al finalizar habrá extraído framework/android.policy/services.jar y framework-res.apk del stockrom.zip y los habrá desmontado.
A continuación usaremos este comando:

                                        


*Si en algún momento mientras el Terminal parchea te encuentras con esto:

                  
Solo debes escribir una "y" (sin las comillas) y darle a enter*


Con esto lo que haremos será transformar el código de nuestra ROM base a código de Miui.
Hay tres directorios de código smali involucrados:

  • old framework.jar.out
  • new framework.jar.out
  • target framework.jar.out
En principio, el "old framework" será el framework.jar desmontado que se compila desde el código fuente lanzado por Google. El "new framework" será el framework.jar desmontado que se compila desde el código fuente de MIUI. Y por último, el "target framework" será el framework.jar desmontado de nuestro dispositivo que ya está preparado cuando hicimos "make workspace".

Con el fin de facilitar este proceso , tratamos de hacer cambios mínimos en el código fuente de Google . Puedes ver estos cambios al comparar miui/src y android/src. Sin embargo, a menuda habrán conflictos al aplicar los parches.

Al ejecutar  el comando "make firstpatch" se habrán creado 5 sub-carpetas temporales. Serán los siguientes:

  • old_smali : el código smali del "old framework" con la .línea eliminada.
  • new_smali : . el código smali del "new framework" con la .línea eliminada.
  • dst_smali_orig : . el código smali del "target framewrok" con la .línea eliminada.
  • dst_smali_patched : el código smali después de aplicar el parche al "target framework" con la línea eliminada.
  • reject : el parche rechazado. Utilizaremos este directorio para resolver los posibles conflictos.
*Recomendación: en principio no hagas nada en reject. Si al compilar la ROM funciona, perfecto. Si no compila, ya nos meteríamos a aplicar los parches*

Para solucionar los rejects, sigue este tutorial aparte.

Y por último de todo, compilamos la ROM final Miui v6:

                                            

Seguramente tendrás errores al compilar. Intentaré publicar todos los que encuentre, pero siéntete libre de comentar tu problema y trataré de ayudar.
Al terminar, tendrás un archivo zip en el directorio patchrom/out con el nombre que le hayas dado al archivo en el makefile.

Ahora solo tendrás que instalar por CWM/TWRP. Si no arranca, haz LogCat y así podrás ver qué falla y lo podrás solucionar con parches.


¡Listo! Has Compilado MIUI v6



8. Errores al Compilar

Como dije, agrego aquí la solución a los errores que te puedes encontrar al hacer "make fullota":


Error con Reject

Puede que a la hora de compilar te encuentres con algo así:



Este error se debe a que has parcheado mal un reject. Debes ir al archivo que indica el Terminal, en este caso sería el archivo GSMPhone.smali que se encuentra en telephony-common.jar.
Una vez abierto el archivo, localizamos su correspondiente reject y corregimos el parche aplicado.


Error de Values


Un error muy común, cuya solución es realmente simple, pero complicada de averiguar si no la conoces. En Terminal obtendrás un error así:




Para solucionarlo, debemos ir a la carpeta "metadata" dentro del directorio raíz de nuestro dispositivo (patchrom/codename/metadata) y abrir un archivo llamado "filesystem_config.txt".

Dentro de él encontraremos una gran variedad de líneas. Lo que hay que hacer es borrar la primera línea que aparece, llamada "Segmentation fault" y no dejar espacios en blanco. También asegurarse que en el resto del archivo todas las líneas estén juntas, es decir, sin líneas en blanco.

Al terminar se guardan los cambios y listo!


Y esos son todos los errores que me encontré. Si sufres alguno más, no dudes en comentarlo.


6 comentarios:

  1. Hola Buenas me sale este error:alguna idea?

    >>> build out/services.jar...
    /home/paloda/patchrom/tools/overlay_smali.sh >/dev/null out/services /home/paloda/patchrom/android/overlay
    /home/paloda/patchrom/tools/add_miui_smail.sh >/dev/null out/services_miui out/services
    /home/paloda/patchrom/tools/apktool --quiet b out/services -o out/services.jar
    Exception in thread "main" java.lang.IllegalStateException: Cannot get the location of a label that hasn't been placed yet.
    at org.jf.dexlib2.builder.Label.getLocation(Label.java:54)
    at org.jf.dexlib2.builder.Label.getCodeAddress(Label.java:48)
    at org.jf.dexlib2.builder.BuilderOffsetInstruction.internalGetCodeOffset(BuilderOffsetInstruction.java:60)
    at org.jf.dexlib2.builder.BuilderOffsetInstruction.getCodeOffset(BuilderOffsetInstruction.java:50)
    at org.jf.dexlib2.writer.InstructionWriter.write(InstructionWriter.java:189)
    at org.jf.dexlib2.writer.DexWriter.writeCodeItem(DexWriter.java:954)
    at org.jf.dexlib2.writer.DexWriter.writeDebugAndCodeItems(DexWriter.java:769)
    at org.jf.dexlib2.writer.DexWriter.writeTo(DexWriter.java:222)
    at org.jf.dexlib2.writer.DexWriter.writeTo(DexWriter.java:200)
    at brut.androlib.src.SmaliBuilder.build(SmaliBuilder.java:57)
    at brut.androlib.src.SmaliBuilder.build(SmaliBuilder.java:41)
    at brut.androlib.Androlib.buildSourcesSmali(Androlib.java:354)
    at brut.androlib.Androlib.buildSources(Androlib.java:294)
    at brut.androlib.Androlib.build(Androlib.java:280)
    at brut.androlib.Androlib.build(Androlib.java:255)
    at brut.apktool.Main.cmdBuild(Main.java:225)
    at brut.apktool.Main.main(Main.java:84)
    make: *** [out/services.jar] Error 1

    ResponderEliminar
    Respuestas
    1. El error indica que no encuentra líneas, así que debes definirlas. Te recomiendo comenzar de cero el parcheo.

      Eliminar
  2. Al momento de compilar me encuentro con este error :/

    out/services/smali/com/android/server/pm/PackageManagerService.smali[22172,4] There is already a label with that name.
    Exception in thread "main" brut.androlib.AndrolibException: Could not smali file: com/android/server/pm/PackageManagerService.smali
    at brut.androlib.src.SmaliBuilder.buildFile(SmaliBuilder.java:71)
    at brut.androlib.src.SmaliBuilder.build(SmaliBuilder.java:55)
    at brut.androlib.src.SmaliBuilder.build(SmaliBuilder.java:41)
    at brut.androlib.Androlib.buildSourcesSmali(Androlib.java:354)
    at brut.androlib.Androlib.buildSources(Androlib.java:294)
    at brut.androlib.Androlib.build(Androlib.java:280)
    at brut.androlib.Androlib.build(Androlib.java:255)
    at brut.apktool.Main.cmdBuild(Main.java:225)
    at brut.apktool.Main.main(Main.java:84)
    make: *** [out/services.jar] Error 1

    ResponderEliminar
    Respuestas
    1. En este post mío en XDA explico cómo solucionar ese tipo de error:
      http://forum.xda-developers.com/showpost.php?p=62854395&postcount=3

      Eliminar
  3. makefile:40: /porting.mk: No existe el archivo o el directorio
    make: *** No hay ninguna regla para construir el objetivo '/porting.mk'. Alto.
    me aparece ese error que hago

    ResponderEliminar
    Respuestas
    1. Has hecho algo mal a la hora del entorno de trabajo o al ejecutar el comando en Terminal no te has situado dentro de la carpeta con el comando cd.

      Eliminar