2012-06-03 3 views
14

Sulla mainbord abbiamo un controllore di interruzioni (IRC) che agisce come un multiplexer tra i dispositivi in ​​grado di generare un interrupt e la CPU:Interrupt movimentazione (Linux/Generale)

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

Ogni dispositivo è associato un IRQ (il numero a sinistra). Dopo ogni esecuzione, la CPU rileva la linea di richiesta di interruzione. Se viene rilevato un segnale, verrà eseguito un salvataggio di stato e la CPU carica una routine di gestione degli interrupt che può essere trovata nel vettore di interrupt che si trova su un indirizzo fisso in memoria. Per quanto posso vedere il numero dell'IRQ e il numero di vettore nel vettore di interruzione non sono gli stessi perché ho per esempio la mia scheda di rete registrata su IRQ 8. Su un processore Intel Pentium questo indicherebbe una routine usata per segnalare una condizione di errore, quindi ci deve essere una mappatura da qualche parte che punta al gestore corretto.

Domande:

1) Se scrivo un driver di periferica e registrano un IRQ X per esso. Da dove viene il sistema a sapere quale dispositivo deve essere gestito? Ad esempio, posso usare request_irq() con IRQ numero 10 ma come fa il sistema a sapere che il gestore deve essere usato per il mouse o la tastiera o per qualsiasi cosa scriva il driver?

2) Come appare allora il Vettore Interrupt? Voglio dire se uso l'IRQ 10 per il mio dispositivo questo sovrascriverebbe un gestore standard che è per la gestione degli errori nella tabella (il primo utilizzabile è 32 secondo Silberschatz (Operating System Concepts)).

3) Chi stabilisce gli IRQ in modo iniziale? Il Bios? Il sistema operativo?

4) Chi è responsabile per la corrispondenza dell'IRQ e dell'offset nel vettore di interrupt?

5) È possibile condividere IRQS. Come è possibile? Ci sono delle corsie hardware sulla scheda madre che collegano i dispositivi al controller di interrupt. Come possono essere configurate le corsie per lo stesso interrupt? Ci deve essere una tabella in cui la corsia 2 e 3 gestiscono IRQ15, ad es. Dove risiede questo tavolo e come si chiama?

+0

Una spiegazione più dettagliata sulla configurazione di interruzione, la manipolazione e la mappatura può essere trovato qui: [Un codice passeggiata all'interno quadro kernel interrupt] (http://linuxburps.blogspot.in/2013/10/linux-interrupt- handling.html) –

risposta

18

Risposte relative al kernel di Linux. Dovrebbe funzionare anche per la maggior parte degli altri sistemi operativi.

1) Se scrivo un driver di dispositivo e registro un IRQ X per esso. Da dove viene il sistema a sapere quale dispositivo deve essere gestito? Ad esempio, posso usare request_irq() con IRQ numero 10 ma come fa il sistema a sapere che il gestore deve essere usato per il mouse o la tastiera o per qualsiasi cosa scriva il driver?

Non c'è 1 risposta ad esso. Ad esempio, se si tratta di un sistema incorporato personalizzato, il progettista hardware comunicherà all'autore del driver "Sto andando a instradare il dispositivo da x a irq y". Per maggiore flessibilità, ad esempio per una scheda di rete che generalmente utilizza il protocollo PCI. Esistono arbitraggi a livello hardware/firmware per assegnare un numero irq a un nuovo dispositivo quando viene rilevato. Questo verrà quindi scritto in uno dei registri di configurazione PCI. Il driver legge prima questo registro del dispositivo e quindi registra il suo gestore di interrupt per quel particolare irq. Ci saranno meccanismi simili per altri protocolli.

Quello che puoi fare è cercare le chiamate a request_irq nel codice del kernel e come il driver ha ottenuto il valore irq. Sarà diverso per ogni tipo di guidatore.

La risposta a questa domanda è quindi, il sistema non lo sa. Il progettista hardware oi protocolli hardware forniscono queste informazioni all'autore del driver. E poi lo scrittore di driver registra il gestore per quel particolare irq, dicendo al sistema cosa fare nel caso in cui si veda quell'irq.

2) Come appare allora il Vettore Interrupt? Voglio dire se uso l'IRQ 10 per il mio dispositivo questo sovrascriverebbe un gestore standard che è per la gestione degli errori nella tabella (il primo utilizzabile è 32 secondo Silberschatz (Operating System Concepts)).

Buona domanda. Ci sono due parti.

a) Quando request_irq (irq, gestore). Il sistema in realtà non programma la voce 0 nell'IVT o IDT. Ma la voce N + irq. Dove N è il numero di gestori di errori o eccezioni generiche supportate su quella CPU. I dettagli variano da sistema a sistema.

b) Cosa succede se si richiede erroneamente un irq che viene utilizzato da un altro driver. Si ottiene un errore e IDT non è programmato con il gestore.

Nota: IDT è la tabella descrittore di interrupt.

3) Chi stabilisce gli IRQ in modo iniziale? Il Bios? Il sistema operativo?

Bios prima e SO. Ma ci sono alcuni sistemi operativi, per esempio, MS-DOS che non riprogramma la IVT impostata dal BIOS. I sistemi operativi moderni più sofisticati come Windows o Linux non vogliono affidarsi a particolari funzioni di bios e riprogrammano l'IDT. Ma il bios deve farlo inizialmente solo dopo che il SO entra in scena.

4) Chi è responsabile per la corrispondenza dell'IRQ e dell'offset nel vettore di interrupt?

Non sono davvero chiaro cosa intendi. Il flusso è così. Per prima cosa al tuo dispositivo viene assegnato un numero irq, e quindi ti registri un gestore con quel numero irq. Se si utilizza il numero irq errato e si abilita l'interruzione sul dispositivo, il sistema si bloccherà. Perché il gestore è registrato per il numero irq errato.

5) È possibile condividere IRQS. Come è possibile? Ci sono delle corsie hardware sulla scheda madre che collegano i dispositivi al controller di interrupt. Come possono essere configurate le corsie per lo stesso interrupt? Ci deve essere una tabella in cui la corsia 2 e 3 gestiscono IRQ15, ad es. Dove risiede questo tavolo e come si chiama?

Questa è una buona domanda. La tabella aggiuntiva non è come viene risolta nel kernel. Piuttosto per ogni irq condiviso, i gestori sono tenuti in un elenco collegato di puntatori di funzione. Il kernel esegue il ciclo di tutti i gestori e li richiama uno dopo l'altro fino a quando uno dei gestori dichiara l'interrupt come proprio.

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

Risposta eccellente, grazie! – fliX

+0

Hai aggiunto una descrizione su IDT, potresti aggiungerne una per IVT? – einstein