lunes, 18 de junio de 2007

Compilación e instalación de quemu-0.9.0 + kqemu-1.3.0pre11 en Linux

Orestes Leal R. [orestesleal13022@cha.jovenclub.cu]

Antes que nada un saludo a la gente de BlackHat por permitirme tan amablemente colaborar con mi humilde aporte. Hola a todos y a cada uno de ustedes. Uno de los objetivos de este artículo es dejar documentado de una vez por todas cómo compilar sin problemas (o eso supongo:) qemu y kqemu, para poder "emular" sin problemas el sistema que se nos venga en gana (si tienes suficiente RAM... of course).

Para los que no estén familiarizados, qemu es una aplicación que se encarga de crear, manejar y, entre otras cosas, hacer que se ejecute una máquina virtual, o lo que es lo mismo, un sistema sobre otro. Pues sí, muy parecido al Vmware de Win32, pero sin tanto parecido estético, digamos.

El primer problema conque me encontré en muchos casos es que los documentos sobre cómo compilar qemu (con su consiguiente beneficio, CFLAGS, CXXFLAGS, etc, ya eso es otro artículo) eran dependientes de la distribución, Debian, Slack, Suse, Redhat, Gentoo. La mayoría de la documentación relacionada estaba orientada a paquetes precompilados y sujetos a métodos de instalación dependientes, que, como todos sabemos, ocultan un proceso de pre-configuración muy beneficioso para aquel que estuviera interesado. Quiero decir que compilar los programas da una ventaja muy sustanciosa y que nos pone un paso por delante de los precompilados, más rendimiento por encima de todo y lo más importante: lo que aprendemos con ello. Es por eso que esta mini-guía es aplicable a todas las distribuciones actuales de Linux y, cómo no, también una referencia -en muchos aspectos- para otros sistemas, (BSD, etc).

Este documento está basado en la versión de qemu 0.9.0 y de kqemu 1.3.0pre11 (kqemu es un add-on de qemu, que realmente es un módulo del Kernel para acelerar la virtualización implementando rutinas optimizadas para su objetivo final). Dicho esto, si se sienten motivados y existe esa curiosidad, vamos a lo que importa y a pasar un buen rato.

Deben obtener los files necesarios:

http://fabrice.bellard.free.fr/qemu/qemu-0.9.0.tar.gz » 1.8 Mb
http://fabrice.bellard.free.fr/qemu/kqemu-1.3.0pre11.tar.gz » 157 Kb

Los que no puedan acceder a la web pueden obtenerlo en los repos de Debian existentes en Cuba, localizando el paquete qemu en los sources (no en los deb):

ftp://ftp.softwarelibre.cu
ftp://ftp.sld.cu
http://packages.debian.org

Hay una alternativa al final del documento para los que no puedan compilar, pero con el defecto de no tener capa de aceleración kqemu (emulación más lenta).

Vamos a darle... Si ya tienes qemu no tienes que desinstalar el otro; el prefijo de instalación será /usr/local/qemu0.9. Después ajustaremos el $PATH para que el Shell pueda encontrar los binarios que allí se alojen.

Nota sobre el Kernel:
Esta guía la estoy escribiendo sobre el Kernel 2.6.21.2, pero ése no es el punto, sino que a partir del núcleo 2.6.20 el soporte de virtualización se ha integrado para plataformas AMD e Intel con la consiguiente mejora que esto trae consigo, haciendo uso también del Intel® VT (que fue introducido en el Pentium IV, modelo seriado 662 y 672), los cuales son un set de extensiones para soportar la virtualización más comúnmente conocida como VMX.

Si tienes una de estas series del Kernel y no tienes activado esta nueva característica, recomiendo hacerlo, lo cual beneficia, claro está. Recuerde que cuando se habla de qemu se está hablando de virtualización que, sin ciertas características de los procesadores, nunca hubieran sido posibles este tipo de aplicaciones. En el Kernel puedes activar la VT en la configuración del núcleo siguiente:

