tpe minix

25
TRABAJO PRÁCTICO ESPECIAL DE SISTEMAS OPERATIVOS Tema: Diseño e implementación de un servidor gráfico con soporte para mouse para Minix 2.0.0 Docentes: Etchegoyen, Hugo Vallés, Santiago Integrantes: Liverotti, Ignacio Migliorisi, Sebastián Sánchez Romero, Carlos Instituto Tecnológico de Buenos Aires 2006

Upload: estuardo-fuentes

Post on 30-Sep-2015

2 views

Category:

Documents


0 download

DESCRIPTION

Minix Documentacion

TRANSCRIPT

TRABAJO PRCTICO ESPECIAL N 3 DE SISTEMAS OPERATIVOS

TRABAJO PRCTICO ESPECIAL DE SISTEMAS OPERATIVOS

Tema: Diseo e implementacin de un servidor grfico con soporte para mouse para Minix 2.0.0

Docentes:

Etchegoyen, Hugo

Valls, Santiago

Integrantes:

Liverotti, Ignacio

Migliorisi, Sebastin

Snchez Romero, Carlos

Instituto Tecnolgico de Buenos Aires

2006

TABLA DE CONTENIDOS

3Tema elegido

3Diseo del servidor grfico LittleGL

3Caractersticas del diseo original

4Implementacin

4Problemas encontrados durante la implementacin

6Punto flotante

6Tamao de los archivos de cdigo fuente

7Copia del buffer auxiliar a la memoria de video

7Cambio de enfoque

8Diseo del driver para mouse

8Listado de los fuentes de Minix modificados y los fuentes nuevos

8Implementacin del lado del kernel

14Implementacin del servidor

16Implementacin de la system call

16Manuales de usuario

17Instalacin y desinstalacin

17Servidor LGL

17Programas de test

17Nofnc

18Mouse en consola

18Rect

18Buffer

18Conclusin

18Referencias

Tema elegido

Para el presente trabajo se opt por desarrollar un servidor grfico con soporte para mouse para Minix 2.0.0, dos componentes de software de los cuales Minix, por tratarse de un sistema operativo con fines acadmicos, carece.

A lo largo de este informe explicaremos las caractersticas de ambos componentes, analizaremos los archivos de Minix que tuvieron que ser modificados para permitir su incorporacin, describiremos su forma de uso y finalmente analizaremos los programas de prueba propuestos.

Diseo del servidor grfico LittleGL

En las prximas secciones analizaremos el diseo del servidor grfico LittleGL: estudiaremos cul fue su diseo original y comentaremos tambin los problemas encontrados durante la implementacin los cuales nos forzaron a reducir radicalmente la complejidad del mismo.

Caractersticas del diseo original

El servidor grfico diseado originalmente tena la finalidad de proveer a los programas que se ejecuten en el anillo de usuario una capa de abstraccin hacia el hardware grfico. Puesto que el adaptador VGA (Video Graphic Array) constituye el mnimo comn denominador entre todas las placas de video para computadoras personales ya que todas ellas incluyendo las aceleradoras grficas- cuentan con la circuitera necesaria para proveer los servicios brindados por un adaptador de este tipo, se decidi realizar la implementacin del servidor grfico teniendo en mente que el target seran estos adaptadores.

El servidor grfico originalmente tomaba prestadas algunas partes del diseo de la API OpenGL [1], y de ah deriva su nombre. OpenGL es un conjunto de especificaciones desarrolladas a principios de la dcada del 90 por SGI para una API multi-lenguaje y multi-plataforma para la generacin de imgenes 2D y 3D. Cualquier fabricante de hardware grfico que busque ser compatible con OpenGL deber proveer un driver para su dispositivo que implemente las especificaciones anteriormente mencionadas. Anlogamente, cualquier programador puede elegir escribir sus aplicaciones grficas utilizando esta API tal como la define el estndar. El beneficio es mutuo, puesto que, en el caso del fabricante de hardware, se ofrece una buena razn para que los usuarios compren sus dispositivos ya que estos soportarn todas las aplicaciones escritas con la API y, en el caso del programador, el beneficio radica en que su aplicacin podr ser ejecutada por todas aquellas computadoras que posean una placa grfica compatible con el estndar. Adems de eso, la API provee una caracterstica muy importante que consiste en la capacidad de emular por software aquellas funciones que no sean soportadas por el hardware. Si bien este sistema producir un rendimiento de la aplicacin no del todo ptimo, cabe mencionar que evitar que el programador de la aplicacin tenga que escribir cdigo especfico para cada dispositivo creando, adems, una mayor claridad en el cdigo de la aplicacin.

