ROM de Cyanogen

Introducción

Nos hemos volcado con Cyanogen por ser el proyecto más maduro a la hora de crear una ROM (distro) totalmente libre para Android. Ya hemos documentos algunos aspectos del proceso en como compilar Android pero esto es ya un caso práctico con Cyanogen, N1 y su instalación,

La ROM

Instalación de la ROM

Las ROMs de cyanogen se distribuyen como ficheros "update.zip" que incluyen un sistema de instalación muy básico.

La estructura de estos ficheros "update.zip" es:

mkdir cm6
cd cm6
unzip ../update-cm-6.0.0-N1-RC1-signed.zip
tree -L 1 .
.
|-- boot.img
|-- META-INF
`-- system

tree META-INF/
META-INF/
|-- CERT.RSA
|-- CERT.SF
|-- com
|   |-- android
|   |   `-- metadata
|   `-- google
|       `-- android
|           |-- update-binary
|           `-- updater-script
`-- MANIFEST.MF

El núcleo de Cyanogen

Ahora mismo tenemos el problema de que en los núcleos creados por nosotros desde las fuentes de cyanogen no funciona la carga de módulos.

Vamos a trabajar con el boot.img que viene en la ROM, lo vamos a modificar para cambiarle el núcleo y vamos a probarlo.

ls -l boot.img 
-rw-r--r-- 1 acs acs 2390016 2008-02-28 21:33 boot.img

Este fichero de arranque para dispositivos empotrados hay que manejarlo según nos indican en este howto de Android-DLs. Vamos a utilizar los scripts que nos proporcionan que nos ahorran el trabajo:

mkdir bootimage
cd bootimage/
split_bootimg.pl ../boot.img
Page size: 2048 (0x00000800)
Kernel size: 2218240 (0x0021d900)
Ramdisk size: 166370 (0x000289e2)
Second size: 0 (0x00000000)
Board name: 
Command line: no_console_suspend=1 msmsdcc_sdioirq=1 wire.search_count=5
Writing boot.img-kernel ... complete.
Writing boot.img-ramdisk.gz ... complete.
acs@rayito:~/devel/android/cyanogen/cm6/bootimage$ ls
boot.img-kernel  boot.img-ramdisk.gz

Como resultado tenemos el núcleo, "boot.img-kernel", y su ramdisk asociado "boot.img-ramdisk.gz".

Si queremos cambiar el núcleo, tendremos que cambiar tanto el núcleo en sí, como los módulos de dicho núcleo. El próximo paso es trabajar con el "ramdisk".

mkdir new-ramdisk
cd new-ramdisk/
gzip -dc ../boot.img-ramdisk.gz | cpio -i
tree 
.
|-- data
|-- default.prop
|-- dev
|-- init
|-- init.goldfish.rc
|-- init.mahimahi.rc
|-- init.rc
|-- proc
|-- sbin
|   `-- adbd
|-- sys
`-- system

Vemos que en este ramdisk no están los módulos, ya que no se necesitan para acceder al sistema de ficheros definitivo, donde ya sí que estarán. No nos hace falta por lo tanto tocar nada de aquí.

Por lo tanto, vamos a copiar el nuevo núcleo y a rehacer "boot.img":

cp ~/devel/android/kernel/cm-kernel/arch/arm/boot/zImage boot.img-kernel
cd ..
mkbootimg --base 0x20000000 --cmdline 'no_console_suspend=1 console=null' --kernel boot.img-kernel --ramdisk boot.img-ramdisk.gz -o boot-new.img
ls -l boot-new.img 
-rw-r--r-- 1 acs acs 2385920 2010-07-22 18:45 boot-new.img

Nos dicen que usemos "--base 0x20000000" para el Nexus One pero no funciona con el mkbootimg de cupcake.

Hay que bajarse el mkbootimg de froyo y compilarlo (gcc mkbootimg.c -o mkbootimg -I/home/acs/devel/android/cupcake/system/core/include -L/home/acs/devel/android/cupcake/out/host/linux-x86/obj/STATIC_LIBRARIES/libmincrypt_intermediates/libmincrypt.a). Sin la opción de "--base" no funciona en N1.

Y llega el momento de cambiar el "boot" del sistema grabando este nuevo. Para ello vamos a iniciar en modo fastboot el teléfono y ejecutamos el comando:

sudo fastboot flash boot boot-new.img

Ahora reiniciamos el móvil y debería de iniciar con el nuevo arranque, que incluye el nuevo núcleo.

Si no funciona, que no cunda el pánico. Volvemos a instalar el boot.img original utilizando "fastboot" y listo.

sudo fastboot flash boot ../boot.img

Pruebas rápidas de núcleos

Si queremos evitar tener que hacer el "boot.img" y grabarlo podemos hacer una prueba de iniciar sólo una vez con el nuevo núcleo.

Para ello en modo "fastboot" del móvil ejecutamos:

sudo fastboot boot boot.img-kernel

Probando núcleos de esta forma no funciona la carga de módulos por lo que por ejemplo, la wifi no funciona al ester como módulos.

El sistema completo

Una vez que ya sabemos como crear nosotros un núcleo y arranque personalizados, pasemos ya al resto del sistema. En general serán aplicaciones Java que funcionan sobre la máquina virtual y están en el directorio "/system", aunque hay partes de bajo nivel como la máquina virtual en sí (dalvik) y algunas librerías que están en C.

Obteniendo el código fuente de la plataforma

El primer paso es obtener todo el código fuente de la plataforma. En Cyanogen se hace de forma parecida a como se hace para Android, utilizamos la herramienta repo para bajar todo el código fuente:

