Introducción

El Bochs es un emulador de la arquitectura IA-32. Esta aplicación Open Source puede ser ejecutada en varias plataformas, permitiendo simular de forma sencilla y controlada una PC completa, incluyendo los periféricos y el conjunto de integrados que la componen. También permite “conectar” los periféricos simulados, a ficheros o mecanísmos de IPC del host donde se ejecuta, para simular la interacción de la PC virtual con el mundo exterior.

Una de las principales características que distinguen este emulador de otros como Virtual Box o VM Ware, es la funcionalidad de depuración, la cual permite un seguimiento completo del código que ejecuta la CPU así como también inspeccionar el estado de todos sus registros, visualizar el contenido de la memoria y analizar el estado de los periféricos.

Esta aplicación se puede instalar tanto en Windows como en Linux, aunque las opciones de configuración varían de un sistema al otro, debido principalmente a la forma de interactuar con el resto del host de desarrollo ( el “mundo exterior” de la simulación ). Ambas se pueden descargar de la web oficial del proyecto, http://bochs.sourceforge.net/

La versión de Windows incluye por defecto dos ejecutables, uno para el modo normal (llamado “bochs”) y otro para el depurador (llamado “bochsdbg”). Las versiones de Linux que se instalan a través de los gestores de paquetes solo suelen incluir el ejecutable para el modo normal, debiendo el usuario descargar los fuentes y compilarlo con las opciones correspondientes, lo que generará un ejecutable también llamado “bochs” a secas, pero que si utilizará el modo de depuración.

En la Cátedra solo se utilizará y brindará soporte, de la versión homologada por la misma, para la instalación y configuración en un entorno Linux.

La Cátedra provee una imágen de Linux (Linux TDiii) que dispone de la aplicación instalada, pero no configurada.

En los apartados subsiguientes se detalla el proceso de instalación y configuración, tanto para el depurador interno como para GDB.

Instalación

Ver también: Video de instalación de Bochs en Linux.

A continuación se detallan los pasos necesarios (ante problemas recuerde leer las FAQ) para la instalación de la aplicación tanto con la interfaz de depuración propia del Bochs, como con GDB (GNU DeBugger).
La versión homologada por la Cátedra y con la cual se analizarán y evaluarán los trabajos prácticos es la 2.6.9 (MM=2.mm=6.vv=9).

  1. Descomprimir el paquete de instalación en un directorio de trabajo temporario, mediante el comando:
     tar -xzvf bochs-MM.mm.vv.tar.gz -C /su_directorio_temporal 
    • -x: Extrae el contenido del fichero.
    • -z: Descomprime el contenido mediante gzip.
    • -v: Muestra en pantalla todas las salidas del comando (modo verbose).
    • -f: Especifica que fichero tar debe ser tomado como argumento.
    • -C: Indica la ruta a la carpeta donde se desea descomprimir el fichero.
      Para mayores detalles
      man tar
  2. Si la operación fue exitosa, se observará en /su_directorio_temporal/bochs-MM.mm.vv todos los fuentes de la aplicación, mediante
     cd su_directorio_temporal/bochs-MM.mm.vv/
     ls 
  3. Verificar que se disponen de todas las dependencias (librerías) necesarias para que la aplicación pueda ser instalada y funcionar correctamente.
     sudo apt-get update
     sudo apt-get install nasm build-essential gtk-2.0 libgtk2.0-dev

    Dependiendo de la distribución de Linux, el GTK puede venir preinstalado o no.

Interfaz de depuración BOCHS