Tal como explicamos anteriormente, LittleGL intentaba ser una versin reducida de OpenGL y, como tal, no contara con opciones multi-lenguaje (aunque se pueden escribir bindings en cualquier lenguaje que invoquen a las system calls) ni soporte para hardware 3D, puesto que los fabricantes de hardware no ponen los esquemticos de sus circuitos a disposicin del pblico. Por esta razn, incorporaramos en LittleGL un flag en la funcin de inicializacin de la API que indica si la aplicacin sera ejecutada sacando provecho de la aceleracin grfica por hardware, si la hubiera, o indicando si debera forzarse su ejecucin a travs del modo software, es decir, dejndole la carga computacional para el renderizado a la CPU. De esta manera, dejaramos la puerta entreabierta para que, si algn da se llegaba a fabricar un dispositivo grfico con un driver para LittleGL, las aplicaciones de usuario pudieran sacar provecho de l.

Acorde a la estructura de Minix, el diseo original tena previsto hacer una subdivisin de la API grfica en 3 partes: usuario, servidor y task. La idea original era que el usuario tuviera acceso a la definicin de unas pocas estructuras de la API, tales como la definicin de un vrtice, un polgono o una matriz de transformacin y que le pasara punteros a estas estructuras al servidor en un mensaje junto con una constante que indicara la tarea que este deba realizar. El servidor sera entonces quien se dedicara a operar sobre dichas estructuras insertando las primitivas bsicas (tringulos) en una lista de renderizado que, finalmente, sera transferida hacia el task para que ste la dibuje.

Implementacin

Se opt por fraccionar la primera parte del desarrollo en dos partes que pudieran realizarse en forma paralela. Ms especficamente, estas consistan en:

Lograr poner a la placa VGA en modo grfico, imprimir un pxel y volver a modo texto.

Implementar toda la funcionalidad necesaria para el clculo y el renderizado de primitivas 3D utilizando algoritmos de software.

Puesto que Minix no ofrece un entorno de trabajo lo suficientemente cmodo para el desarrollo de un mdulo con una gran cantidad de cdigo fuente, se decidi implementar la primera fraccin en Minix mientras que la segunda (que es independiente de la plataforma) fue implementada en Windows utilizando la librera multimedia multiplataforma SDL [2], la cual, entre otras cosas, provee acceso directo a la memoria de video. Luego de eso, el plan original consista en migrar el cdigo realizado en SDL hacia Minix y, dada la naturaleza multiplataforma de la librera, el proceso de migracin consistira solamente en hacer un pequeo cambio en cada funcin de dibujado para que, en lugar de dibujar sobre una superficie de SDL, lo hiciera sobre un buffer propio que luego sera copiado a la memoria de video mediante una funcin de copia.

Problemas encontrados durante la implementacin

El primer problema encontrado consisti en lograr poner a la placa de video en modo grfico en Minix. Si bien existe mucha documentacin en la red sobre cmo programar la placa VGA, la mayor parte corresponde a publicaciones de principios y mediados de la dcada del 90 y, por lo tanto, hacen uso de la interrupcin 10h de BIOS lo cual era til en esa poca puesto que DOS (que utiliza las interrupciones de BIOS) era el sistema operativo ms popular. El adaptador VGA tiene la capacidad de ser configurado en diversos modos de operacin, muchos de ellos para mantener una compatibilidad hacia atrs con placas de video ms antiguas, tales como EGA y CGA. Los modos grficos ms interesantes para trabajar son el modo 13h y el modo X.

El modo 13h est documentado en forma oficial y, bsicamente prepara un arreglo lineal de 64K que comienza en la direccin de memoria A000 y mapea el pxel superior izquierdo con el primer byte del arreglo y asigna en forma sistemtica el segundo pxel de la primer lnea del monitor con el segundo elemento del arreglo, el tercer pxel con el tercer elemento y as sucesivamente hasta cubrir los 64K, obteniendo entonces una resolucin total de 320x200. El modo 13h es un modo paletizado, esto es, utiliza una paleta de 256 colores cuyas entradas pueden ser configuradas en forma individual asignndole una intensidad de rojo, de verde y de azul. Bsicamente, el proceso de dibujado consiste en escribir valores entre 0 y 255 sobre los bytes que se encuentran mapeados a la memoria de video obteniendo el color que se encuentre almacenado en esa entrada de la paleta sobre los pxeles correspondientes. Si bien este modo ofrece una interfaz simple de programar, su principal carencia es que no permite la implementacin de la tcnica de page-flipping y, por ende, todo el dibujado debe ser realizado utilizando la tcnica de double-buffering.

La tcnica de page-flipping consiste en dibujar el frame de animacin actual en una seccin de la memoria de video que sea invisible, esto es, una seccin de la memoria distinta a la que est escaneando el monitor para dibujar la imagen. Bsicamente, mientras el monitor se encuentra dibujando el frame actual (encendiendo los pxeles del monitor en forma acorde a la informacin que se encuentra a partir de la posicin donde comienza la parte visible de la memoria de video), el programa dibuja el prximo frame en otra seccin de la memoria y, cuando el rayo de barrido alcanza la parte inferior derecha de la pantalla, se cambia el puntero para que ste apunte hacia la seccin de memoria donde se dibuj el ltimo frame y el rayo de barrido comience a barrer esa nueva seccin. De esta forma, se logra una animacin fluida y se evita una anomala grfica conocida como tearing, que se produce al intentar modificar la memoria de video que el rayo de barrido se encuentra dibujando y que, por estar mezclando informacin antigua con informacin actual, produce una imagen cortada.

