Interrupciones en modo protegido

  1. Alpertron
  2. Microprocesadores de la línea Intel
  3. Interrupciones en modo protegido

por Dario Alejandro Alpern

Archivos necesarios

Transcripción

Hola. Mi nombre es Darío Alpern y hoy vamos a ver interrupciones en modo protegido.

Interrupción

Una interrupción es el cambio temporario de flujo del programa que se está ejecutando debido a un evento externo al procesador, por ejemplo apretar un tecla, la llegada de caracteres por el puerto serie, etc.

En el diagrama se puede ver el programa principal que está corriendo hasta que llega un evento de hardware.

En ese momento el procesador termina de ejecutar la instrucción en curso y ejecuta el manejador de la interrupción, que es una subrutina cuyo contenido depende del evento de hardware, por ejemplo puede poner el carácter que llega del puerto serie en una FIFO.

Luego de terminar de ejecutar el manejador de interrupción, el procesador continúa ejecutando el programa principal desde la siguiente instrucción después de la última que había ejecutado antes de que ocurriera la interrupción.

Es importante que el manejador de interrupciones salve el contenido de los registros cuando entra y los recupere antes de salir, ya que en caso contrario, los valores de los registros no serían los esperados y se colgaría el programa o ejecutaría algo no esperado.

8259

Aquí se puede ver cómo se conectan los controladores programables de interrupción (PIC por la sigla en inglés) al procesador.

Originalmente el PIC estaba implementado mediante el chip 8259 de Intel. Actualmente esta funcionalidad se encuentra dentro del chipset en el motherboard de la computadora.

El PIC tiene una interfaz de programación. El primer PIC (configurado como maestro) usa los puertos 20 hexa y 21 hexa y el segundo (configurado como esclavo) usa los puertos A0 hexa y A1 hexa.

Puertos

Los puertos de entrada/salida conforman un espacio separado del de memoria y se utiliza para periféricos que requieran pocas direcciones, como el caso del PIC que necesita dos direcciones para operar.

Aquí se ven las instrucciones que se utilizan para acceder a los puertos tanto para escritura como para lectura. Se pueden leer o escribir 8, 16 ó 32 bits por vez. Como el PIC solo usa 8 bits de datos, usaremos el registro AL para almacenar el dato.

Abajo se puede ver un ejemplo de escritura en un puerto.

8259

El sistema heredado tiene 15 entradas de interrupción denominadas IRQ0 a IRQ15, excepto IRQ2. Actualmente, con APIC, puede haber hasta 224 entradas de interrupción.

Las señales IRQ0 a IRQ7 se conectan al PIC amo y las señales IRQ8 a IRQ15 se conectan al PIC esclavo. Varios de estas señales de interupción son estándar. Por ejemplo IRQ0 viene del timer, IRQ1 viene del teclado, IRQ3 viene del puerto serie COM2, IRQ4 del puerto serie COM1, IRQ8 del reloj de tiempo real, etc.

Máscara de PIC

En general solo queremos habilitar algunas fuentes de interrupción, no todas. Para esto se usa la máscara de interrupciones, que es un registro interno del PIC.

Este registro tiene 8 bits, uno por cada IRQ. Si el bit vale uno, la interrupción está deshabilitada, mientras que si vale cero, la interrupción está habilitada.

Este registro se accede mediante el puerto 21 hexa en el PIC amo y el puerto A1 hexa para el PIC esclavo.

Cuando el timer 0 de 16 bits termina su cuenta, dispara la señal IRQ0 que está marcado con el número 1 en el diagrama. Si la máscara de interrupciones del PIC tiene IRQ0 habilitado y no se está ejecutando esa interrupción u otra de mayor prioridad, entonces el PIC pone a '1' la señal INT (marcado con el número 2) que está conectada a la pata interrupt request del procesador.

Si el procesador tiene el bit 9 del registro EFLAGS a '1', indicando que las interrupciones estándar habilitadas, entonces luego de terminar la instrucción en curso, no continúa con la siguiente instrucción, sino que habilita la señal interrupt acknowledge (marcado con el número 3). Esto enciende el bit correspondiente a la IRQ en curso del registro interno denominado In Service Register (ISR), indicando que el PIC está procesando esa IRQ.

El procesador envía un segundo ciclo de interrupt acknowledge (marcado con el número 4), lo que hace que el PIC envíe el tipo de interrupción (que es un número de 8 bits) por el bus de datos (marcado con el número 5).

Tipo de interrupción