Para la configuración de la interfaz de depuración interna de Bochs se deben seguir los siguientes lineamientos:

  1. El script configure, permite establecer las opciones de compilación con las cuales se creará la aplicación. Dicho script se debe ejecutar en el directorio donde se encuentra el código fuente, es decir que debe ejecutarse después de haber realizado el paso 3 de la sección anterior. Es posible visualizar todas las opciones brindadas mediante
     ./configure --help | less 

    , o bien ingresando a http://bochs.sourceforge.net/doc/docbook/user/compiling.html.
    Por defecto en la Cátedra se emplearán las siguientes opciones:

    ./configure --enable-x86-64 --enable-smp --enable-usb --enable-usb-ohci --enable-debugger --enable-disasm --enable-x86-debugger --disable-docbook

    Verificar que no se visualicen errores al finalizar la ejecución del comando indicado.

    • –enable-x86-64: Habilita el soporte del conjunto de instrucciones x86-64 (64bit).
    • –enable-smp: Habilita el multiprocesamiento simétrico.
    • –enable-usb: Habilita el soporte para USB UHCI
    • –enable-usb-ohci: Habilita el soporte para USB OHCI
    • –enable-debugger: Habilita el depurador interno de Bochs. Para nuestros objetivos, esta es la herramienta más útil de la aplicación.
    • –enable-disasm: Habilita el desensamblado de un binario.
    • –enable-x86-debugger: Permite utilizar los registros de depuración de los procesadores Intel.
    • –disable-docbook: Deshabilita la generacion de documentación. Requiere dependencias que ocupan un espacio no menor y no es de gran utilidad
  2. Luego ejecutaremos los comandos:
     make
     sudo make install

Interfaz de depuración GDB (opcional)

Para disponer de la interfaz de depuración GDB, se deben repetir los pasos pasos detallados en Interfaz de depuracion BOCHS, pero reconfigurando las siguientes opciones

  • La carpeta de instalación debe ser diferente al seleccionado previamente, por ejemplo bastaria con agregar el sufijo _gdb es decir <carpeta_de_instalacion>_gdb. Esto es necesario ya que el binario de la aplicación generado en Interfaz de depuracion BOCHS es diferente al que se generará en esta instancia, al igual que las opciones de configuracion.
  • –enable-gdb-stub: Esta opción habilita GDB como interfaz de depuración, siendo mutuamente excluyente con –enable-debugger, es decir que esta última debe ser eliminada.
  • –enable-smp: GDB no soporta depuración en un entorno de multiprocesamiento, por lo que esta opción se debe quitar.

Antes de ejecutar el comando make, se debe verificar que los paquetes libxrandr-dev y gdb se encuentren disponibles, a tal fin basta ejecutar

 sudo apt-get install “nombre del paquete” 

Adicionalmente, se deberá cambiar la ruta de acceso de la opción –prefix, de manera que se instale sin sobrescribir la instalación previa de forma tal de disponer de ambas alternativas. Para ello solo basta con especificar

--prefix=/var/tmp/bochs-MM.mm.vv-gdb 

Configuración

La configuración de la aplicación puede ser llevada a cabo fácilmente mediante su interfaz de edición, para inicializarla solo basta con ejecutar bochs y seleccionar la opción Edit options y una vez finalizada la edición guardar la configuración mediante Save options to en .bochsrc

Depurador BOCHS