La tcnica de double-buffering consiste en dibujar el prximo frame en un buffer en memoria y, nuevamente, cuando el rayo de barrido llega hasta la parte inferior derecha de la pantalla se copia por software- el buffer en memoria hacia la seccin visible de la memoria de video. Para ver mayor informacin sobre estas tcnicas, consultar [7], [8] y [9].

A diferencia del modo 13h, el modo X no est documentado en forma oficial. Este modo de operacin es un tanto ms complejo de programar puesto que no se opera sobre un arreglo lineal sino que se trabaja sobre planos. Si bien la forma de acceder a cada pxel es un tanto ms compleja, permite acceder a una mayor porcin de la memoria de vdeo y, por lo tanto, usar la tcnica de page-flipping (adems de permitir utilizar una resolucin mayor). Para mayor informacin respecto a la programacin de este modo, sugerimos consultar [3].

Afortunadamente, encontramos un sistema operativo casero llamado LunarOS [4] que tena implementada una rutina para poner a la placa en modo grfico sin hacer uso de las interrupciones de BIOS, as que tomamos su cdigo fuente y lo adaptamos a nuestras necesidades. Puesto que LunarOS no contaba con la capacidad de volver al modo texto, el cdigo utilizado para realizar esta tarea fue adaptado de [5].

Hasta esta parte del desarrollo, la mayor cantidad de inconvenientes encontrados fueron dos: poner a la placa en modo grfico y tener acceso desde el servidor hacia la memoria de video. Lo primero se debi a que carecamos de un conocimiento completo sobre el hardware que conforma la VGA y, por tratarse de una placa muy compleja, en varios momentos nos encontramos trabajando a ciegas, intentando lograr nuestras metas por el mtodo de prueba y error.

El segundo problema, que consista en otorgarle acceso al servidor hacia la posicin de memoria A000, se resolvi en una forma relativamente rpida: se defini un nuevo segmento que comience en la direccin A000 lo suficientemente extenso como para abarcar toda la porcin visible de la memoria de video.

Mientras se intentaba poner a la placa en modo grfico en Minix, se trabajaba en forma paralela en el desarrollo de las funciones de dibujado en la plataforma Windows. Una vez que se logr el primer objetivo, la tarea consistira en migrar el cdigo de clculo y de dibujado de primitivas 3D hacia Minix.

Los problemas encontrados durante la nueva etapa fueron muchos y muy variados. Explicaremos a continuacin, a modo de resea, los ms significativos.

Punto flotante

Uno de los primeros problemas encontrados al migrar la librera de clculo y dibujado de primitivas 3D hacia Minix consisti en que obtenamos resultados invlidos desde el mdulo de clculo (3DPipeline.c), los cuales eran realizados con variables de punto flotante. El problema se deba a que estbamos compilando el cdigo sin usar la opcin -f del compilador cc (que sirve para indicarle que debe emular el punto flotante por software, ya que cc no ofrece soporte para poder utilizar la unidad de punto flotante del hardware) y, por ende, los clculos no eran realizados en forma correcta. Todo este asunto fue bastante frustrante, puesto que como desarrollador uno esperara que un compilador con semejante limitacin haga mayor nfasis sobre todo este asunto en su documentacin.

Tamao de los archivos de cdigo fuente

Otro de los problemas encontrados, tanto o ms frustrante que el anterior, consisti en la incapacidad de cc en compilar un archivo de cdigo fuente de, aproximadamente, 8000 lneas (RendHEL.c). Para resolver este problema fue necesario fraccionar el archivo en diez partes y mover la declaracin de la mayora de las funciones (que eran estticas al mdulo para que no puedan ser accedidas por fuera) hacia un header, lo cual rompi completamente el ocultamiento que habamos planificado en un principio.

Copia del buffer auxiliar a la memoria de video

El ltimo problema significativo, y por el cual el trabajo final no pudo realizarse tal como lo planificamos, consisti en que no pudimos lograr copiar un arreglo de 64K residente en la memoria RAM hacia la memoria de video. Tal como se explic anteriormente, este arreglo sera utilizado como un buffer en el cual se realizara todo el renderizado para luego copiar su contenido en el momento en que el rayo de barrido alcanzara la seccin inferior derecha de la pantalla.

Despus de mucho trabajo, no pudimos conseguir copiar este arreglo en forma correcta. Ms an, una misma imagen de Bochs produca un cierto resultado en una computadora y uno completamente distinto en otra (ambas computadoras utilizaban la misma versin de Bochs).