Device Drivers » Virtualización

Y se presenta esto:

Como se aprecia, la selección tiene lugar como <M>, que indica que se va a compilar como un módulo más del núcleo. Si desean que la virtualización vaya insertada dentro del mismo, le asignamos con otra selección un <*>, con el consiguiente aumento (ligero) del size del Kernel.

En mi caso poseo un Intel, como se puede apreciar (diablos, ¡como me gustaría probar un AMD2!). Si no lo tienen activado, márquenlo y recompilen el Kernel (recuerden que no es obligatorio) y reinicien con el nuevo Kernel. Este paso no es requerido, pero ayuda tener un Kernel con KVM a la hora de trabajar con máquinas virtuales.

Requerimientos en la versión de GCC::

qemu es bien conocido por no compilar sobre gcc-4.x.x (al menos hasta la versión que describe este documento), por lo que es requerido tener una versión 3.x.x en el sistema para que puedan finalizar esta guía. En mi caso tengo dos versiones: gcc-4.1.2 y 3.3.6, claro está, con rutas diferentes. El compilador que uso por defecto es el gcc4 en un prefix común, y el gcc3 en /opt/gcc-3.3.6. Para que las detecciones del script configure me detecte el gcc3, en vez del gcc4, mi variable PATH luce así.

PATH="/opt/gcc-3.3.6/bin:/usr/sbin:/sbin:/bin:/usr/bin:
/usr/local/bin:/usr/local/lib:/usr/local/sbin/:/usr/X11/bin:
/usr/X11/lib:/usr/X11/lib/pkgconfig:/opt/qt/bin:
/opt/kde-3.5.6/bin:/usr/local/apache2/bin:/usr/local/MPLAYER:
/usr/local/gdb/bin"

Vean como antepongo antes que nada la ruta al directorio donde se aloja gcc3. Esto da como consecuencia que cualquier script configure (los usados en la compilación basados en la GNU Toolchain) u otros detecten que el compilador por defecto es gcc3, con lo cual van a guardar esa información en los makefiles, por ejemplo, como una entrada similar a CC=/opt/gcc-3.3.6/bin/gcc.

Si deseas apuntar a un gcc3 existente -siendo el gcc4 el establecido por defecto-, sólo ejecuta esto:

export PATH=/ruta/al_directorio_donde_se_aloja_el_gcc3/:$PATH

Esto trae como efecto que el compilador gcc3 se vuelva el compilador por defecto a menos que haya algún wrapper (modificación/implementación típica que lo impida, caso raro) de la distribución que obligue a hacer lo contrario, ya sabes, "debes" compilar qemu con gcc3... seguimos dándole.

Compilando qemu::

A veces me cuesta un poco eliminar los sources de los programas que compilo. Por eso siempre los pongo en /tmp para que el script de limpieza del sistema se encargue de hacerlo por mí. ¿Cuál es el script de limpieza? Es /etc/rc.d/init.d/cleanfs. Esto es en mi caso; es probable que en su distribución no se llame así y esté ubicado en /etc/init.d/.

Ejecutemos:
cd /tmp
tar xzvf qemu-0.9.0.tar.gz
cd qemu-0.9.0
./configure --prefix=/usr/local/qemu0.9 --enable-Alsa
make
make install

Agregue --enable-alsa si se está usando Alsa como sistema de sonido por defecto. Esto es sólo compatible con Linux y distribuciones que usen Alsa, no con el ya casi obsoleto OSS, por lo que la compilación en un sistema con OSS daría como resultado en un error, ya que se intentaría compilar contra las librerías libasound de Alsa que no existen, y habría que remover ese parámetro del configure en cuestión.

En mi caso, qemu se ha compilado contra Alsa y también contra libSDL, entre otras que son básicas (como libc, la librería estándar de C en Linux ). Veamos:

