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.
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).
tar -xzvf bochs-MM.mm.vv.tar.gz -C /su_directorio_temporal
man tar
cd su_directorio_temporal/bochs-MM.mm.vv/ ls
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.
Para la configuración de la interfaz de depuración interna de Bochs se deben seguir los siguientes lineamientos:
./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.
make sudo make install
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
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
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
A continuación se detallan las opciones más relevantes para utilizar con el depurador interno del Bochs.
, options="gui_debug"
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:
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
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>
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.
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
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
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.
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
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)
En el caso de querer analizar el stack, se puede optar por dos alternativas.
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.
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
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
Agregar la siguiente opción LDFLAGS='-pthread' al momento de realizar la configuración.
Como /opt/ solo puede ser modificado por root, se debe ejecutar sudo make install
Efectivamente es el funcionamiento esperado, ya que /tmp/ es un directorio de ficheros no persistentes. Por este motivo se debe instalar en /var/tmp/.
NO. La ubicación indicada permite que todos los scripts sean compatibles facilitando el trabajo de desarrollo y evaluación.