2012-06-03 53 views
14

En la mainbord tenemos un controlador de interrupciones (IRC) que actúa como un multiplexor entre los dispositivos que puede elevar una interrupción y la CPU:manejo de interrupciones (Linux/General)

       |--------| 
      |-----------|  |  | 
-(0)------| IRC _____|______| CPU | 
-(...)----| ____/  |  |  | 
-(15)-----|/   |  |--------| 
      |-----------| 

Cada dispositivo está asociado a un IRQ (el número a la izquierda). Después de cada ejecución, la CPU detecta la línea de solicitud de interrupción. Si se detecta una señal, se realizará un guardado de estado y la CPU cargará una Rutina de controlador de interrupciones que se puede encontrar en el Vector de interrupción que se encuentra en una dirección fija en la memoria. Por lo que puedo ver, el Número de IRQ y el Número de Vector en el Vector de Interrupción no son los mismos porque tengo, por ejemplo, mi tarjeta de red registrada en IRQ 8. En un procesador Intel Pentium, esto apuntaría a una rutina que se usa para señalar una condición de error, por lo que debe haber una asignación en algún lugar que apunte al controlador correcto.

Preguntas:

1) Si escribo un controlador de dispositivo y registran un IRQ X para ello. ¿De dónde sabe el sistema qué dispositivo debe manejarse? Puedo, por ejemplo, usar request_irq() con IRQ número 10, pero ¿cómo sabe el sistema que el controlador debe usarse para el mouse o el teclado o para lo que sea que escriba el controlador?

2) ¿Cómo se ve entonces el vector de interrupción? Quiero decir que si uso el IRQ 10 para mi dispositivo esto sobrescribiría un controlador estándar que es para el manejo de errores en la tabla (el primero utilizable es 32 según Silberschatz (Conceptos del sistema operativo)).

3) ¿Quién establece inicialmente las IRQ? ¿Bios? El sistema operativo?

4) ¿Quién es responsable de la coincidencia de la IRQ y la compensación en el vector de interrupción?

5) Es posible compartir IRQS. ¿Cómo es eso posible? Hay carriles de hardware en la placa base que conectan los dispositivos al controlador de interrupción. ¿Cómo se pueden configurar los carriles para la misma Interrupción? Debe haber una tabla que diga que las líneas 2 y 3 manejan IRQ15, p. ¿Dónde reside esta tabla y cómo se llama?

+0

Una explicación más detallada sobre la configuración de interrupción, la manipulación y la cartografía se puede encontrar aquí: [Un código de pie en el interior del núcleo marco de interrupción] (http://linuxburps.blogspot.in/2013/10/linux-interrupt- handling.html) –

Respuesta

18

Respuestas con respecto al kernel de Linux. Debería funcionar para la mayoría de otros sistemas operativos también.

1) Si escribo un controlador de dispositivo y registro un IRQ X para ello. ¿De dónde sabe el sistema qué dispositivo debe manejarse? Puedo, por ejemplo, usar request_irq() con IRQ número 10, pero ¿cómo sabe el sistema que el controlador debe usarse para el mouse o el teclado o para lo que sea que escriba el controlador?

No hay 1 respuesta. Por ejemplo, si se trata de un sistema embebido personalizado, el diseñador del hardware le dirá al escritor del controlador "Voy a enrutar el dispositivo x a irq y". Para obtener más flexibilidad, por ejemplo, para una tarjeta de red que generalmente usa el protocolo PCI. Hay un arbitraje de nivel de hardware/firmware para asignar un número irq a un nuevo dispositivo cuando se detecta. Esto se escribirá en uno de los registros de configuración PCI. El controlador primero lee este registro de dispositivo y luego registra su manejador de interrupción para ese irq particular. Habrá mecanismos similares para otros protocolos.

Lo que puede hacer es buscar llamadas a request_irq en el código kernel y cómo el controlador obtuvo el valor irq. Será diferente para cada tipo de controlador.

La respuesta a esta pregunta es por lo tanto, el sistema no sabe. El diseñador de hardware o los protocolos de hardware proporcionan esta información al controlador de escritor. Y luego el conductor del controlador registra el manejador de ese irq en particular, diciéndole al sistema qué hacer en caso de que vea ese irq.

2) ¿Cómo se ve entonces el vector de interrupción? Quiero decir que si uso el IRQ 10 para mi dispositivo esto sobrescribiría un controlador estándar que es para el manejo de errores en la tabla (el primero utilizable es 32 según Silberschatz (Conceptos del sistema operativo)).

Buena pregunta. Hay dos partes.

a) Cuando request_irq (irq, handler). El sistema realmente no programa la entrada 0 en el IVT o IDT. Pero la entrada N + irq. Donde N es el número de manejadores de errores o excepciones de propósito general compatibles con esa CPU. Los detalles varían de un sistema a otro.

b) ¿Qué ocurre si solicita erróneamente un irq que otro controlador utiliza? Obtiene un error e IDT no está programado con su controlador.

Nota: IDT es la tabla de descriptor de interrupción.

3) ¿Quién establece inicialmente las IRQ? ¿Bios? El sistema operativo?

Bios primero y luego sistema operativo. Pero hay ciertos SO, por ejemplo, MS-DOS que no reprograman el IVT configurado por el BIOS. Los sistemas operativos modernos más sofisticados, como Windows o Linux, no quieren confiar en determinadas funciones de BIOS, y reprograman el IDT. Pero BIOS tiene que hacerlo inicialmente solo cuando el sistema operativo entra en escena.

4) ¿Quién es responsable de la coincidencia de la IRQ y la compensación en el vector de interrupción?

No tengo claro a qué se refiere. El flujo es así. Primero se le asigna un número irq a su dispositivo y luego registra un manejador con ese número irq. Si usa el número irq incorrecto y luego habilita la interrupción en su dispositivo, el sistema se bloqueará. Porque el controlador está registrado en un número irq incorrecto.

5) Es posible compartir IRQS. ¿Cómo es eso posible? Hay carriles de hardware en la placa base que conectan los dispositivos al controlador de interrupción. ¿Cómo se pueden configurar los carriles para la misma Interrupción? Debe haber una tabla que diga que las líneas 2 y 3 manejan IRQ15, p. ¿Dónde reside esta tabla y cómo se llama?

Esta es una muy buena pregunta. La tabla adicional no es cómo se resuelve en kernel. Más bien para cada irq compartido, los manejadores se mantienen en una lista vinculada de indicadores de función. Kernel recorre todos los manipuladores y los invoca uno tras otro hasta que uno de los manejadores reclama la interrupción como propia.

The code looks like this: 

driver1: 

d1_int_handler: 
     if (device_interrupted()) <------------- This reads the hardware 
     { 
      do_interrupt_handling(); 
      return MY_INTERRUPT; 
     }else { 
      return NOT_MY_INTERRUPT; 
     } 

driver2: 
     Similar to driver 1 


kernel: 
     do_irq(irq n) 
     { 
      if (shared_irq(n)) 
      { 
       irq_chain = get_chain(n); 
       while(irq_chain) 
       { 
        if ((ret = irq_chain->handler()) == MY_INTERRUPT) 
         break; 
        irq_chain = irq_chain->next; 
       } 
       if (ret != MY_INTERRUPT) 
        error "None of the drivers accepted the interrupt"; 
      } 
     } 
+2

¡Excelente respuesta, gracias! – fliX

+0

Agregaste una descripción en IDT, ¿podrías agregar uno para IVT? – einstein

Cuestiones relacionadas