Al no poder copiar el buffer en memoria RAM hacia la memoria de video, nuestros planes de lograr animacin 3D fluida se vieron frustrados por lo que, tal como detallaremos en la prxima subseccin, decidimos mover el enfoque del trabajo.

Cambio de enfoque

Debido a los problemas explicados en la seccin anterior y a nuestra imposibilidad de resolver el ltimo de ellos, LittleGL no cuenta con la capacidad para el renderizado de primitivas 3D. Por lo tanto se cambi, casi a ltimo momento, el enfoque hacia una librera ms simple que permitiera el renderizado de primitivas 2D. Puesto que seguimos sin contar con los medios para usar una tcnica de animacin como double-buffering o page-flipping, la librera tiene sus limitaciones. Sin embargo, cumple con el objetivo de mostrar cmo agregar un nuevo servidor a Minix.

La interfaz actual de LittleGL consiste entonces en un nica system call que acepta diversos tipos de mensajes, los cuales permiten realizar las siguientes tareas:

Inicializar el sistema.

Cerrar el sistema.

Limpiar la pantalla en modo grfico.

Cambiar el color asociado a una entrada de la paleta de colores.

Dibujar un pxel.

Dibujar una lnea.

Dibujar un crculo.

El cdigo que implementa toda esta funcionalidad se encuentra en el archivo /usr/src/lgl/commands.c

Diseo del driver para mouse

Para implementar el mouse, se agreg un nuevo manejador de interrupcin que atiende a tal dispositivo. El manejador de interrupcin recolecta la informacin que enva el controlador de teclado (que es el encargado de dialogar con el mouse). Una vez que el manejador finaliz de armar un paquete, este lo decodifica y llena una estructura para que la tarea de la consola la recupere. En este punto se simula que ocurri un evento para que la consola enve la informacin a LGL. El servidor LGL se guarda la nueva informacin provista por la tarea TTY para que el usuario posteriormente la solicite.

Listado de los fuentes de Minix modificados y los fuentes nuevosImplementacin del lado del kernel

Lo primero que se modific de los fuentes de Minix fue agregarle soporte al un nuevo servidor:

Se agrego una constante simblica que representa el nmero de servidor LGL (Lo utilizan las funciones que envan mensaje a este servidor), al igual que MM y FS, esta definicin se realiza en /usr/include/lib.h:

#define MM 0

#define FS 1

#define LGL 2

El paso siguiente es crear otra constante que permita habilitar o deshabilitar el uso del servidor dentro del Kernel (en forma anloga a como lo hace el servidor de red). Esta declaracin se efecta en el archivo /usr/include/minix/config.h:

#define ENABLE_XT_WINI 0/* enable XT winchester driver */

#define ENABLE_ADAPTEC_SCSI 0/* enable ADAPTEC SCSI driver */

#define ENABLE_MITSUMI_CDROM 0/* enable Mitsumi CD-ROM driver */

#define ENABLE_SB_AUDIO 0/* enable Soundblaster audio driver*/

#define ENABLE_LITTLEGL 1/* enable LittleGl driver */

Se agrega una constante simblica que representa el nmero de proceso del servidor LGL. Al igual que MM y FS, esta definicin se realiza en /usr/include/minix/const.h:

#define MM_PROC_NR 0/* process number of memory manager */

#define FS_PROC_NR 1/* process number of file system */

#define LGL_PROC_NR 2/* process number of LittleGl server */

Tambin se agrega la constante ENABLE_LITTLEGL a las definiciones del proceso init y a la constante que indica el comienzo de los programas de usuario.

#define INIT_PROC_NR(INET_PROC_NR + ENABLE_NETWORKING + ENABLE_LITTLEGL)

/* init -- the process that goes multiuser */

#define LOW_USER(INET_PROC_NR + ENABLE_NETWORKING + ENABLE_LITTLEGL)

/* first user not part of operating system */

Y adems se agrega a la cantidad de tareas, para que el kernel tenga conocimiento del servidor LGL.

/* Number of tasks. */

#define NR_TASKS (9 + ENABLE_WINI + ENABLE_SCSI + ENABLE_CDROM

+ ENABLE_NETWORKING + 2 * ENABLE_AUDIO + ENABLE_LITTLEGL)

Se agrega el archivo /usr/include/minix/lgl.h que contiene la declaracin de las constantes utilizadas para la interrupcin de Mouse y el apagado de LGL por teclado:

#define LGL_INT_SHUTDOWN 90

#define LGL_INT_MOUSE91

Se agrega la declaracin de la libreria lgl.h a /usr/src/kernel/kernel.h

#include

#include

#include

#include

#include

Una vez que se declararon las constantes, el prximo paso es definir el espacio en la tabla de procesos del Kernel. Esto se realiz en el archivo /usr/src/kernel/table.c

