Sei sulla pagina 1di 8

Rutinas de Tratamiento de Interrupciones

Primer nivel de manejo de Interrupciones


Toda interrupcin en Linux, pues, tiene como punto de entrada a su rutina de servicio cdigo generado por el bucle de entry.S [arch/i386/kernel/entry.S#L337]. Este cdigo se limita a poner en la pila el nmero de la interrupcin menos 256 y saltar a common_interrupt. La rutina common_interrupt [arch/i386/kernel/entry.S#L358] se encarga de llamar a la macro SAVE_ALL y despus a la funcin C do_irq [arch/i386/kernel/irq.c#L48]. El cdigo en ensablador le pasa a la funcin do_irq() el puntero al contenido de la pila en el registro %eax.

Tras el proceso de la interrupcin, que estudiaremos en el resto de este tema, realizado todo l ya en C por do_irq, se vuelve al cdigo que se haba interrumpido a travs de la rutina ret_from_intr [arch/i386/kernel/entry.S#L161]. Esta rutina comprueba si estamos volviendo a modo usuario, en cuyo caso ejecuta resume_userspace [arch/i386/kernel/entry.S#L167], o bien se nos interrumpi dentro del ncleo (o volvemos a modo virtual 8086), que ejecuta resume_kernel [arch/i386/kernel/entry.S#L178] o restore_all [arch/i386/kernel/entry.S#L260], dependiendo de si estn o no permitidas las expulsiones dentro del ncleo.

Estructuras de Datos
Cada posible tipo de controlador de interrupciones est representado por una estructura del tipo hw_irq_controler [include/linux/irq.h#L38], con los siguientes campos:

typename: Nombre del tipo de controlador. startup, shutdown: Punteros a las funciones que se deben invocar para inicializar y finalizar la actividad sobre una lnea de interrupcin. enable, disable: Punteros a las funciones que se deben invocar para habilitar y deshabilitar una lnea de interrupciones en el controlador. ack: Puntero a la funcin que se debe invocar para indicarle al controlador que el SO ha sido notificado de la llegada de la interrupcin correspondiente. end: Puntero a la funcin que se debe invocar para indicarle al controlador que ya se ha acabado de antender la interrupcin correspondiente. set_affinity: Puntero a la funcin que se debe invocar para establecer que CPUs se encargarn de manejar ciertas interrupciones especficas.

Segundo nivel de manejo: do_irq


La funcin do_irq [arch/i386/kernel/irq.c#L48] realiza las siguientes acciones:

La macro fastcall se transforma en __attribute__((regparm(3))) y se utiliza para pasar los parmetros de la funcin en registros en lugar de utilizar la pila. El nico parmetro de esta funcin estar en el registro %eax y debe contener un puntero al contenido de la pila antes de invocar a la funcin (ver common_interrupt [arch/i386/kernel/entry.S#L358]). Asigna a la variable irq el nmero de la interrupcin depositado en la pila por la rutina de manejo de interrupcin [arch/i386/kernel/entry.S#L349] invocada desde la IDT

(insertado justo antes de los registros que salva SAVE_ALL en common_interrupt [arch/i386/kernel/entry.S#L358]). El tipo del parmetro que recibe do_irq es pt_regs [include/asm-i386/ptrace.h#L23], que refleja el orden en el que se guardan en la pila los diferentes elementos cuando llega una interrupcin (hardware o software).

La macro irq_enter [include/linux/hardirq.h#L98] incrementa el contador que representa el nmero de manejadores de interrupcin que se estn ejecutando de forma anidada. El contador se almacena en el campo preempt_count de la estructura thread_info del proceso actual. Invoca a la funcin __do_IRQ(irq, regs) (le pasa el nmero de la interrupcin y el puntero al contendido de la pila). La funcin irq_exit [kernel/softirq.c#L164] que decrementa el contador de interrupciones anidadas y comprueba si alguna funcin diferible (softirq) est esperando a ser ejecutada. El ncleo slo podr ser interrumpido si el contador de interrupciones anidadas es 0.

Segundo nivel de manejo: status


El campo status de la estructura irq_desc_t puede contener combinaciones de varios estados [include/linux/irq.h#L24] referentes al estado de la lnea de interrupcin: IRQ_INPROGRESS indica que la interrupcin est siendo procesada (probablemente por otra CPU). IRQ_DISABLED indica que la interrupcin est deshabilitada. En este estado el PIC no debera pasarle las interrupciones a la CPU. IRQ_PENDING indica que la interrupcin ya se le ha reconocido al PIC pero que todava no se ha comenzado a ejecutarse el manejador correspondiente. El resto de los posibles valores tienen que ver con la autodeteccin y el reenvio de interrupciones y los sistemas multiprocesadores.

Drivers de Dispositivos
El Kernel de Linux debe poder interactuar con ellos en maneras normales. Cada clase de controlador de dispositivo, carcter, bloque y red, proporciona interfaces comnes que el Kernel usa cuando solicita los servicios de ellos. Estos medios de las interfaces comunes que el Kernel puede tratar a menudo de dispositivos diferentes y sus controladores de dispositivo son absolutamente los mismos. Por ejemplo, SCSI y discos de IDE se comportan muy diferentemente pero el Kernel de Linux usa la misma interface para ambos. Linux es muy dinmico, cada vez que inicia el Kernel de Linux puede encontrarse los dispositivos fsicos diferentes y as la necesidad de controladores de dispositivos diferentes. Linux le permite incluir a controladores de dispositivos en el momento de la estructura del Kernel por va de escritura en su configuracin. Cuando estos controladores se inicializan en el tiempo de arranque ellos no pueden descubrir ningn hardware para controlar. Pueden cargarse otros controladores como mdulos del Kernel cuando son necesitados. Tener suficiente fuerza para esta naturaleza dinmica de controladores de dispositivos, los controladores de dispositivo se registran con el Kernel como son inicializados. Linux mantiene tablas de controladores de dispositivos registrados como parte de sus interfaces con ellos. Estas tablas incluyen los indicadores a las rutinas y a la informacin que sostiene la interface con esa clase de dispositivos.

8.4.1 Dispositivos de carcter

Los dispositivos de carcter, son el ms simple de los dispositivos de Linux, como los archivos, las aplicaciones usan el sistema normal de llamama para abrirlos, leerlos, escribir en ellos y cerrarlos exactamente como si el dispositivo fuera un archivo. Esto es verdad aun cuando el dispositivo es un mdem usndo por el demonio de PPP para conectar un sistema de Linux hacia una red. Cuando un dispositivo de carcter se inicializa su controlador se registra con el kernel de Linux agregando una entrada en el chrdevsvector de estructuras de datos de device_struct. El identificador del dispositivo mayor (por ejemplo 4 para el dispositivo del tty) se usa como un ndice en este vector. El identificador del dispositivo mayor para un dispositivo es fijo. Cada entrada en el vector del chrdevs, es una estructura de datos de device_struct que contiene dos elementos; un indicador al nombre del controlador del dispositivo registrado y un indicador a un bloque de operaciones del archivo. Este bloque de operaciones del archivo tiene direcciones de rutinas dentro del controlador del dispositivo de carcter cada una de las cuales los une con las operacioness del archivo especfico como abrir, leer, escribir y cerrar. El contenido de /proc/devices para los dispositivos de carcter se toma del vector del chrdevs. Cuando un archivo especial de carcter que representa un dispositivo de carcter (por ejemplo /dev/cua0) se abre el kernel para preparar las cosas para que se llamen las rutinas de las operaciones del archivo correctas del controlador del dispositivo de carcter. Simplemente como un archivo ordinario o directorio, cada dispositivo del archivo especial se representa por un inode VFS. El inode VFS para un carcter es el archivo especial, de hecho para todos los archivos especiales de dispositivos, este contiene ambos identificadores mayores y menores para el dispositivo. Este inode VFS

se cre por el filesystem subyacente, por ejemplo EXT2, de la informacin en el filesystem real cuando el nombre del archivo especial de dispositivo es parecido. Cada inode VFS es asociado con un juego de operaciones del archivo y stos son diferentes dependiendo del filesystem que el inode representa. Siempre que un inode VFS representa un carcter el archivo especial se crea, las operaciones del archivo se ponen por defecto a las operaciones del dispositivo de carcter. Estas son operaciones unicas del archivo, la operacin de abrir el archivo. Cuando se abre el archivo especial del carcter por una aplicacin la operacion de abrir el archivo genrico usa el identificador mayor del dispositivo como un ndice en el vector del chrdevs para recuperar las operaciones bloqueadas del archivo para este dispositivo particular. Tambin prepara la estructura de datos del archivo describiendo el archivo especial de caracter, tomando los indicadores de las operaciones del archivo del controlador del dispositivo. Despus de esto todas a las aplicaciones de las operaciones de archivo se trazarn las llamadas a las de los dispositivos de carcter puestos en las operaciones del archivo. FIN TAREA 3 8.4.2 Dispositivos de Bloque Los dispositivos de bloque tambien soportan ser accedidos como los archivos. Los mecanismos usados para mantener el correcto set de operaciones de archivo para abrir el archivo especial de bloque son muy parecidos como en los dispositivos del carcter. Linux mantiene el set de dispositivos de bloque registrados en el vector blkdevs. Eso es, como en el vector del chrdevs, que usa el numero de mayor indice del dispositivo. Sus entradas tambin son las estructuras de datos de device_struct. Los diferentes dispositivos de carcter, tienen clases de dispositivos de bloque. Los dispositivos de SCSI son de una tal clase y dispositivos de IDE son de otra. Es la clase la que se registra con el kernel de Linux y proporciona las operaciones de archivo al kernel. Los controladores de dispositivo para una clase de dispositivo de bloque proporcionan la clase de las interfaces especficas a la clase. Por ejemplo, as como un controlador de dispositivo SCSI tiene que proporcionar las interfaces al subsistema de SCSI que el subsistema de SCSI usa para mantener las operaciones de archivo para este dispositivo en el kernel. Cada controlador de dispositivo de bloque debe proporcionar una interfaz al buffer de cache para una normal interfaz de las operaciones de archivo. Cada controlador de dispositivo de bloque rellena su entrada en el vector del blk_dev en la estructura de datos de blk_dev_struct. El ndice en este vector es, de nuevo, el nmero mayor del dispositivo. La estructura de datos de blk_dev_struct consiste en la direccin de una rutina de requerimiento y en un indicador a una lista de requerimientos de la estructura de datos, cada uno representa un requerimiento del buffer cache para que el controlador pueda leer o escribir un bloque de datos.

El Buffer Cache de los requerimientos de los Dispositivos de Bloque Cada tiempo el buffer cache desea leer o escribir un bloque de datos desde un registro de dispositivos si agrega que un requerimiento en la estructura de datos blk_dev_struct. La Figura 8.2 muestra que cada requerimiento tiene un indicador a una o ms estructura de datos del buffer_head, cada uno de los requerimientos son para leer o escribir en un bloque de datos. Las estructuras del buffer_head se cierran con llave (por el buffer cache) y puede haber un proceso esperando a que el bloque de operaciones del buffer se complete. A cada estructura del requerimiento se asigna una lista esttica, la all_requestslist. Si el requerimiento est agregndose a una lista de requerimientos vaca, la funcin de la demanda del controlador se llama para empezar el proceso en la cola de requerimientos. Por otra parte el controlador procesar cada requerimiento simplemente en la lista de los requirimientos. Una vez el controlador del dispositivo ha completado un requerimiento debe quitarlo de cada una de las estructuras del buffer_head desde la estructura de requerimentos, abriendolos y marcandolos para actualizar. Al abrirlos del buffer_head se despertar cualquier proceso que ha estado esperando inactivo para completar el bloque de operaciones. Un ejemplo de esto sera donde el nombre de un archivo est estando resuelto y los filesystem de EXT2 deben leer el bloque de datos que contiene el prximo directorio de entrada EXT2 del dispositivo de bloque que sostiene el filesystem. El proceso esta inactivo en el buffer_head que contendr la entrada del directorio hasta que el controlador del dispositivo lo active. La estructura de datos de requerimiento es marcada como libre para que pueda usarse en otro requerimeinto del bloque.

Potrebbero piacerti anche