Despues de trastear con el emulador de android y tras mis intentos infructuosos hace un año para portar la versión 1.6 a la Zaurus C3000, principalmente por la imposibilidad de conseguir un kernel 2.6 para la zaurus, voy a intentar ahora hacer que funcione en Virtual Box.

Para hacer esto vamos a seguir las instrucciones de la AOSP que se pueden ver en esta página. Recomiendo utilizar Ubuntu 10.04 LTS para evitar estar viendo warnings cada dos por tres, ya que la versión de gcc recomendada para compilar es la 4.5. Yo comencé a compilar con una Debian Sid, y tuve que cambiar tras haberle configurado el repo y los paquetes.

Tras descargar el repo y hacer ". build\envsetup.sh" podemos ejecutar lunch para elegir en nuestro caso vbox_x86 y si queremos podemos afinar la configuración con choosecombo, donde podemos por ejemplo cambiar de versión eng a user.

Como estoy compilando en una máquina virtual con 2GB de RAM, no merece la pena usar swap ni ccache, ya lo intenté y llega un momento en que el I/O se convierte en un cuello de botella y la compilación se ralentiza. Es mucho mejor lanzar siempre el make con -j1 o -j2 para que haya poco proceso con alto consumo de ram y no haga uso de swap.
Cuando hayamos realizado todo el proceso tendremos las imagenes en archivos .img separados. Cada uno de esos archivos corresponde a una partición dentro de disco.

Para convertirlos a VirtualBox tenemos dos opciones, make installer_vdi y make android_disk_vdi, ambas generan un disco vdi para VirtualBox, en el primer caso es una pseudo instalación y en el segundo caso es el propio disco que se generaría despues de hacer la instalación. Es preferible esta segunda opción.

Tenemos la imagen, vamos a ejecutarla en virtual box y comienzan los problemas, en mi portatil no funciona, se queda colgada nada más empezar justo antes de lanzar el init. Pero si lo hacen en el PC de escritorio de un compañero de trabajo. Llego a la conclusión, tras leer la misma experiencia en XDA Developers, de que estas imagenes está preparadas solo para funcionan en equipos con procesadores que soporten extensiones VT.

Continuan los problemas, las resoluciones de pantalla son muy limitadas. Esto tiene solución dentro del propio VirtualBox, vamos a editar el fichero de configuración y vamos a añadir resoluciones personalizadas. Editando el fichero .vbox de la máquina, dentro de tag ExtraData añadimos:


      <ExtraDataItem name="CustomVideoMode1" value="1280x800x16"/>
      <ExtraDataItem name="CustomVideoMode2" value="1366x768x16"/>
      <ExtraDataItem name="CustomVideoMode3" value="1920x1080x16"/>
      <ExtraDataItem name="CustomVideoMode4" value="800x1280x16"/>
      <ExtraDataItem name="CustomVideoMode5" value="480x800x16"/>
      <ExtraDataItem name="CustomVideoMode6" value="400x800x16"/>

Con esto podremos arrancar con resoluciones personalizadas, utilizando el parámetro vga=ask del kernel. Para arrancar el kernel de forma personalizada, desde el grub, eliminaremos la primera línea (cmdline (hd0,2) /cmdline) y modificaremos la siguiente para que quede de la siguiente manera:
kernel (hd0,2) /kernel init=/init console=tty0 vga=ask qemu=1 verbose

El cmdline y otros interesantes aspectos relacionados con la máquina se pueden configurar en el fichero build/target/board/vbox_x86/BoardConfig.mk.
Como podemos ver, el cmdline se define de la siguiente manera:
BOARD_KERNEL_CMDLINE := init=/init qemu=1 console=ttyS0 console=tty0 vga=788 verbose androidboot.hardware=vbox_x86 androidboot.console=ttyS0 android.qemud=ttyS1

En este momento tenemos una build que se ejecuta en VirtualBox, que podemos personalizar con diferentes resoluciones, pero que no tiene ni ratón, ni sonido, ni red, además de que no se puede depurar de ninguna manera, ya que al no haber red no hay acceso a adb.

Es el momento de personalizar el kernel. Hasta ahora hemos estado utilizando una prebuilt de un kernel 2.6.29 personalizado para qemu.
Podemos descargar este mismo kernel a traves de git, copiarnos la config por defecto que viene con el y tendremos un kernel igual que el que viene con la AOSP, podemos añadirle soporte para el ratón y tendremos el esperado puntero, pero en cuanto indaguemos a través de foros de desarrollo de android para x86 veremos que mucha gente achaca problemas a que Android 4.0 no se lleva bien con un kernel tan antiguo así que vamos a descargarnos un kernel 3.0.8.


git clone https://android.googlesource.com/kernel/common.git
git branch -a
git checkout -t remotes/origin/android-3.0



Vamos a tener que personalizarlo bastante, yo cogí como config de base la misma que para el kernel anterior pero hay algunas opciones que no se están activando.
Tuve que activarle las opciones de android de staging, la android rtc alarm, el manejo de los fs que vamos a necesitar, el ratón, las tarjetas de red que usa el emulador de virtualbox (pcnet y e1000), y las tarjetas de sonido con soporte alsa (Intel HD Audio y AC97). El manejo de wakelock en userspace (/sys/power/) me dío bastante guerra. Aquí dejo colgada una config que compila sin muchos problemas, habrá que editar algunos archivos, comentar algunas cosas, rezamos dos 'Hail Mary' y hacemos el make ARCH=x86.