PUBLIC struct tasktab tasktab[] = {

{ tty_task,TTY_STACK,"TTY"},

#if ENABLE_NETWORKING

{ dp8390_task,DP8390_STACK,"DP8390"},

#endif

#if ENABLE_CDROM

{ cdrom_task,CDROM_STACK,"CDROM"},

#endif

#if ENABLE_AUDIO

{ audio_task,AUDIO_STACK,"AUDIO"},

{ mixer_task,MIXER_STACK,"MIXER"},

#endif

#if ENABLE_SCSI

{ scsi_task,SCSI_STACK,"SCSI"},

#endif

#if ENABLE_WINI

{ winchester_task,WINCH_STACK,"WINCH"},

#endif

{ syn_alrm_task,SYN_ALRM_STACK, "SYN_AL"},

{ idle_task,IDLE_STACK,"IDLE"},

{ printer_task,PRINTER_STACK,"PRINTER"},

{ floppy_task,FLOP_STACK,"FLOPPY"},

{ mem_task,MEM_STACK,"MEMORY"},

{ clock_task,CLOCK_STACK,"CLOCK"},

{ sys_task,SYS_STACK,"SYS"},

{ 0,HARDWARE_STACK,"HARDWAR"},

{ 0,0,"MM"},

{ 0,0,"FS"},

#if ENABLE_NETWORKING

{ 0,0,"INET"},

#endif

#if ENABLE_LITTLEGL

{ 0,0, "LGL"},

#endif

{ 0,0,"INIT"},

};

Ahora que se tiene el espacio del servidor, hay que modificar el archivo que contiene la funcin que verifica si un determinado proceso es un servidor. Si no se modifica este archivo, cuando el programa de usuario enve un mensaje va a ser rechazado por el system call. Esto se realiza en /usr/src/kernel/proc.h

#define isrxhardware(n) ((n) == ANY || (n) == HARDWARE)

#define issysentn(n) ((n) == FS_PROC_NR || (n) == MM_PROC_NR || (n) == LGL_PROC_NR)

#define istaskp(p) ((p) < END_TASK_ADDR && (p) != proc_addr(IDLE))

Lo nico falta agregar es que el servidor LGL tenga acceso a los puertos de la computadora y definir un descriptor de segmento (que apunte a la memoria de video) accesible por LGL.

El acceso a los puertos se define en /usr/src/kernel/main.c utilizando la funcion enable_iop:

bill_ptr = proc_addr(IDLE);/* it has to point somewhere */

enable_iop(proc_addr(2));

lock_pick_proc();

El descriptor de segmento se define en /usr/src/kernel/protect.h:

#define DP_ETH0_INDEX 12/* Western Digital Etherplus buffer */

#define DP_ETH1_INDEX 13/* Western Digital Etherplus buffer */

#define VGA_INDEX 14/* VGA driver descriptor */

#define FIRST_LDT_INDEX 15/* rest of descriptors are LDT's */

Una vez definido el descriptor de segmento, este se debe cargar en la tabla GDT del sistema, esta tarea se realiza en el archivo /usr/src/kernel/protect.c:

/* Build scratch descriptors for functions in klib88. */

init_dataseg(&gdt[DS_286_INDEX], (phys_bytes) 0,

(phys_bytes) MAX_286_SEG_SIZE, TASK_PRIVILEGE);

init_dataseg(&gdt[ES_286_INDEX], (phys_bytes) 0,

(phys_bytes) MAX_286_SEG_SIZE, TASK_PRIVILEGE);

/* Build VGA descriptor */

init_dataseg(&gdt[VGA_INDEX], (phys_bytes) 0xA0000,

(phys_bytes) 0xAF000, USER_PRIVILEGE);

/* Build local descriptors in GDT for LDT's in process table.

* The LDT's are allocated at compile time in the process table, and

* initialized whenever a process' map is initialized or changed.

*/

Por ltimo se debe modificar /usr/src/tools/Makefile para agregar a LGL como un servidor ms:

inet=

PROGRAMS=../kernel/kernel ../mm/mm ../fs/fs ../lgl/lgl $(inet) init

programs:

---------

cd ../fs && $(MAKE)

cd ../lgl && $(MAKE)

@if [ `exec ./tell_config ENABLE_NETWORKING` = 0 ]; then \

$(MAKE) image; \

---------

all install clean::

cd ../kernel && $(MAKE) $@

cd ../mm && $(MAKE) $@

cd ../fs && $(MAKE) $@

cd ../inet && $(MAKE) $@

cd ../lgl && $(MAKE) $@

Para que el teclado pueda apagar el servidor LGL, primero hay que definir con qu tecla se va activar la funcion deseada. Esto se realiza en la funcin func_key del archivo /usr/src/kernel/keyboard.c :

case F1:p_dmp(); break;/* print process table */

case F2:map_dmp(); break;/* print memory map */

