Solo sé que Interrupt
es una hardware signal assertion
causa en un pin del procesador. Pero me gustaría saber cómo lo maneja el sistema operativo Linux.
¿Cuáles son todas las cosas que suceden cuando ocurre una interrupción?
Solo sé que Interrupt
es una hardware signal assertion
causa en un pin del procesador. Pero me gustaría saber cómo lo maneja el sistema operativo Linux.
¿Cuáles son todas las cosas que suceden cuando ocurre una interrupción?
Respuestas:
Aquí hay una vista de alto nivel del procesamiento de bajo nivel. Estoy describiendo una arquitectura típica simple, las arquitecturas reales pueden ser más complejas o diferentes en formas que no importan a este nivel de detalle.
Cuando ocurre una interrupción , el procesador mira si las interrupciones están enmascaradas. Si lo son, no pasa nada hasta que se desenmascaran. Cuando las interrupciones se desenmascaran, si hay interrupciones pendientes, el procesador elige una.
Luego, el procesador ejecuta la interrupción ramificándose a una dirección particular en la memoria. El código en esa dirección se llama controlador de interrupciones . Cuando el procesador se bifurca allí, enmascara las interrupciones (por lo que el controlador de interrupciones tiene control exclusivo) y guarda el contenido de algunos registros en algún lugar (generalmente otros registros).
El manejador de interrupciones hace lo que debe hacer, generalmente comunicándose con el periférico que activó la interrupción para enviar o recibir datos. Si el temporizador provocó la interrupción, el controlador podría activar el programador del sistema operativo para cambiar a un hilo diferente. Cuando el controlador termina de ejecutarse, ejecuta una instrucción especial de retorno de interrupción que restaura los registros guardados y desenmascara las interrupciones.
El controlador de interrupciones debe ejecutarse rápidamente, ya que impide que se ejecute cualquier otra interrupción. En el kernel de Linux, el procesamiento de interrupción se divide en dos partes:
Como es habitual en este tema, para obtener más información, lea Controladores de dispositivo Linux ; El capítulo 10 trata sobre las interrupciones.
Gilles ya describió el caso general de una interrupción, lo siguiente se aplica específicamente a Linux 2.6 en una arquitectura Intel (parte de esto también se basa en las especificaciones de Intel).
Una interrupción es un evento que cambia la secuencia de instrucciones ejecutadas por el procesador.
Hay dos tipos diferentes de interrupciones:
Las excepciones son causadas por errores de programación (por ejemplo , error de división , error de página , desbordamiento ) que debe manejar el núcleo. Envía una señal al programa e intenta recuperarse del error.
Se clasifican las siguientes dos excepciones:
Las interrupciones pueden ser emitidas por dispositivos de E / S (teclado, adaptador de red, ..), temporizadores de intervalo y (en sistemas multiprocesador) otras CPU. Cuando ocurre una interrupción, la CPU debe detener su instrucción actual y ejecutar la interrupción recién llegada. Necesita guardar el antiguo estado del proceso interrumpido para (probablemente) reanudarlo después de que se maneje la interrupción.
Manejar interrupciones es una tarea delicada:
Se definen dos niveles de interrupción diferentes:
Cada dispositivo de hardware tiene su propia línea de solicitud de interrupción (IRQ). Las IRQ están numeradas a partir de 0. Todas las líneas IRQ están conectadas a un controlador de interrupción programable (PIC). El PIC escucha las IRQ y las asigna a la CPU. También es posible deshabilitar una línea IRQ específica.
Los sistemas Linux multiprocesamiento modernos generalmente incluyen el nuevo PIC avanzado (APIC), que distribuye las solicitudes de IRQ por igual entre las CPU.
El paso intermedio entre una interrupción o excepción y su manejo es la Tabla de descriptores de interrupción (IDT). Esta tabla asocia cada vector de interrupción o excepción (un número) con un controlador específico (por ejemplo, la función maneja el error de divisióndivide_error()
).
A través del IDT, el núcleo sabe exactamente cómo manejar la interrupción o excepción ocurrida.
Entonces, ¿qué hace el núcleo cuando ocurre una interrupción?
VIP
-flag en el registro de banderas o lo que sea? Gracias de antemano
En primer lugar, los participantes involucrados en el manejo de interrupciones son dispositivos de hardware periférico, controlador de interrupciones, CPU, núcleo del sistema operativo y controladores. Los dispositivos de hardware periférico son responsables de la generación de interrupciones. Afirman líneas de solicitud de interrupción cuando quieren atención del núcleo del sistema operativo. Estas señales son multiplexadas por el controlador de interrupción, que es responsable de la recolección de señales de interrupción. También es responsable de determinar el orden en que las señales de interrupción se pasarán a la CPU. El controlador de interrupción puede deshabilitar temporalmente una línea de solicitud de interrupción particular (IRQL) y volver a habilitarla nuevamente (enmascaramiento IRQL). El controlador de interrupción pasa las solicitudes de interrupción recopiladas a la CPU de forma secuencial. La CPU después de completar la ejecución de cada instrucción La CPU verifica si hay alguna solicitud de interrupción en espera del controlador de interrupción. Si la CPU encuentra que hay una solicitud de espera Y el indicador de habilitación de interrupción se establece en el registro de control interno de la CPU, la CPU comienza a manejar la interrupción. Como puede ver, al manipular el indicador de interrupción en la CPU y comunicarse con el controlador de interrupción, el kernel de Linux puede controlar la aceptación de la interrupción. Por ejemplo, Linux puede deshabilitar la aceptación de interrupciones desde un dispositivo en particular o deshabilitar la aceptación de interrupciones. El kernel de Linux puede controlar la aceptación de interrupciones. Por ejemplo, Linux puede deshabilitar la aceptación de interrupciones desde un dispositivo en particular o deshabilitar la aceptación de interrupciones. El kernel de Linux puede controlar la aceptación de interrupciones. Por ejemplo, Linux puede deshabilitar la aceptación de interrupciones desde un dispositivo en particular o deshabilitar la aceptación de interrupciones.
¿Qué sucede cuando el procesador recibe una solicitud de interrupción? En primer lugar, la CPU deshabilita automáticamente las interrupciones restableciendo el indicador de interrupción. Se volverán a habilitar una vez que finalice el manejo de interrupciones. Al mismo tiempo, la CPU realiza una cantidad mínima de trabajo necesaria para cambiar la CPU del modo de usuario al modo kernel de tal manera que le permita reanudar la ejecución del código interrumpido. La CPU consulta con estructuras especiales de control de la CPU llenadas por el kernel de Linux para encontrar una dirección de código a la que se pasará el control. Esta dirección es la dirección de la primera instrucción del controlador de interrupciones, que forma parte del núcleo de Linux.
Como primer paso para el manejo de interrupciones, el núcleo identifica el vector de interrupción recibido para identificar qué tipo de evento ha sucedido en el sistema. El vector de interrupción define qué acciones tomará Linux para manejarlo. Como segundo paso, Linux guarda el resto de los registros de la CPU (que la CPU no guardó automáticamente) y que potencialmente pueden ser utilizados por el programa interrumpido. Esta es una acción muy importante, ya que permite que Linux maneje las interrupciones de forma transparente con respecto al programa interrumpido. Como tercer paso, Linux logra cambiar al modo kernel configurando el entorno del kernel y el estado de la CPU requerido para ello. Y finalmente, se llama al controlador de interrupción dependiente del vector. (Puede buscar en la macro BUILD_INTERRUPT3 en arch \ x86 \ kernel \ entry_32. S para obtener detalles adicionales para el ejemplo relacionado con la arquitectura x86) En el caso de dispositivos periféricos, esta es una rutina do_IRQ (). (Mire dentro del arco \ x86 \ kernel \ irq.c)
El controlador de interrupción dependiente del vector generalmente envuelto por llamadas a irq_enter () e irq_exit (). El área de código encerrada dentro de un par de estas funciones es atómica con respecto a cualquier otra área y también es atómica con respecto a pares de cli / sti. Irq_enter () e irq_exit () también captura algunas estadísticas relacionadas con el manejo de interrupciones. Finalmente, el núcleo busca en la tabla vector_irq para encontrar el número irq asignado al vector de la interrupción recibida y llama a handle_irq () (desde arch \ x86 \ kernel \ irq_32.c).
En este punto, la parte común del manejo de interrupciones en Linux termina, porque el kernel considera la rutina de manejo de interrupciones dependiente del dispositivo instalada por el controlador del dispositivo como parte del descriptor irq y la invoca. Si dicho controlador no fue instalado por el controlador, el núcleo simplemente reconoce la interrupción en el controlador de interrupción y sale para salir del controlador de interrupción general.
Después del final del kernel de manejo de interrupciones, se restaura el estado del programa que se interrumpió anteriormente y se reanuda la ejecución de este programa.
CPU consults with special CPU control structures filled by Linux kernel to find an address of code to which control will be passed.
¡Sí! Aunque me pregunto cuáles son esas estructuras de control especiales ...
Desde el aspecto teórico, casi todo ha sido explicado. Pero si está buscando una explicación sobre el marco de código de manejo de interrupción de kernel, el siguiente enlace debe: Un paseo de código dentro del manejo de interrupción de kernel
Y si todavía está buscando teoría sobre las interrupciones y los manejadores de interrupciones, le recomiendo leer esto: Comprender las interrupciones y los manejadores de interrupciones