Una vez compilado copiamos el vmlinux y la bzImage a las ubicaciones que requiere la build del AOSP:
cp vmlinux /opt/AOSP_SOURCE/prebuilt/android-x86/kernel/vmlinux-vbox
cp arch/x86/boot/bzImage /opt/AOSP_SOURCE/prebuilt/android-x86/kernel/kernel-vbox

Llegados aquí tenemos nuestra VirtualBox levantada con Android Ice Cream Sandwich 4.0.3 y kernel 3.0.8. Tenemos red a través de la eth0, que se levanta con DHCP, que podemos usar para depurar con adb (adb connect ip.de.la.vm:5555), pero las aplicaciones no tienen red, presumiblemente por falta de permisos.

Este comportamiento del comando ping, presumiblemente es el mismo que experimentan las aplicaciones:

root@android:/ # ifconfig eth0
eth0: ip 192.168.1.134 mask 255.255.255.0 flags [up broadcast running multicast]
root@android:/ # ping www.google.es
ping: unknown host www.google.es
root@android:/ # setprop net.dns1 8.8.8.8
root@android:/ # ping www.google.es
PING www.l.google.com (173.194.34.240) 56(84) bytes of data.
64 bytes from mad01s09-in-f16.1e100.net (173.194.34.240): icmp_seq=1 ttl=55 time
=9.02 ms
root@android:/ # su 1000
root@android:/ $ id
uid=1000(system) gid=1000(system)
root@android:/ $ ping www.google.es
You must have internet permissions to use ping.  Aborting.

Viendo las fuentes del comando ping:

if (!isInSupplementaryGroup(AID_INET)) {
fprintf(stderr, "You must have internet permissions to use ping. Aborting.\n");
exit(2);
}

Me deja un poco frio, ya que teoricamente he desactivado el ANDROID_PARANOID_NETWORK del kernel, igual que esta en el emulador, y tuve que comentar incluso unas líneas en el código de security/commoncap.c para evitar que fallara la compilación del kernel. Creo que debo investigar más a fondo el linux/android_aid.h para seguir investigando este fallo.

Hasta que no solucione esto no continuaré con el sonido, que en principio está activado en el kernel y tan solo habría que clonar la configuración de alguna build para eeepc.

Por último, veo a través de adb que la gran mayoría de los fallos que se producen dentro de android estarían relacionados con problemas de memoria:

D/skia    (  156): --- decoder->decode returned false
W/WallpaperManager(  156): Can't decode stream
W/WallpaperManager(  156): java.lang.OutOfMemoryError

D/dalvikvm(  541): GC_FOR_ALLOC freed 8K, 7% free 7368K/7879K, paused 3ms
I/dalvikvm-heap(  541): Forcing collection of SoftReferences for 9830412-byte allocation
D/dalvikvm(  541): GC_BEFORE_OOM freed 62K, 8% free 7306K/7879K, paused 206ms
E/dalvikvm-heap(  541): Out of memory on a 9830412-byte allocation.


Sería bueno saber donde se configura la memoria del sistema, ya que seguramente esté a unos valores mínimos.

Seguire investigando...

Actualización:

- (01/01) Introduciendo lo siguiente en /build.prop se aumenta la VM Heap de dalvikvm y las aplicaciones ya no fallan por falta de memoria:
dalvik.vm.heapsize=32m

- (07/01) Por fin puedo hacer funcionar el navegador. Según parece al limpiar código quitaron la llamada a loader.executeLoad() y por eso se quedaba bloqueado el navegador. Esto, que funcionaba bien con la version 4.0.1, no está funcionando si no se parchea en la 4.0.3. Explicación en ingles y parcheado aquí.

- (07/01) Pruebo el paquete de aplicaciones gapps para ICS (link). Basicamente lo que no funciona requiere configurar una cuenta de Google.

- (11/01) Gracias a la información de este post de Nicu Pavel, he podido portar un stick wifi usb (rtl8187b) y ya puedo registrar la cuenta con Google. Puedo acceder al market, pero las aplicaciones disponibles son muy escasas. Optimizada memoria de dalvik para una vm de 1GB de RAM.

- (14/01) Configurado el parpadeo del cursor en fbcon (write /sys/class/graphics/fbcon/cursor_blink 0), ya no se ve. Ya se escucha sonido a través del comando tinyplay. El mixer se ve y se puede configurar con tinymixer para subir el volumen. AudioManager aún no reconoce el sonido. El mensaje de error es el mismo que están teniendo otros al portar el audio de ICS a sus teléfonos:

E/AudioFlinger(   59): createTrack_l() Bad parameter: sampleRate 44100 format 1, channelMask 0x00000001 "for output 0x8a4c0d0 with format 1
E/AudioTrack(   99): AudioFlinger could not create track, status: -22

- (17/01) Añadido soporte para almacenamiento interno en /data (/data/media). Agregado FUSE al kernel.
El truco para que funcionen las aplicaciones y no haya Force Close producido por las peticiones de estado del volumen a vold pasaría por editar ./frameworks/base/core/res/res/xml/storage_list.xml y configurarlo así.

    <storage android:mountPoint="/mnt/sdcard"
             android:storageDescription="@string/storage_internal"
             android:primary="true"
             android:emulated="true"
             android:mtpReserve="100" />

Añadimos también el servicio en init.vbox_x86.rc:


service sdcard /system/bin/sdcard /data/media 1023 1023
        class late_start

0 comentarios:

Publicar un comentario

Nube de Bits, 2011. Con la tecnología de Blogger.