case F3:toggle_scroll(); break;/* hardware vs. software scrolling */

case F4:lgl_shut(); break;

#if ENABLE_NETWORKING

case F5:dp_dump(); break;/* network statistics */

#endif

case CF7:sigchar(&tty_table[CONSOLE], SIGQUIT); break;

La funcin lgl_shut se define en el archivo /usr/src/kernel/proto.h:

/* dmp.c */

_PROTOTYPE( void map_dmp, (void));

_PROTOTYPE( void p_dmp, (void));

_PROTOTYPE( void reg_dmp, (struct proc *rp));

_PROTOTYPE( void lgl_shut, (void));

Y se implementa en el archivo /usr/src/kernel/dmp.c:

PUBLIC void lgl_shut(void)

{

message shut_msg;

shut_msg.m_type=LGL_CMD;

shut_msg.m1_i1=LGL_INT_SHUTDOWN;

send(2, &shut_msg);

}

Lo nico que realiza la funcin antes citada es enviarle un mensaje LGL indicndole que tiene que apagar el servidor.

Para implementar el servicio del Mouse, primero se defini una estructura para almacenar la informacin pertinente a dicho dispositivo que se encuentra en el archivo

/usr/include/lgl/lgl.h:

typedef struct ms_status_s {

int x;

int y;

int lbutton;

int rbutton;

} MouseStatusType, *lpMouseStatusType;

Esta estructura va ir pasando del kernel al servidor y, de este ltimo, al usuario.

En el archivo /usr/src/kernel/glo.h se encuentra definida la estructura del tipo ms_status_s que utiliza el kernel y adems data_mouse_available que se utiliza para indicar a la tarea TTY que hay informacin nueva del Mouse.

EXTERN clock_t tty_timeout;/* time to wake up the TTY task */

EXTERN int current;/* currently visible console */

EXTERN int data_mouse_available;

EXTERN struct ms_status_s ms_status;

Otra estructura de vital importancia es:

struct ms_s{

int iCurrentPacket;

int iPackets[3];

};

que se encuentra en /usr/src/kernel/keyboard.c. y se declara una variable de ese tipo en el mismo archivo:

PRIVATE struct ms_s ms_data;

PRIVATE struct kb_s kb_lines[NR_CONS];

Que se inicializa en la funcion kb_init:

slock_off = 1;

esc = 0;

/* Set mouse initial values */

ms_data.iCurrentPacket = 0;

ms_data.iPackets[0] = 0;

ms_data.iPackets[1] = 0;

ms_data.iPackets[2] = 0;

set_leds();/* turn off numlock led */

Esta estructura almacena la informacin que enva el mouse, para posteriormente ser utilizada por el manejador de interrupciones. Es PRIVATE debido que slo tiene sentido dentro de keyboard.c.

Dentro de keyboard.c se encuentra la inicializacin del mouse que ocurre junto a la del teclado, esto es, en la funcin kb_init:

scan_keyboard();/* stop lockup from leftover keystroke */

out_byte(KB_STATUS, 0x60);

out_byte(KEYBD, 0x43);

kb_wait();

out_byte(KB_STATUS, 0xd4);

kb_wait();

out_byte(KEYBD, 0xf4);

kb_wait();

while(( in_byte(KB_STATUS) & 1) == 0);

in_byte(KEYBD);

put_irq_handler(12, ps2ms_hw_int);

enable_irq(12);

put_irq_handler(KEYBOARD_IRQ, kbd_hw_int);/* set the interrupt handler */

enable_irq(KEYBOARD_IRQ);/* safe now everything initialised! */

El cdigo lo nico que hace es habilitar el Mouse por hardware y declarar un manejador de interrupcin.

La funcin del manejador de interrupcin tambin se declara y se implementa en keyboard.c ya que no tiene sentido que sea accesible por otro mdulo:

FORWARD _PROTOTYPE( void kb_read, (struct tty *tp) );

FORWARD _PROTOTYPE( unsigned map_key, (int scode) );

FORWARD _PROTOTYPE( int ps2ms_hw_int, (int irq));

PRIVATE int ps2ms_hw_int(irq)

int irq;

{

int valor;

ms_data.iPackets[ms_data.iCurrentPacket++]=in_byte(KEYBD);

if(ms_data.iCurrentPacket == 3)

{

ms_data.iCurrentPacket = 0;

ms_status.lbutton = ms_data.iPackets[0] & 0x01;

ms_status.rbutton = (ms_data.iPackets[0] & 0x02) >> 1;

if(ms_data.iPackets[1] != 0)

{

if(ms_data.iPackets[0] & 0x10)

{

if(ms_status.x > 0)

{

ms_status.x--;

}

}else{

if(ms_status.x < 320)

{

ms_status.x++;

}

}

}

if(ms_data.iPackets[2] != 0)

{

if(ms_data.iPackets[0] & 0x20)

{

if(ms_status.y < 200)

{

ms_status.y++;

}

}else{

if(ms_status.y > 0)

{

ms_status.y--;

}

}

}

}

data_mouse_available=1;

force_timeout();

return 1;

}

