Anda di halaman 1dari 8

Universidad de la Repblica | Facultad de Ingeniera | Inco | Arquitectura de

Computadores 2
2008

Arquitectura de
Computadores 2
Laboratorio 1
Documentacin de
La Solucin Implementada

Integrantes

C.I.

Dufrechou Lasca, Ernesto


Almeida Rodrguez, Alberto Emmanuel
Funez Gutierrez, Juan Ernesto

4.506.720-7
4.323.204-0
3.975.469-4

InformeObligatorio1.Pagina1de8

Universidad de la Repblica | Facultad de Ingeniera | Inco | Arquitectura de


Computadores 2
2008

1 Introduccin
1.1 Introduccin
El propsito de este documento es brindar una descripcin general del Diseo
de la solucin implementada para resolver el problema planteado en el primer
laboratorio de Arquitectura de Computadores 2.

1.2 Estructura del documento


El documento esta dividido en dos partes, la introduccin y la descripcin de la
solucin. Esta ltima esta subdividida en dos partes, que son las partes A y B
del obligatorio.

2 Descripcin de la Solucin Implementada


2.1 Parte A
La solucin de la parte A del obligatorio fue resuelta en base a la referencia 3
http://www.osdever.net/tutorials/brunmar/tutorial_03.php brindada por los
profesores del curso en la letra del mismo. De todas maneras la solucin es
explicada a continuacin.

2.1.1 Bootloader (bootloader.asm)


El bootloader tiene como funcion principal cargar desde la imagen de diskett los sectores
correspondientes al kernel y pasar a modo protegido para luego ceder el control a la rutina main
de dicho kernel. Esta parte muestra un pseudocdigo de nuestra solucin. Los comentarios
indican lo que se debe hacer en el cdigo real.

Pseudocdigo:
InformeObligatorio1.Pagina2de8

Universidad de la Repblica | Facultad de Ingeniera | Inco | Arquitectura de


Computadores 2
2008
Usar instrucciones de 16 bits;

// modo real [BITS 16]

Poner rutina en la dir 0x7C00;

// Donde la BIOS comienza a correr al comenzar

Repetir
Reset diskette;
Hasta que no haya error;

// Se utiliza la int 0x13 con el reg AH en 0


// Si reg AL<>0 hubo error

Repetir
seteo parmetros;

// indico cuantos sectores se van a cargar y donde

cargar sectores;

// se utiliza la misma int 0x13 con el reg AH en 02h

Hasta que no haya error;

// Si reg AL<>0 hubo error

Deshabilitar interrupciones;

//cli

Cargar gdt;

//lgdt

Modo protegido;

// el bit 0 de CR0 en 1 y un jmp

Usar instrucciones de 32 bits;

// modo real [BITS 32]

DS=SS =10h;
ESP= 90000h;

// tope del stack

Saltar a ejecutar main();

//jmp 08h:1000h

//En esta parte se crea la gdt


Gdt:
Null;
Code segment;
Data segment;
Endgdt
Rellenar con ceros el sector;
Firma de disco booteable;

// dw 0AA55h

2.1.2 Bibliotecas del Kernel (video.c, ports.c)


La pantalla:
La pantalla es interpretada como una matriz de tamao 25x80 (25 filas 80 columnas) donde
cada posicin es representada por dos bytes. El primero almacena el caracter ASCII que se
imprime en esa pocisin y en el segundo se especifican opciones de formato (por ej el color de
fondo y el de la letra). El espacio de memoria que representa la pantalla comienza por la
direccin 0xB8000.

El cursor:
La posicin del cursor se almacena en dos registros de 8 bit ya que las posibles posiciones son
80*25 = 2000 > 256 que sera lo que se puede especificar con uno solo. Luego tanto para saber

InformeObligatorio1.Pagina3de8

Universidad de la Repblica | Facultad de Ingeniera | Inco | Arquitectura de


Computadores 2
2008
en que posicin se encuentra el cursor como para posicionarlo, se debe especificar primero a
que registro (indicando el ndice 14 o 15) se va a modificar o leer y luego se lo lee o escribe.
Esto se hace mediante los puertos 0x3D4 y 0x3D5 respectivamente. El registro ndice 14 es el
byte mas significativo de la posicin del cursor y el 15 el menos significativo.