A continuación se detallan las opciones más relevantes para utilizar con el depurador interno del Bochs.

  • Logfile options: permite establecer los ficheros en los cuales se almacenarán los mensajes de información provistos por el depurador y la consola de control. Seleccionar la opción deseada e indicar el nombre del fichero en el cual se desea almacenar la información, por ejemplo console.log y debugger.log para la consola y el depurador respectivamente.
  • CPU Options: esta configuración es una de las más importantes ya que establece que tipo de CPU se simulará. En la Cátedra se utilizará la siguiente configuración:
    • CPU configuration bx_generic
    • Emulated instructions per second (IPS) 2500000
    • Las opciones no especificadas deben disponer de su valor por defecto
  • CPUID Options: establece las caracterìsticas del CPU a simular
    • Support for SSE instruction set sse4_2
    • Support for XSAVE instruction yes
    • Support for XSAVEOPT instruction yes
    • 1G pages support in long mode yes
    • PCID support in long mode yes
    • FS/GS BASE acces instructions support yes
    • Supervisor Mode Execution Protection support yes
    • Supervisor Mode Access Protection support yes
    • Las opciones no especificadas deben disponer de su valor por defecto
  • Memory options: establece la memoria a simular por el emulador y la que el host le asignará
    • Standard Options→RAM size options→memory size 512
    • Standard Options→RAM size options→host memory size 512
    • Standard Options→ROM image options→file ruta a la imagen de bios
    • Standard Options→ROM image options→address 0xf0000
  • Clock & CMOS options: establece las opciones de configuración de la BIOS referentes al reloj
    • Synchronisation method slowdown
  • Disk & Boot options: permite especificar el dispositivo desde el cual se iniciará la PC simulada y que unidades de disco dispondrá
    • First Floppy Drive→What type of floppy drive 3.5“ 1.44M
    • First Floppy Drive→Enter new filename floppy.img
    • First Floppy Drive→What type of floppy media 1.44M
    • First Floppy Drive→Is media write protected no
    • First Floppy Drive→Is the device inserted… inserted
    • Boot Options→Boot drive #1 floppy
  • Existen algunas opciones de configuración que no se encuentran accesibles desde la interfaz de edición, para lo cual con algùn editor de texto se abrirá el fichero creado (.bochsrc), y se modificará el valor de la opciones, en especial
    • magic_break: enabled=1 : Permite insertar breakpoints en el código fuente. Es importante destacar que esta metodologìa no debe ser utilizada para la depuración salvo excepciones, ya que para insertar breakpoints se debe emplear el comando del depurador, tal como se detallará en Breakpoints.
    • display_library: x : En esta lìnea para disponer de una interfaz de depuración gráfica, se debe agregar
      , options="gui_debug"

Depurador GDB

La configuración de Bochs para su utilización con GDB, solo debe ser aplicada si se generó el binario como se indica en Interfaz de depuración GDB, adicionalmente debe seguir los pasos detallados en Depurador BOCHS, con las siguientes modificaciones:

  • Other options→GDB Stub Options→Enable GDB stub yes
  • Las no especificadas deben disponer de su valor por defecto

Adicionalmente al iniciar DDD (la GUI de GDB), se debe configurar la interfaz con la cual se conectará con Bochs, para ello bastará con ejecutar en la consola de DDD

 target remote localhost:1234 

y esperar la respuesta

 Connected to 127.0.0.1 

Argumentos de la linea de comandos

Visualizar la ayuda disponible

/opt/bochs-2.6.9-int/bin/bochs --help

Cargar la configuración desde un fichero específico

/opt/bochs-2.6.9-int/bin/bochs -f <ruta_delfichero_de_configuracion>

Comandos del depurador interno

La lista completa de los comandos provistos por Bochs se encuentra en http://bochs.sourceforge.net/doc/docbook/user/internal-debugger.html, o simplemente ejecutando help en la consola del depurador. Sin embargo a continuación se detallan los que son considerados más relevantes.

Breakpoints

Sin lugar a duda al momento de desarrollar cualquier aplicación resulta de suma utilidad, detener la ejecución de código en puntos conocidos, ya sea para inspeccionar a posteriori el contenido de ciertas variables o bien para analizar condiciones de error. A tal fin el depurador del Bochs, cuenta con la familia de comandos break o bien su abreviatura b

vb seg:off
lb linearaddress
b  physicaladdress

Como se verá durante el desarrollo de los problemas, el siguiente comando detiene la ejecución de código en la dirección lógica asociada al segundo descriptor (0x10) de la GDT en la instrucción ubicada en el desplazamiento 0x89a, a partir de la base del descriptor mencionado.

vb 10:89a

Si la base del descriptor se inicializa en 0x0, el siguiente comando detendrá la ejecución en el mismo punto que el anterior, es decir en la dirección lìneal 0x89a

lb 0x89a

Por otro lado si se trabaja en un esquema de paginación en el cual las direcciones lógicas coincidan con las físicas (identity mapping), el siguiente comando generará los mismos efectos que los descriptos anteriormente.

