Compilar Android Cupcake (1.5) en Ubuntu Karmic (10.9)
Contents
-
Compilar Android Cupcake (1.5) en Ubuntu Karmic (10.9)
- Introducción
- Resumen de alto nivel
- Antes de compilar
- Descarga de Cupcake
- Compilando Android 2.2 (Froyo)
- Compilando Android 2.2 (Froyo) para x86
- Manejando el entorno de compilación
- ¿Qué hacer ahora?
- Compilando el núcleo y drivers en Android
- Soporte wifi en Android
- Instalando Android + núcleo en el emulador
- Instalando todo en un teléfono real
- Otros proyectos
Introducción
Android es una plataforma extensa y el proceso de compilación es complejo. Está muy probado así que lo normal es que estemos en la plataforma que estemos, encontraremos experiencias sobre que tocar para que toco compile bien.
En esta página nos referiremos a Ubuntu Karmic y a la rama Cupcake (1.5) de Android, y según el tiempo lo permita, iremos incluyendo otros entornos si los necesitamos.
Instrucciones básicas de Android: Lee esta página con cuidado y te ahorrarás mucho tiempo.
Como arranca y las particiones de Android | Explicando los *.img
Resumen de alto nivel
Una ROM de Android es una distro de Linux compilada desde cero. Muy similar a Linux From Scratch. En el proceso para Cyanogen se crean todo el sistema completo, incluyendo el sistema de recuperación (recovery.img), el sistema de arranque (núcleo + ramdisk, boot.img) y el sistema base con las aplicaciones (system.img).
En la compilación de la plataforma se incluyes pues:
- userdata.img: Datos iniciales de usuario
- boot.img: Núcleo de arranque
- system.img: Sistema base con todas las aplicaciones
- recovery.img: Sistema de recuperación ante fallos
Para compilar necesitamos Java y gcc y g++. El proceso de compilación es largo y necesitamos bastante disco duro (10 GB). Además, necesitamos el móvil destino para poder extraer de él algunos ficheros binarios como los drivers de la parte de radio.
Una vez acabado el proceso deberemos de juntar todo en un fichero de actualización, "update.zip", para poder instalarlo de forma cómoda sobre el móvil. También podríamos hacer paso a paso con fastboot.
Antes de compilar
- Instalar JDK 1.5
- Instalar y configurar gcc 4.3 y g++ 4.3
Tengo aún por probar si ya funciona con JDK6 ya que 1.5 ya no tiene ni soporte. En tiempo de compilación se comprueba y es necesario JDK 1.5. Así se instalar en Ubuntu posterior a jaunty.
Descarga de Cupcake
Es recomendable manejarnos bien con git.
Instalar el binario "repo" de Android
$ mkdir cupcake $ cd cupcake $ repo init -u git://android.git.kernel.org/platform/manifest.git -b cupcake $ repo sync $ make
Con esto lo que hemos hecho es bajarnos el repositorio entero y luego irnos a la rama cupcake. Dentro de este mismo repositorio podemos saltar a otras ramas. Por ejemplo, si quisiéramos irnos a Android 2.0 saltaríamos a eclair con:
$ repo sync $ repo init -u git://android.git.kernel.org/platform/manifest.git -b eclair
Tras descargar todos los ficheros, son 2.1 GB aprox, comenzará el proceso de compilación.
Una vez completado el proceso nos genera los ficheros:
tree -L 1 out/target/product/generic/ out/target/product/generic/ |-- android-info.txt |-- clean_steps.mk |-- data |-- installed-files.txt |-- obj |-- previous_build_config.mk |-- ramdisk.img |-- root |-- symbols |-- system |-- system.img `-- userdata.img
Tenemos tres ficheros "img" que serán los que hay que utilizar para crear el sistema.
Compilando Android 2.2 (Froyo)
El proceso para compilar Android 2.2, aka Froyo, es idéntico y se terminan generando los ficheros
find . -name "*.img" ./out/target/product/generic/userdata.img ./out/target/product/generic/ramdisk.img ./out/target/product/generic/system.img
Compilando Android 2.2 (Froyo) para x86
Existe un proyecto donde preparan Android para ser ejecutado en plataformas x86, algo que es natural ya que es la arquitectura más habitual en GNU/Linux. En dicho proyecto lo que hacen es generar a partir del núcleo y fuentes del sistema Android una ISO en CD desde la que poder ejecutar en modo "live" el sistema en una plataforma x86, o donde poder instalarla. También se puede generar una imagen para ser usada desde USB.
export PATH=$PATH:/sbin (para que encuentre tune2fs) sudo apt-get install genisoimage acs@macitong:~/devel/android/x86$ repo init -u git://android-x86.git.sf.net/gitroot/android-x86/manifest.git -b froyo-x86 Getting repo ... from git://android.git.kernel.org/tools/repo.git remote: Counting objects: 1090, done. .... From git://android-x86.git.sf.net/gitroot/android-x86/manifest * [new branch] donut-x86 -> origin/donut-x86 * [new branch] eclair-x86 -> origin/eclair-x86 * [new branch] froyo-x86 -> origin/froyo-x86 * [new branch] master -> origin/master .... acs@macitong:~/devel/android/x86$ repo sync Initializing project platform/bionic ... remote: Counting objects: 5350, done ... make iso_img TARGET_PRODUCT=generic_x86 ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=2.2 TARGET_PRODUCT=generic_x86 TARGET_BUILD_VARIANT=eng TARGET_SIMULATOR= TARGET_BUILD_TYPE=release TARGET_BUILD_APPS= TARGET_ARCH=x86 HOST_ARCH=x86 HOST_OS=linux HOST_BUILD_TYPE=release BUILD_ID=MASTER ============================================ Checking build tools versions... ... 292592 extents written (571 MB) ls -l out/target/product/generic_x86/generic_x86.iso -rw-r--r-- 1 acs acs 599228416 ago 9 22:28 out/target/product/generic_x86/generic_x86.is make usb_img TARGET_PRODUCT=generic_x86 I/diskutils( 9648): Wrote 620490752 bytes to out/target/product/generic_x86/generic_x86_usb.img @ 1048576 File edit complete. Wrote 1 images.
Ya tenemos tanto una ISO como un sistema USB autoarrancable con android 2.2 para x86.
Si queremos probar todo en una máquina virtual, nos hacemos una ISO pero con una imagen preparada para máquina virtual, donde le ratón debe de ser el puntero y no la pantalla táctil:
make iso_img TARGET_PRODUCT=vm ls -l out/target/product/vm/vm.iso -rw-r--r-- 1 acs acs 572549120 ago 10 00:55 out/target/product/vm/vm.iso
Luego nos creamos una nueva máquina virtual en virtual box y ponemos esta ISO como dentro del CD de dicha máquina, arrancamos y podemos probar en modo "live" o instalar android 2.2 en ella.
Vamos a meter en un llavero USB la imagen USB autoarracanble. Para ello metemos un llavero USB de 1GB (sin datos importantes) en el ordenador con dicha imagen y ejecutamos:
dd if=devel/android/x86/generic_x86_usb.img of=/dev/sdb 1213944+0 registros de entrada 1213944+0 registros de salida 621539328 bytes (622 MB) copiados, 280,915 s, 2,2 MB/s
Luego arrancamos desde USB y ya procedemos con el proceso de Instalación.
Manejando el entorno de compilación
La compilación de Android es un proceso bastante lento. Si realizamos cambios nos gustaría lograr que fuera incremental. Vamos a realizar un estudio de esto:
¿Qué hacer ahora?
Ya somos capaces de compilar la plataforma Android, pero por ejemplo, no incluye el núcleo, a diferencia de cyanogen donde aún se incluye.
Si tenemos un HTC Magic o Dream en la propia web de Android o en este artículo nos indican los próximos pasos a dar. Vamos a ir de tener el sistema genérico con sus aplicaciones a la parte de hardware. Esto es ya lo que les toca hacer a los diferentes fabricantes para asegurarse de que Android funciona en su hardware.
Compilando el núcleo y drivers en Android
Vamos a centrarnos en el HTC Magic (Saphire) que rooteado pasa a ser un Google IO. Aquí tenemos unas buenas instrucciones de HTC para jugar con él. Lo que hay que hacer es meter un núcleo y drivers necesario para manejar todo el hardware del HTC.
Los núcleos de Android de Qualcomm MSM7xxx chipsets los podemos obtener del repositorio git. De momento nos vamos a centrar en esta plataforma. Para bajarnos los núcleos:
cd kernel/ git clone git://android.git.kernel.org/kernel/msm.git Initialized empty Git repository in /home/acs/devel/android/kernel/msm/.git/ remote: Counting objects: 1391835, done. ... kernel/msm$ git checkout -b -t android-msm-2.6.32 origin/android-msm-2.6.32 Checking out files: 100% (26417/26417), done. Branch android-msm-2.6.32 set up to track remote branch android-msm-2.6.32 from origin. Switched to a new branch 'android-msm-2.6.32'
Una vez descargado los núcleos nos tenemos que ir a la rama que queremos compilar, en este caso la 2.6.32. El objetivo es tener este núcleo compilado para el HTC Nexus One.
Hay información sobre Android en el directorio doc del kernel.
Hay que hacer "cross compiling". Dentro de "cupcake" tenemos el entorno de compilación cruzada en:
prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/ prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/
pero estas versiones son demasiado antiguas. Nos podemos bajar del repo de android la versión 4.4 que sí que funciona.
Con añadir al PATH la versión que queramos será suficiente.
export PATH=$PATH:/home/acs/devel/android/cupcake/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/
Antes de comenzar a compilar el núcleo cogemos el fichero de configuración del propio terminal HTC Nexus One:
adb pull /proc/config.gz /tmp 112 KB/s (9314 bytes in 0.080s) ... kernel/msm$ gunzip /tmp/config.gz
aunque es para la versión: "# Linux kernel version: 2.6.29" y bastante reciente "# Wed Jan 20 10:23:49 2010".
Este fichero de configuración es el que tenemos que copiar como ".config" al directorio principal de las fuentes del núcleo.
Luego, a la hora de compilar el núcleo, ejecutamos:
kernel/msm$ ARCH=arm CROSS_COMPILE=arm-eabi- make zImage ... scripts/kconfig/conf -s arch/arm/Kconfig * * Restart config... * * * RCU Subsystem * RCU Implementation > 1. Tree-based hierarchical RCU (TREE_RCU) 2. Preemptable tree-based hierarchical RCU (TREE_PREEMPT_RCU) (NEW) choice[1-2]: ...
Nos pregunta las opciones nuevas entre 2.6.29 y 2.6.32. Dejamos las opciones por defecto. Una vez configurado el núcleo comienza la compilación y todo termina bien con:
... LD vmlinux.o MODPOST vmlinux.o GEN .version CHK include/linux/compile.h UPD include/linux/compile.h CC init/version.o LD init/built-in.o LD .tmp_vmlinux1 KSYM .tmp_kallsyms1.S AS .tmp_kallsyms1.o LD .tmp_vmlinux2 KSYM .tmp_kallsyms2.S AS .tmp_kallsyms2.o LD vmlinux SYSMAP System.map SYSMAP .tmp_System.map OBJCOPY arch/arm/boot/Image Kernel: arch/arm/boot/Image is ready .... Kernel: arch/arm/boot/zImage is ready Building modules, stage 2. MODPOST 1 modules CC drivers/net/wireless/bcm4329/bcm4329.mod.o LD [M] drivers/net/wireless/bcm4329/bcm4329.ko
Ahora tenemos que crear la imagen que nos permita seleccionarlo para iniciar con este núcleo desde el móvil.
Una vez compilado el núcleo, si queremos arrancar con la nueva imagen podemos utilizar "fastboot":
root@rayito:/home/acs/devel/android/kernel/msm# fastboot boot arch/arm/boot/zImage creating boot image... creating boot image - 2000896 bytes downloading 'boot.img'... OKAY booting... OKAY
Y con esto se iniciará el sistema en Android utilizando este núcleo que acabamos de compilar.
Todo parece haber funcionado. Comprobemos que tenemos dentro del móvil:
adb pull /proc/config.gz /tmp * daemon not running. starting it now * * daemon started successfully * error: device not found
Veamos si somos capaces de ver dentro del dispositivo el núcleo que tiene funcionando ...
2.6.32-26379-gadab5b4 acs@rayito #1
Claramente este es el núcleo que acabo de compilar así que todo ha funcionado de forma correcta!
Tras unas pruebas funcionales:
- Funciona la recepción de llamadas.
- NO funciona la cámara.
- NO funciona wifi
- El bluetooth SÍ se activa y es capaz de buscar dispositivos
- El sonido SÍ funciona
Bueno, nos tocará terminar de ajustar algunas cosas de módulos adicionales para que funcione todo, pero creo que el camino está bastante despejado. Puede que añadiendo ramdisk.img se solucionen estos problemas.
http://wiki.acsblog.es/acswiki/CompilarAndroid?action=AttachFile&do=view&target=P1010094.JPG
En realidad como hemos sabido posteriormente, utilizando el método de inicio con "fastboot" no funciona la carga de módulos e incluso la wifi metida dentro del núcleo, tampoco. La solución es crear un boot.img con el nuevo núcleo y flashearlo.
Soporte wifi en Android
El soporte wifi en Android requiere de algunas cosas específicas de Android.
Instalando Android + núcleo en el emulador
Instalando todo en un teléfono real
Otros proyectos
http://labs.embinux.org/index.php/Introduction (Toolchain)