Funciones de video:
Tenemos las funciones de limpiar la pantalla (clrscr) que lo que hace nicamente es colocar el
caracter ASCII 0 con el fondo y color 0xF en toda la pantalla y luego posicionar el cursor en
(0,0). Por otra parte la funcin print() escribe en pantalla el string parmetro (que es un array de
chars) a partir de la posicin del cursor (tal como se explic anteriormente), y por ltimo le suma
a la posicin del cursor el largo del string.

Ports.c:
Tanto la funcin in como out son una lnea usando assembler embebido en lenguaje C de las
operaciones in y out de assembler.

2.1.3 Main.c
El main limpia la pantalla usando la funcin clrscr() detallada anteriormente, imprime el mensaje
Arquitectura de Computadores 2 usando la funcion print y por ultimo entra en loop infinito.

InformeObligatorio1.Pagina4de8

Universidad de la Repblica | Facultad de Ingeniera | Inco | Arquitectura de


Computadores 2
2008

2.2 Parte B
En esta parte se utiliz el bootloader de la parte A con muchos agregados para soportar las
interrupcines, as como cumplir con el resto de los requerimientos. Tambin fueron utilizadas
las bibliotecas antes mencionadas. En esta seccin se comentar acerca de los agregados del
bootloader y la forma en que se solucion el problema de manejar el cronmetro con dos
interrupciones.

2.2.1 bootloader.asm
Estructura:
Tenemos tres TSSs (Task State Segment) uno para el main, uno para la rutina de atencin a la
interrupcin del timer y otro para la rutina del teclado. El TSS es el lugar donde la CPU salva el
contexto de la tarea que esta ejecutando para darle la CPU a otra; entre otras cosas guarda el
IP (instruccin pointer) el DS, CS, SS y el registro de flags. Cada TSS es accesible mediante un
TSS-descriptor en la GDT (General Descriptor Table).
Para el main se defini un segmento de cdigo que ocupa toda la memoria y uno de datos que
tambin comienza en la posicin 0 y se extiende hasta la 0xFFFF. Estos segmentos son
compartidos con el timer y se encuentran especificados en la GDT.
En cuanto a el teclado fueron definidos segmentos de cdigo y datos especficos para esa tarea
y por lo tanto fue necesaria una tabla LDT (Local Descriptor Table) la cual es referenciada desde
la GDT con un LDT-descriptor e indirectamente desde el TSS del teclado haciendo referencia
al ndice en la GDT donde se encuentra dicho LDT-descriptor. En el caso del timer como no
tiene LDT, la referencia se pone en 0.
Por otra parte se tiene la IDT (Interrupt Description Table). Esta tabla dice bsicamente donde
esta la rutina de atencin a las interrupcines. Los ndices 8 y 9 son los del timer y el teclado
respectivamente. En esta tabla pueden haber tres clases de Gate descriptors, Task gate,
Interrupt gate y Trap gate descriptors. Como en el obligatorio se pidi que las rutinas de
atencin a las interrupciones fuesen tareas distintas a las interrumpidas era necesario definir
Task gate descriptors, los cuales hacen referencia a el ndice en la GDT de los TSS-descriptors
de cada una de las rutinas.

InformeObligatorio1.Pagina5de8

Universidad de la Repblica | Facultad de Ingeniera | Inco | Arquitectura de


Computadores 2
2008

Pseudocdigo:
Leer sectores desde diskette;

//Como en la parteA

Deshabilitar interrupciones;

//cli

Levantar gdt;

// lgdt

Levantar idt;

//lidt

Pasar a modo protegido;

//Parte A

Inicializacin de TSS del timer;


Inicializacin de TSS del teclado;
TR = indice en la gdt del TSS del main //ltr
Permitir interrumpir al timer y el teclado;

//out 0x21,0fch

Saltar a ejecutar main();

//jmp 08h:1000h

//Creacin de las tablas y la firma de que es un disco booteable