La funcin antes citada espera hasta que lleguen los 3 paquetes de informacin que enva el mouse, los procesa, y le avisa a la tarea de TTY que hay nueva informacin disponible.

Por ultimo en la funcin de /usr/src/kernel/tty.c se encuentra el cdigo que procesa la interrupcin de mouse y se encarga de enviarle un mensaje al servidor LGL:

receive(ANY, &tty_mess);

/* A hardware interrupt is an invitation to check for events. */

if (tty_mess.m_type == HARD_INT)

{

if(data_mouse_available)

{

mouse_mess.m_type=LGL_CMD;

mouse_mess.m1_i1=LGL_INT_MOUSE;

mouse_mess.m1_i2=ms_status.x;

mouse_mess.m1_i3=ms_status.y;

mouse_mess.m1_p1=(char *) ms_status.lbutton;

mouse_mess.m1_p2=(char *) ms_status.rbutton;

send(2, &mouse_mess);

data_mouse_available=0;

}

continue;

}

/* Check the minor device number. */

line = tty_mess.TTY_LINE;

Implementacin del servidor

Toda la informacin que maneja el servidor est definida en el archivo /usr/include/lgl/lgl.h, donde estn las estructuras de las formas geomtricas bsicas. Pero lo ms importante es la definicin de los comandos que acepta el servidor:

/* LittleGl commands */

#defineLGL_INIT1

#define LGL_SHUTDOWN2

#define LGL_SETPALENTRY3

#define LGL_SWAPBUFFERS4

#define LGL_PUTPIXEL 10

#define LGL_CLEARSCREEN 11

#define LGL_DRAWLINE12

#define LGL_SETPROCPID 13

#define LGL_GETMOUSE14

#define LGL_DRAWCIRCLE 15

#define LGL_DRAWRECTANGLE 16

Otra definicin importante se encuentra en /usr/include/minix/callnr.h. All est definida la system call LGL_CMD que es el punto de entrada al servidor:

#define SIGNAL 48

#define LGL_CMD 50

#define IOCTL 54

#define FCNTL 55

Al igual que MM y FS el servidor espera esa system call y la deriva en main.c:

/* If the call number is valid, perform the call. */

If (lgl_call < 0 || lgl_call >= NCALLS)

error = EBADCALL;

else

error = (*call_vec[lgl_call])();

De la misma manera que FS y MM, utilizando la tabla de system calls (call_vec) definida en table.c, se declara un manejador para procesar los comandos del servidor:

no_sys,/* 47 = getgid*/

no_sys,/* 48 = (signal)*/

no_sys,/* 49 = unused*/

do_lgl_cmd,/* 50 = lgl_cmd*/

no_sys,/* 51 = (acct)*/

no_sys,/* 52 = (phys)*/

no_sys,/* 53 = (lock)*/

no_sys,/* 54 = ioctl*/

no_sys,/* 55 = fcntl*/

no_sys,/* 56 = (mpx)*/

La funcin do_lgl_cmd se encuentra en commands.c:

PUBLIC int do_lgl_cmd()

{

int command = lgl_in.m1_i1;

switch(command)

{

case LGL_INIT: do_lgl_init(); break;

case LGL_SHUTDOWN: do_lgl_shutdown(); break;

case LGL_SETPALENTRY: do_lgl_setpalentry();break;

case LGL_SWAPBUFFERS: do_lgl_swapbuffers();break;

case LGL_INT_SHUTDOWN: do_lgl_int_shutdown();break;

case LGL_PUTPIXEL: do_lgl_putpixel(); break;

case LGL_CLEARSCREEN: do_lgl_clearscreen(); break;

case LGL_DRAWLINE: do_lgl_drawline(); break;

case LGL_SETPROCPID: do_lgl_set_pid(); break;

case LGL_INT_MOUSE: do_lgl_int_mouse(); break;

case LGL_GETMOUSE: do_lgl_get_mouse(); break;

case LGL_DRAWCIRCLE: do_lgl_drawcircle(); break;

case LGL_DRAWRECTANGLE: do_lgl_drawrectangle(); break;

default: panic("LGL receive error", NO_NUM); break;

}

return (OK);

}

Por ltimo el cdigo que resta slo se encarga de dibujar las formas geomtricas ofrecidas (resto del archivo commands.c). Los archivos lglasm.s y swapbuffers.c contienen cdigo en ensamblador para dialogar con la placa de video.

Implementacin de la system call

La declaracin de la system call se encuentra en /usr/include/unistd.h:

_PROTOTYPE( int unlink, (const char *_path));

_PROTOTYPE( ssize_t write, (int _fd, const void *_buf, size_t _n));

_PROTOTYPE( int lgl_cmd, (int _cmd_type, void * _pData, size_t _n));

La system call, al ser sencilla se implementa en /usr/src/lib/syscall/lgl_cmd.s (slo funciona como un wrapper) y en /usr/src/lib/posix/_lgl_cmd.c se encuentra el cuerpo de la funcin:

PUBLIC int lgl_cmd(cmd_type, pData, n)

int cmd_type;

void * pData;

size_t n;

{

message m;

m.m1_i1=(int) cmd_type;

m.m1_i2=(int) n;

m.m1_p1=(char *) pData;

return(_syscall(LGL, LGL_CMD, &m));

}

La funcin prepara el mensaje para el servidor y lo enva.

Manuales de usuario

Los manuales de usuario del servidor y de las funciones de la librera grfica se encuentran en el diskette y se instalan automticamente por medio del script de instalacin.

Instalacin y desinstalacinServidor LGL

Para instalar todo el sistema, introducir los siguientes comandos en una consola con permisos de root:

#mount /dev/fd0 /fd0

#cd /fd0

#./install.sh

Una vez instalado el sistema, hay que recompilar el kernel y las libreras:

#cd /usr/src/tools

#make hdboot

#cd ../lib

#make install

Y por ltimo compilar los ejemplos provistos:

#cd /root/examples

#make

Para instalar todo el sistema, introducir los siguientes comandos en una consola con permisos de root:

#mount /dev/fd0 /fd0

#cd /fd0

#./uninstall.sh

Una vez desinstalado el sistema, hay que recompilar el kernel y las libreras:

#cd /usr/src/tools

#make clean

#make hdboot

#cd ../lib

#make clean

#make install

Programas de testNofnc

nofnc constituye el primer programa de prueba de nuestro sistema. El objetivo del mismo es mostrar toda la funcionalidad de la librera provista. Para ello, dibuja cada 2 segundos un tipo de figura generada al azar. El programa finaliza presionando la tecla F4.

Mouse en consola

La aplicacin mouse permite al usuario comprobar el funcionamiento del mouse sobre la consola. Bsicamente, este se queda en un ciclo infinito esperando informacin del Mouse y, cuando esta se actualiza, se le muestra al usuario la nueva informacin. El programa finaliza presionando la tecla DEL.

Rect

El programa rect se utiliza para comprobar el funcionamiento del mouse sobre el modo grfico. Permite al usuario desplazar un cursor en forma de rectngulo por toda la pantalla. Si se presiona el botn derecho se dibuja sobre la pantalla y si se presiona el izquierdo el contenido de sta se limpia completamente. El programa finaliza presionando la tecla F4.

Buffer

El objetivo del programa buffer es mostrar al usuario como un buffer de video que se encuentra en el servidor LGL se vuelca a la memoria de video. Este buffer contiene 3 puntos: uno en la esquina superior izquierda, otro en la esquina inferior derecha y un tercero en el centro. Las sucesivas pruebas de este programa muestran que los puntos no aparecen en el lugar esperado. El programa finaliza presionando la tecla F4.

Conclusin

A lo largo de este informe hemos analizado el diseo y la implementacin de un servidor grfico con soporte para mouse para Minix 2.0.0. Discutimos las decisiones de diseo y los problemas encontrados durante la implementacin que no nos permitieron entregar el trabajo que hubiramos deseado.

A modo de referencia, dejamos el cdigo fuente de la librera 3D en el diskette. El cdigo est basado en las discusiones de [6] y ofrece la funcionalidad necesaria para realizar los clculos para proyectar y para dibujar primitivas 3D (tringulos) con interpolacin de colores y mapeado de texturas con opcin de utilizar un bfer Z. Los archivos clave son 3DPipeline.c/h, que implementa las funciones que transforman los vrtices desde un espacio tridimensional hacia la pantalla y RendHEL.c/h (del 1 al 10), que implementan todas las funciones de dibujado.

A pesar de nuestra frustracin por no haber podido entregar el trabajo en forma completa, estamos muy conformes con l puesto que aprendimos muchas cosas de hardware y de teora de sistemas operativos durante su desarrollo.

Referencias

[1]: http://www.opengl.org/

[2]: http://www.libsdl.org

[3]: http://www.gamedev.net/reference/articles/article1698.asp

[4]: http://individual.utoronto.ca/Phibred/LunarOS.htm

[5]: http://ftp.lanet.lv/ftp/mirror/x2ftp/msdos/programming/source/tauron30.zip

[6]: Tricks of the 3D Game Programming Gurus-Advanced 3D Graphics and Rasterization, Andr LaMothe. Sams. June 2, 2003. ISBN: 0672318350.

[7]: http://en.wikipedia.org/wiki/Double_buffering

[8]: http://www.brackeen.com/home/vga/unchain.html

[9]: http://everything2.com/index.pl?node=page%20flipping