mkdir cm-froyo
cd cm-froyo/
repo init -u git://github.com/CyanogenMod/android.git -b froyo
repo sync
....
Syncing work tree: 100% (178/178), done.

Tarda un buen rato en bajar todo el código fuente de la plataforma.

du -sh *
14M     bionic
4,7M    bootable
4,1M    build
97M     dalvik
39M     development
41M     device
824M    external
303M    frameworks
25M     hardware
468M    kernel-msm
4,0K    Makefile
61M     ndk
110M    packages
824M    prebuilt
14M     sdk
26M     system
32M     vendor

Dentro de Cyanogen aún se mantiene el núcleo, por lo que ocupa más que el entorno de Android que se ha separado. En total, incluyendo el directorio ".repo" de trabajo de git, ocupa:

du -sh .
5,2G
du -sh .repo/
2,3G    .repo/

Compilando la plataforma

Ahora llega el gran momento de compilar toda la plataforma. Para ello ejecutamos:

sudo apt-get install librpc2-dev

cm-froyo$ source build/envsetup.sh

y nos queda seleccionar para que dispositivo vamos a compilar la ROM. En nuestro caso vamos a hacerlo para la N1. Vemos si está disponible con:

sed -n -e "s/^add_lunch_combo//gp" vendor/*/vendorsetup.sh
 cyanogen_passion-eng
 cyanogen_inc-eng
 cyanogen_hero-eng
 cyanogen_sholes-eng
 cyanogen_dream_sapphire-eng
 cyanogen_bravo-eng
 cyanogen_espresso-eng
 cyanogen_supersonic-eng

La N1 es "cyanogen_passion-eng". La principal implicación de esta parte debería de ser a nivel de núcleo ya que la ROM por encima del núcleo, debería de ser muy parecido en todos los casos.

lunch cyanogen_passion-eng

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.2
TARGET_PRODUCT=cyanogen_passion
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=false
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=MASTER
============================================

Vemos de las variables que se definen que son todas bastante genéricas. Finalmente lanzamos el proceso de compilación. Lo mejor es dejar la máquina lo más descargada posible ya que es un proceso bastante largo que necesita de bastantes recursos:

cm-froyo$ make -j2
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.2
....
Checking build tools versions...

La compilación termina de forma correcta pero hay nuevas instrucciones completas de como se debe de realizar todo el proceso. La parte fundamental es poder compilar todo, que ya lo hemos logrado.

cd device/htc/passion
./extract-files.sh 
331 KB/s (30140 bytes in 0.088s)
....
1148 KB/s (292888 bytes in 0.248s)
remote object '/system/lib/libomx_wmvdec_sharedlibrary.so' does not exist
1141 KB/s (140640 bytes in 0.120s)
345 KB/s (18592 bytes in 0.052s)
798 KB/s (116184 bytes in 0.142s)
2 KB/s (183 bytes in 0.078s)

Claramente toda esta parte es lo que hay de privativo en el sistema que estamos creando. Para poder extraerla tenemos que tenerla ya en el móvil. Por eso es recomendable que tengamos en el móvil una versión lo más similar posible a la que estamos compilando. En este caso, tener instalado CM6RC1 en el móvil, que es lo que tenemos.

cd -
cd vendor/cyanogen
./get-rommanager
./get-google-files 
Fetching from http://www.kanged.net/mirror/gapps/gapps-passion-FRF91-signed.zip

Estos dos últimos comandos diría que ponen ya en la ROM la aplicación "Rom Manager", ¿es software libre?, y las aplicaciones privativas de Google.

cd -
source build/envsetup.sh
lunch cyanogen_passion-eng
make -j4 CYANOGEN_WITH_GOOGLE=true otapackage
...
./vendor/cyanogen/tools/squisher

Al acabar ya tenemos todo listo para actualizar nuestra ROM con esta totalmente compilada por nosotros, salvo los ficheros privativos del móvil, y la aplicación ROM Manager y las aplicaciones de Google.

Instalamos el fichero resultante, update-cm-6.0.0-N1-RC2-signed.zip, y todo funciona perfectamente :) Nuestra primera ROM generada desde cero e instalada en el móvil. Excelente noticia.

Queremos una versión libre!

Si queremos que construir una versión 100% libre los directorios a eliminar son:

./vendor/htc/passion/proprietary
./vendor/cyanogen/proprietary

Dentro del directorio "./vendor/htc/passion/proprietary" hay cosas necesarias para que funcione todo el hardware. Esto de momento lo vamos a dejar aunque no es legal su distribución y puede causar problemas. Dentro de "./vendor/cyanogen/proprietary" están las aplicaciones privativas de Google y el ROM Manager. Este directorio lo eliminamos y construimos de nuevo la ROM. Lo más rápido es eliminar las aplicaciones de "target/product/passion/system/app".

Comentamos de ./vendor/cyanogen/products/common.mk el objetivo del Rom Manager y arrancamos:

source build/envsetup.sh
lunch cyanogen_passion-eng
make -j4 otapackage
./vendor/cyanogen/tools/squisher

Y hale, ya tenemos una ROM 99% software libre que podemos distribuir de forma 99% legal :) ¿Qué fabricante será el primero en darnos el código fuente de todo? ¿Quién será el primer Open Hardware Smartphone? Yo haría un esfuerzo por tenerlo.

Foros de Cyanogen

Los foros de Cyanogen son muy activos. Tiene partes cerradas sólo para desarrolladores.

CyanogenMod (last edited 2010-10-06 21:13:03 by AlvaroDelCastillo)