b 0x89a

Control de ejecución

En conjunto con los breakpoints una de las funcionalidades más potentes de un depurador es la capacidad de controlar la ejecución de un programa. Como es bien sabido un depurador permite ejecutar instrucciones paso a paso

 <bochs:5> s 

continuar con la ejecución hasta el final o el próximo breakpoint

 <bochs:6> c 

o bien continuar con la ejecución de la instrucción inmediatamente posterior a una rutina, sin la necesidad de recorrerla paso a paso

 <bochs:7> p 

Inspección de las tablas de descriptores

Uno de los comandos más útiles y de los primeros que se utilizarán al momento de realizar la guía de trabajos prácticos es

info gdt n
info idt n

Estos comandos permiten visualizar el contenido del descriptor n de la Tabla Global de Descriptores (GDT) y la Tabla de Descriptores de Interrupción (IDT), respectivamente. En caso de requerir el análisis de las tabla completa, solo basta con omitir el parámetro. Es muy ilustrativo comparar los descriptores utilizados en modo IA-32e tanto para 32b como para 64b.

Inspección de memoria

El contenido de la memoria puede ser inspeccionado mediante el comando 'x' (para ver la memoria lineal), o el comando 'xp' (para ver la memoria física), de acuerdo a la siguiente regla:

x /<n><u><f>  <linear address>

donde

<n> es la cantidad de posiciones consecutivas que quieren ver.

<u> es el formato número en el que lo quieren ver (x para hexadecimal, d para decimal).

<f> es el tamaño de la posición (b para byte, h para 16 bits y w para 32 bits).

Como se puede apreciar es posible inspeccionar el contenido de la memoria, ya sea con de las direcciones lineales o de las direcciones físicas. Este comando es sumamente útil en el desarrollo de la guía de trabajos prácticos para todo aquello referido a paginación, asi como también para inspeccionar el estado de variables, o el contenido de tablas y/o cadenas.

Asi, por ejemplo, el siguiente comando del depurador mostrará los 10 bytes de memoria a partir de la dirección lineal 0x1000, en formato hexadecimal.

x /10xb  0x1000

De forma similar, el siguiente comando mostrará los 10 dwords de memoria a partir de la dirección lineal 0x1000, en formato hexadecimal.

x /10xw 0x1000

Si en cambio quisieramos ver los 10 bytes de memoria a partir de la dirección lineal 0x1000, pero en formato decimal, deberíamos ejecutar:

x /10db 0x1000

Traducción de las direcciones lineales paginadas a físicas

Uno de los principales escollos que el desarrollador se encuentra al momento de resolver los ejercicios relacionados con paginación, es verificar que el mapa de memoria implementado en código coincida con el requerido. Para tal fin, existen los comandos

page <linearaddress>
info tab

El primer comando permite no solo realizar la traducción de la dirección líneal paginada a su correspondiente dirección física, sino también permite visualizar la inicialización de los registros y entradas de paginación asociadas. El segundo caso permite visualizar las traducciones de las direcciones lineales a físicas, para toda la memoria RAM del sistema, es decir se observarán las traducciones que se inicializaron correctamente y las que tienen un contenido erroneo. A continuación se muestran algunos ejemplos, el primero de los cuales no utiliza la unidad de paginación, mientras que en el segundo la misma se encuentra activa para el modo IA32e 64b. En todos los casos la dirección lineal coincide con la física (identity mapping)

<bochs:1>page 0
linear page 0x0000000000000000 maps to physical page 0x0000000000000000
<bochs:2>page 0x8000
PML4: 0x0000000000011021 ps         A pcd pwt S R P
PDPE: 0x0000000000012021 ps         A pcd pwt S R P
 PDE: 0x00000000000000e7 PS g pat D A pcd pwt U W P