El tipo de interrupción tiene 8 bits. Los cinco bits más significativos se programan durante la inicialización del PIC, mientras que los tres bits menos significativos indican el número de IRQ.

Como hay dos PICs en el sistema, se deben inicializar ambos dispositivos para programarlos con tipos diferentes. Por ejemplo, si queremos que el primer PIC genere tipos 20 hexa a 27 hexa, lo programaremos la parte variable con el número 20 hexa y si queremos que el segundo PIC genere tipos 28 hexa a 2F hexa, lo programaremos con el valor 28 hexa.

IDT

Aquí se puede ver la tabla de vectores de interrupción que usa el procesador cuando está en modo protegido. El formato de la tabla de vectores de interrupción en modo real es diferente y no lo vamos a ver aquí.

La tabla de descriptores de interrupción (en inglés la sigla es IDT (Interrupt Descriptor Table) tiene una compuerta por cada tipo de interrupción. El registro IDT apunta a la compuerta correspondiente al tipo de interrupción cero. A continuación se encuentra la compuerta correspondiente al tipo de interrupción 1, y así sucesivamente hasta el tipo más alto de interrupción que se genere en el sistema. Como existen 256 diferentes tipos de interrupción, la tabla tendrá una longitud máxima de 256 compuertas * 8 bytes/compuerta = 2048 bytes. Si por ejemplo, las interrupciones que se generan están en el rango 0x20 a 0x2F, entonces la tabla tendrá 48 entradas. En este caso el límite de la IDT que deberemos poner en la imagen de la IDTR será 48 * 8 - 1 = 383.

Las compuertas son direcciones lógicas que se componen de selector y offset y tienen el formato que se muestra a la derecha. El tipo de compuerta en el caso de interrupciones es 1110 binario. La dirección lógica apunta al inicio del manejador de la interrupción.

End of Interrupt

Cuando termina el manejador de interrupción, éste debe enviar el comando de Fin de interrupción (End of Interrupt) al PIC. Hay dos tipos de comandos de Fin de Interrupción: específico y no específico. El específico apaga el bit indicado por el comando del registro In Service Register (ISR), mientras que el no específico apaga el bit encendido del In Service Register de la IRQ que tenga mayor prioridad. La prioridad más alta la tiene el IRQ0 y la máscara baja la IRQ7. Nosotros siempre vamos a usar comandos de Fin de interrupción no específicos. Una vez que el bit del In Service Register está apagado, el PIC puede volver a interrumpir el procesador con esa IRQ.

Abajo se pueden ver las instrucciones que se deben ejecutar para enviarle al pic el comando de Fin de interrupción no específico.

Multiplicación

Una vez calculada la semilla pseudoaleatoria, obtenemos un número de 32 bits. Tenemos que convertir ese número en el rango de 0 a EBX exclusive.

Para ello, observando como funciona la multiplicación, se puede ver que la parte alta del producto de 64 bits se almacena en EDX y la parte baja en EAX.

Vamos a ver cuánto vale el producto máximo cuando multiplico por el argumento. Eso ocurre cuando EAX = 232 − 1.

Entonces, haciendo algunas transformaciones se puede ver que el producto es 232 (argum-1) + (232 − argum) donde ambos paréntesis son números que entran en 32 bits.

Comparando las partes altas, es decir las que están multiplicadas por 232, resulta que el máximo valor posible de EDX es argum − 1, por lo tanto EDX está en el rango entre 0 y argum excluyendo el último valor.

Programmable Interval Timer

Originalmente implementado mediante el circuito integrado Intel 8253 y luego por Intel 8254, actualmente se encuentra dentro del chipset en el motherboard.

El PIT tiene 3 canales de 16 bits. El canal cero se conecta a la entrada IRQ0 del controlador de interrupciones. El canal uno se utilizaba junto con el controlador de DMA para refrescar memorias dinámicas. El refresco de las memorias dinámicas hoy en día no usa este canal y por lo tanto está deshabilitado. El canal dos se usa para generar una frecuencia para el parlante en la PC. Para que no suene todo el tiempo, la salida de este canal tiene una compuerta AND lógica que está controlada por el bit 0 del puerto 61 hexa.

Para programar el PIT, se debe escribir una palabra de control en el puerto 43 hexa y luego uno o dos bytes en el puerto correspondiente al canal que queremos programar.

Hay dos fuentes de interrupción: una es el timer que es el que muestra los caracteres y otro es el teclado que es el que borra la pantalla.