ROM de Cyanogen
Contents
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
- Dentro de boot.img está el núcleo y ramdisk de arranque.
- Dentro de META-INF está la firma de todos los ficheros a actualizar y los scripts de actualización
tree META-INF/ META-INF/ |-- CERT.RSA |-- CERT.SF |-- com | |-- android | | `-- metadata | `-- google | `-- android | |-- update-binary | `-- updater-script `-- MANIFEST.MF
- Dentro de "system" están todos los ficheros a ser copiados al directorio "/system" de android.
El núcleo de Cyanogen
- Lleva activada la carga de módulos: la wifi (bcm4329 o wlan) va como módulo.
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.