linear page 0x0000000000008000 maps to physical page 0x0000000000008000
<bochs:3> info tab
0x00000000-0x000fffff -> 0x0000000000000000-0x00000000000fffff   (Primer megabyte correctamente inicializado)
0x54a20000-0x54a20fff -> 0x0000003df000e000-0x0000003df000efff   (Traducciones sin 
...                                                               inicilizar
0xd62e7000-0xd62e7fff -> 0x000000000298e000-0x000000000298efff    para 48MB de RAM)

Inspección de la pila

En el caso de querer analizar el stack, se puede optar por dos alternativas.

  • Utilizar el mismo mecanismo empleado para inspeccionar memoria, utilizando la dirección lineal que se conforma a partir de la dirección lógica SS:ESP.
  • Mediante el comando
     print-stack [num words] 

Al ejecutar el mismo se podrá ver el contenido de los primeros multiplos de 16 bit especificados como argumento, mediante num words. Recordar que si se desea inspeccionar el contenido que se guardó en primera instancia, se debe leer en forma completa la pila, ya que el comando mencionado realiza una lectura tipo TOP-DOWN, por lo cual basta omitir el argumento.

Este comando es de mucha utilidad a la hora de depurar excepciones, ya que permite de forma rápida ver el par CS:EIP que causó la excepción, y el ErrorCode de la misma si lo hubiere.

Inspección de dispositivos

En ciertos casos puede resultar de utilidad observar el estado de un dispositivo especìfico, sobre todo el PIC y el PIT en nuestro entorno de trabajo. A tal fin se dispone del comando

 info device "dispositivo" 

Por ejemplo para el caso del PIT

 <bochs:1> info device "pit"
82C54 PIT

GATE #2 = 1
Speaker = 0

counter #0; freq=18,206, OUT=1
counter #1; freq=18,206, OUT=1
counter #2; freq=18,206, OUT=1 

Supported options:
info device 'pit' 'counter=N' - show status of counter N

Se puede observar que además de brindarnos la información completa de la configuración y el estado de cada contador, se indica que es posible seleccionar un elemento en forma individual para conocer su estado, en forma detallada

 <bochs:2> info device "pit" "counter=1"
82C54 PIT

GATE #2 = 1
Speaker = 0

counter #0; freq=18,206
count: 40456
count_binary: 0x9e08
counter GAT: 1
counter OUT: 1
next_change_time:0 

Es importante destacar que tanto los dispositivos como las opciones debe especificarse como argumentos tipo cadena, es decir entre comillas.

ChristiaN 2019/07/29 22:33

FAQ

  • ¡Al ejecutar el comando apt-get build-dep bochs se presenta el error Debe poner algunos URIs 'fuente' en su sources.list!

Como parte de su funcionamiento, APT utiliza un archivo que enlista las “fuentes” en donde se encuentran los paquetes. Este archivo en Debian es /etc/apt/sources.list y bastarà con agregar las siguientes lìneas

     deb http://http.us.debian.org/debian stable main contrib non-free
     deb http://security.debian.org stable/updates main contrib non-free

Para mayores detalles refirise a http://www.debian.org/doc/manuals/apt-howto/ch-basico.es.html En caso de utilizar Ubuntu bastara con habilitar “sources” mediante la interfaz Software & Updates

  • ¡El comando make install finaliza con un mensaje que contiene un texto similar a undefined reference to symbol 'pthread_create@@GLIBC_2.2.5!

Agregar la siguiente opción LDFLAGS='-pthread' al momento de realizar la configuración.

  • ¡El comando make install finaliza con un mensaje similar a mkdir: no se puede crear el directorio «/opt/bochs-…!

Como /opt/ solo puede ser modificado por root, se debe ejecutar sudo make install

  • ¡Instale la aplicación en /tmp/ y al reiniciar la PC se borró!

Efectivamente es el funcionamiento esperado, ya que /tmp/ es un directorio de ficheros no persistentes. Por este motivo se debe instalar en /var/tmp/.

  • ¿Puedo instalar el Bochs en otra ubicación?

NO. La ubicación indicada permite que todos los scripts sean compatibles facilitando el trabajo de desarrollo y evaluación.