Desde hace un tiempo vengo trabajando con una Raspberry Pi en diferentes proyectos de investigación. Hace poco escribí un artículo explicando paso a paso cómo instalar Raspbian en una Raspberry Pi. Raspbian es una versión de Debian adaptada para procesadores ARM. Para agilizar el desarrollo de aplicaciones me propuse crear una máquina virtual con Raspbian, utilizando KVM, por supuesto.



El problema yace en que, al tratarse de una arquitectura de CPU diferente a x86, para poder instalar una máquina virtual con Raspbian es necesario que el emulador (QEMU) soporte dicha arquitectura (si tratamos de correr Raspbian sobre un CPU x86 veremos que no funciona en absoluto).

Afortunadamente las últimas versiones de QEMU (Quick EMUlator) soportan la arquitectura ARM. Cabe recordar que KVM se basa en QEMU para emular el hardware de las máquinas virtuales.

Para realizar las pruebas utilicé, como siempre, mi querida workstation CentOS 6 (mi conejillo de Indias, víctima de toda clase de experimentos). La versión de QEMU 0.12 disponible en los repositorios oficiales de CentOS 6 aún no posee soporte ARM, por lo que es necesario compilar e instalar la última versión. Por esta razón este tutorial funciona en cualquier distribución GNU/Linux, siempre que se cumplan los requisitos para que compile QEMU.

Para comenzar, descargar el último tarball disponible en el sitio oficial del proyecto Savannah: http://download.savannah.gnu.org/releases/qemu/.

$ cd ~/Downloads
$ wget http://download.savannah.gnu.org/releases/qemu/qemu-0.15.0-rc0.tar.gz

Esta versión es 100% libre, ya que el proyecto Savannah se encarga de hospedar software que no posee dependencias con software privativo. Si se desea obtener la última versión de QEMU, es posible hacerlo desde el sitio oficial http://wiki.qemu.org/Download.

Descomprimir el tarball en un directorio de confianza. Personalmente me gusta guardar todo el software compilado en un directorio llamado "packages" dentro de mi directorio $HOME, aunque muchos optan por guardarlos bajo /usr/local, /opt u otros.

$ mkdir ~/packages
$ mv ~/Downloads/qemu-0.15.0-rc0.tar.gz ~/packages
$ cd ~/packages
$ tar -xvf qemu-0.15.0-rc0.tar.gz
$ cd qemu-0.15.0-rc0

Configurar QEMU con soporte para ARM:

$ ./configure --target-list="arm-softmmu arm-linux-user" --prefix=/usr

Si no falla ninguna dependencia, compilar. De lo contrario instalar las dependencias faltantes y volver a configurar. En mi caso particular debí instalar gcc, zlib, zlib-devel, glib2, glib2-devel, autoconf, automake y libtool:

# yum install gcc zlib zlib-devel glib2 glib2-devel autoconf automake libtool

Compilar:

$ make

Finalmente, instalar QEMU:

# sudo su
# make install

Crear un directorio de trabajo base para recopilar todos los archivos necesarios para la máquina virtual:

$ mkdir ~/VM
$ mkdir ~/VM/raspi
$ cd ~/VM/raspi

Conseguir un kernel Linux compilado para ARM. Es posible compilar uno siguiendo los pasos de este tutorial, o descargar uno ya compilado:

$ wget http://xecdesign.com/downloads/linux-qemu/kernel-qemu

Descargar la última imagen de Raspbian, pesa casi 2G así que lleva su tiempo:

$ wget http://downloads.raspberrypi.org/raspbian_latest
$ sudo unzip 2013-07-26-wheezy-raspbian.zip
$ mv 2013-07-26-wheezy-raspbian.img raspi.img

Si iniciamos la máquina virtual directamente con ésta imagen es posible toparse con el error:

INIT: ld "1" respawning too fast: disabled for 5 minutes

Por lo que es necesario repararla para evitarlo. Crear un directorio temporal y montar el root filesystem (/) de la imagen de Raspbian (por supuesto con la máquina virtual apagada, para no corromper el filesystem):

$ mkdir /tmp/raspi
$ sudo mount raspi.img -o offset=62914560 /tmp/raspi/

Editar el archivo /etc/ld.so.preload dentro del sistema de archivos raíz de la imagen:

$ sudo nano /tmp/raspi/etc/ld.so.preload

Comentar la línea "/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so", debe quedar así:

#/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so

Guardar los cambios y desmontar:

$ sudo umount /tmp/raspi/

Ya tenemos todo listo para iniciar la máquina virtual con procesador ARM con la imagen de Raspbian, utilizando el emulador qemu-system-arm con los siguientes parámetros:

$ sudo qemu-system-arm -kernel kernel-qemu -cpu arm1136-r2 -m 128 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda raspi.img -vnc 127.0.0.1:55

"kernel-qemu" es el nombre del archivo del kernel Linux compilado para ARM y "raspi.img" es el nombre de la imagen de Raspbian. Para el servidor VNC, el cual provee video para la máquina virtual, es necesario seleccionar un puerto disponible. Al pasar 127.0.0.1:55 como parámetro indicamos que escuche sólo en localhost en el puerto 5955.

Una vez iniciada, es posible conectarse a la máquina virtual con un cliente VNC (por ejemplo "vncviewer") a "localhost:5955".

En el primer inicio es necesario reparar el filesystem debido al cambio realizado en el archivo "/etc/ld.so.preload". Una vez que el sistema deja el prompt de root (# ) ejecutar:

# fsck.ext4 /dev/root

Presionar 'Y' para reparar cualquier error en el sistema de archivos. Luego reiniciar la máquina virtual:

# reboot

Iniciar la máquina virtual nuevamente, esta vez arranca perfectamente:

$ qemu-system-arm -kernel kernel-qemu -cpu arm1136-r2 -m 128 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda raspi.img -vnc 127.0.0.1:55
Uncompressing Linux... done, booting the kernel.

Debian GNU/Linux 7 raspberrypi ttyAMA0

raspberrypi login:

Al conectarse nuevamente con el cliente VNC se observa la ventana de la herramienta de configuración raspi-config, desde donde es posible finalizar la instalación de la imagen de Raspbian:

Cambiar la contraseña del usuario "pi":

Habilitar el inicio al escritorio LXDE:

Finalizar la configuración y reiniciar:

El emulador no maneja bien la interrupción para reiniciar el sistema, por lo que se debe detener el emulador QEMU desde la consola utilizando la combinación de teclas Ctrl+C una vez que Linux reporta "System halted.":

Luego reinicar el emulador:

$ qemu-system-arm -kernel kernel-qemu -cpu arm1136-r2 -m 128 -M versatilepb -no-reboot -serial stdio -append "root=/dev/sda2 panic=1" -hda raspi.img -vnc 127.0.0.1:55
Uncompressing Linux... done, booting the kernel.

Debian GNU/Linux 7 raspberrypi ttyAMA0

raspberrypi login:

Y reconectarse al servidor VNC:

Raspbian inicia nuevamente:

Y por primera vez carga el escritorio LXDE:

Finalmente tenemos nuestra máquina virtual QEMU con procesador ARM corriendo Raspbian.

Esta saga de artículos dedicados a Raspberry Pi, al mejor estilo culebrón de telenovela, continuará... Así que estén atentos a las novedades.


Tal vez pueda interesarte


Compartí este artículo