webdeveloper@root->/tmp/qemu-0.9.0$ldd /usr/local/qemu0.9/bin/qemu
linux-gate.so.1 => (0xffffe000)
libm.so.6 => /lib/libm.so.6 (0xb7eef000)
libz.so.1 => /lib/libz.so.1 (0xb7edb000)
# libasound.so.2 => /usr/lib/libasound.so.2 (0xb7e1d000)
# libSDL-1.2.so.0 => /usr/lib/libSDL-1.2.so.0 (0xb7d8c000)
libpthread.so.0 => /lib/libpthread.so.0 (0xb7d74000)
libutil.so.1 => /lib/libutil.so.1 (0xb7d70000)
librt.so.1 => /lib/librt.so.1 (0xb7d67000)
libc.so.6 => /lib/libc.so.6 (0xb7c3e000)
/lib/ld-linux.so.2 (0xb7f27000)
libdl.so.2 => /lib/libdl.so.2 (0xb7c3a000)

Si todo ha ido bien, vamos a agregar al PATH la nueva dirección para que el shell pueda encontrar el binario de qemu y qemu-img cuando lo escribamos en nuestro terminal de preferencia.

Abrimos con un editor el ~./bashrc o /etc/profile y lo modificamos para que finalmente deba quedar algo así:

PATH="/opt/gcc-3.3.6/bin:/usr/sbin:/sbin:/bin:/usr/bin:
/usr/local/bin:/usr/local/lib:/usr/local/sbin/:
/usr/X11/bin:/usr/X11/lib:/usr/X11/lib/pkgconfig:
/opt/qt/bin: /opt/kde-3.5.6/bin:/usr/local/apache2/bin:
/usr/local/MPLAYER:/usr/local/gdb/bin:/usr/local/qemu0.9/bin"

Nótese que he agregado otra ruta de búsqueda al final, aunque si ya tiene una versión de qemu instalada, agrégelo al inicio del PATH para que utilice la nueva versión. Finalizado esto ejecutamos:

source ~/.bashrc
ó
source /etc/profile

En dependencia de cual de los dos hayamos editado, source es una función interna del shell de Linux (bash), y es usada para recargar y actualizar las variables de entorno. Generalmente, esta característica es usada también por otros shells como sh, ksh, entre otros.

Pruebe a escribir qemu. La salida debe ser algo más larga que esto:

#webdeveloper@root->/tmp/qemu-0.9.0$qemu
#QEMU PC emulator version 0.9.0, Copyright (c) 2003-2007 Fabrice Bellard
#usage: qemu [options] [disk_image]
#
#'disk_image' is a raw hard image image for IDE hard disk 0
#Standard options:
#-M machine select emulated machine (-M ? for list)
#-fda/-fdb file use 'file' as floppy disk 0/1 image
#
.....

A medio camino::

Todo está listo y, si quisiéramos, podríamos comenzar a montar una máquina virtual, pero déjenme darles una recomendación: vamos a hacer las cosas como debe ser, al proporcionarle a qemu una capa de aceleración que aumentará en un 39% su velocidad, según he podido medir.

Nota sobre las cabeceras (o headers) del núcleo:
Para compilar kqemu necesitarás las cabeceras del núcleo. En mi caso, las cabeceras del 2.6.20.2 las ubiqué en /kernelsource/linux-2.6.20.2/. Si se intenta compilar kqemu con un árbol del Kernel previamente limpiado con make mrproper, la compilación falla, debido a que no encuentra ficheros con símbolos entre otros ficheros necesarios para la compilación. Así que asegúrense de por lo menos ejecutar un make menuconfig y salvar la configuración, y hacer por lo menos un make para que se creen los ficheros necesarios; no importa que no compiles el Kernel completamente como tal.

Compilando kqemu::

Regresamos un nivel detrás (estábamos compilando qemu, ¿sí?):

cd ..
tar xzvf kqemu-1.3.0pre11.tar.gz
cd kqemu-1.3.0pre11