PIC 8259:
Este PIC es a travs del cual se indica qu interrupcines de hardware (de las que son
enmascarables) pueden interrumpir. La CPU puede comunicarse con este PIC mediante los
puertos 0x21 y 0x20. El puerto 0x21 es un registro de 8 bit en donde se indica con un cero si la
interrupcin correspondiente a determinado bit esta habilitada. En nuestro caso se manda a este
puerto el valor 0xFC que es 1111 1100. El primer bit indica que el timer puede interrumpir y el
segundo es para el teclado.
A este mismo PIC se le debe avisar cuando termina la rutina de interrupcin del dispositivo por
la cual se invoc. Para esto se manda un 0x20 al puerto 0x20. De no hacerse esto el PIC no
avisar de la prxima interrupcin del dispositivo, dado que el PIC enmascara las prximas
interrupcines del dispositivo que interrumpi hasta que no se le avise que y fue atendida y que
puede volver a interrumpir.

Restricciones de localidad en memoria:

La rutina del main queda en la direccin 1000h porque este es el destino a partir del
cual se cargan los sectores subsiguientes en el bootloader.

InformeObligatorio1.Pagina6de8

Universidad de la Repblica | Facultad de Ingeniera | Inco | Arquitectura de


Computadores 2
2008

El timer queda entre la direccin 1000h y 1500h porque esta rutina va despus del
main() en memoria y adems es lo suficiente mente corto el cdigo para no pasarse
mas all de la direccin 1500h.

Las variables globales en la direccin 1500h son especificadas en el linker con la


directiva .data, en ambos casos.

La base del stack del teclado y el timer fueron considerados en sus respectivos TSS
y en el caso del main haciendo un mov esp, 070000h

La rutina de atencin al teclado quedo en la direccin 2000h por que su segmento


de cdigo fue asignado en esa posicin (en el TSS). Y no se pasa de la direccin
25001h porque al igual que el timer es un cdigo reducido.

2.2.2 Rutinas de interrupcin y main


El main de la parte B es igual de simple que el anterior. La nica diferencia con el anterior es
que este habilita las interrupciones.
Decidimos que el timer sea el nico encargado de imprimir en pantalla el cronometro. El teclado
nicamente deja en una variable global la tecla presionada (su scancode correspondiente a la
bajada de la tecla) cuando esta es una de las teclas validas. En otro caso no modifica la variable
global dejndola sin actualizar para que el timer no haga nada al respecto. En el caso de las
flechas se hace una lectura en dos pasos ya que la tecla presionada se lee del puerto 0x60 con
lectura de un byte mientras que el cdigo de las flechas es de dos bytes. De leerse solo la
segunda vez que interrumpe el teclado por una de las flechas pudiese confundirse el 8 y el 2
del teclado numrico con la flecha de arriba y abajo respectivamente. Con esta lectura en dos
pasos (usando la bandera flecha) logramos respetar que toda tecla que no sea una de las
teclas vlidas no haga nada.
El timer en cada interrupcin se fija si tiene que actualizar el cronometro porque se presiono una
tecla o porque se supero los 18 tics que indican que se tenga que incrementar en uno la
cantidad de segundos.

InformeObligatorio1.Pagina7de8

Universidad de la Repblica | Facultad de Ingeniera | Inco | Arquitectura de


Computadores 2
2008

Pseudocdigo del teclado:


Chartecla_oprimida=0;
voidteclado()
charaux=in(0x60);
inicio:
Si(auxesunateclavalida)Entonces
tecla_oprimida=aux;
out(0x20,0x20);
iret
gotoinicio;
fin_teclado

Pseudocdigo del timer:

Chartecla_oprimida=0;
Inttic=0;
Booleanpausa=false
voidtimer()
inicio:
Si(tecla_oprimida<>0)
Dependedelcaso
CasoP
pausa=true;
CasoS
pausa=false;
CasoFlecha_arriba
Incrementarcronometro;
CasoFlecha_abajo
Decrementarcronometro;
Fin_depende
Tecla_oprimida=0;
Fin_si
Si(notpausa)tic++;
Si(tic=18)
Incrementarcronometro;
tic:=0
Fin_si
Si(hubocambios)Borraeimprimenuevocronometro
out(0x20,0x20);
iret
gotoinicio;
fin_timer

InformeObligatorio1.Pagina8de8

Anda mungkin juga menyukai