Un ./configure --help nos muestra esto:

#webdeveloper@root->/tmp/kqemu-1.3.0pre11$./configure --help
#Usage: configure [options]
#Options: [defaults in brackets after descriptions]
#
#Standard options:
# --help print this message
# --prefix=PREFIX install in PREFIX []
# --kernel-path=PATH set the kernel path (configure probes it)
#
#Advanced options (experts only):
# --source-path=PATH path of source code [/tmp/qemu-fast/kqemu-1.3.0pre11]
# --cross-prefix=PREFIX use PREFIX for compile tools []
# --cc=CC use C compiler CC [gcc]
# --host-cc=CC use C compiler CC [gcc]
# --make=MAKE use specified make [make]
#

Para hacer las cosas con más seguridad y exactitud, vamos a ejecutar en base a donde tengas los headers del Kernel el siguiente comando (ajústelo para su caso y continúe):

./configure --kernel-path=/kernelsource/linux-2.6.20.2
make
make install

El proceso lleva unos segundos. Si todo ha ido bien, podemos cargar el módulo:

modprobe kqemu

Un lsmod | grep kqemu debería mostrarnos algo como:

kqemu 123560 1

Como sea, puede hacer una búsqueda para comprobar que el modulo está en su lugar:

find /lib/modules/$(uname -r) -name kqemu.ko

La salida debe ser algo parecida a esto:

/lib/modules/2.6.20.2/misc/kqemu.ko

¿Todo perfecto hasta el momento? ...¡genial! Hasta aquí se ha cumplido el objetivo fundamental de esta guía. De todas formas voy a poner referencias de cómo crear espacio para una máquina virtual y cargar una en base a una imagen ISO.

Creando el espacio que será usado como disco duro virtual::

Mis imágenes virtuales las pongo en /mnt/tmp_filesystem. Usted alójelas donde desee. Para crear 2 Gb de disco virtual ejecutemos:

qemu-img create virtual.img 2G

Creo que no lleva mucha explicación... Estoy creando el fichero virtual.img de 2 Gb con el parámetro create. Vamos a cargar algo para probar:

qemu -m 100 -cdrom gparted-livecd-0.2.5-3.iso -boot d virtual.img -kernel-kqemu

El parámetro -m 100 indica que qemu utilizará 100 Mb de memoria física para él. Con -cdrom gparted-livecd-0.2.5-3.iso se carga ese ISO como si estuviera en el CD-ROM. -boot indica que lo bootee desde un CD, disco, floppy, etc. Con d se indica el device que voy a utilizar con el fichero virtual.img creado como dispositivo y -kernel-kqemu activa el soporte para el acelerador kqemu. Al haber cargado el módulo kqemu se crea su dispositivo en /dev/, o sea, /dev/kqemu, donde qemu realizará funciones a través de él (si existiese).

La memoria a utilizar es variable; todo depende de su sistema, aunque si tiene poca memoria, e intenta arrancar qemu, se muestra un mensaje indicando que el sistema de ficheros shm no tiene suficiente espacio. En este caso se puede hacer lo siguiente:

umount /dev/shm
mount -t tmpfs -o size=109m none /dev/shm

...o los megas que desee, siempre teniendo en cuenta que se recomienda la mitad de la memoria física -o algo más-, todo depende.

Alternativa rápida (dependiente de Internet):
Si el proceso de compilación no se ha podido realizar por cualquier causa, puede bajarse binarios de qemu, ya compilados para Linux-X86 en el URL:

http://fabrice.bellard.free.fr/qemu/qemu-0.9.0-i386.tar.gz

Debes copiarla/descomprimirla en /. El único problema es que la virtualización decaerá en su rendimiento, ya que kqemu no existe. Como sea, se puede emular; aunque cuando inicie qemu se queje de que /dev/kqemu no existe, puede suprimir el mensaje pasando a qemu el parámetro:

-no-kqemu



Artículos relacionados


No hay comentarios: