2009-04-21 11 views
4

Im Intel Software-Entwicklerhandbuch heißt es, dass die Interrupt-Vektoren 32-255 normalerweise für externe IO-Devices benutzerdefiniert sind. In meiner Systemprogrammierklasse muss ich einen einfachen Gerätetreiber entwickeln. Meine Frage ist, wie kann ich einen bestimmten Interrupt-Vektor für ein bestimmtes Gerät definieren? Ist das mit dem BIOS getan?Wie erkenne ich gerätespezifische Interrupts auf x86?

Hinweis: Wir entwickeln ein einfaches Betriebssystem, so dass meine Situation ziemlich spezifisch ist, aber am Ende muss ich verstehen, wie dies alles auf einem x86-System passiert. Gegenwärtig ist unser System so eingerichtet, dass ein paar Interruptvektoren über 32 Geräten wie einer seriellen Schnittstelle und einer Tastatur zugewiesen werden. Beim Lesen des Datenblattes für den Intel 82801EB ICH5 IO-Controller, speziell im Abschnitt über die 8259 PICs, heißt es, dass IRQ15 der sekundäre IDE-Kanal ist. Wie würde das schließlich als Interrupt-Vektor auf den Stack gelegt werden?

Ich kann nur so verwirrt sein, dass diese Frage keinen Sinn ergab, also entschuldige ich mich im Voraus.

EDIT: So hat unsere Systemprogrammierklasse ein sehr einfaches Betriebssystem, das Kernroutinen zum Installieren von ISRs aufweist, um spezifische Interrupts mit der Vektornummer zu behandeln. In unserer Klasse im letzten Quartal gab uns der Professor eine Header-Datei, die die Tastatur als Vektornummer 0x2c oder etwas Ähnliches definierte. Ich versuche herauszufinden, wie die primären und/oder sekundären IDE-Kanalunterbrechungen unter Verwendung unserer Kernroutinen verschiedenen ISRs zugeordnet werden. Für den Moment haben alle unbenutzten Interrupt-Vektoren einen Standard-Handler, der Nachrichten drucken würde, wenn ein Interrupt aufgetreten wäre, so dass IDE-Interrupts im Moment nicht gerade aktiv sind, aber das ist eine andere Frage.

+0

Ihre Frage ergibt Sinn. Ich erinnere mich vage, dass die Maus IRQ 31 verwendet? Es tut uns leid.Ich nutze es nicht. –

+0

Ich glaube, ich habe gerade eine gute Quelle gefunden: http://heim.ifi.uio.no/~stanisls/helppc/int_table.html http://heim.ifi.uio.no/~stanisls/helppc/8259 .html –

Antwort

0

Nun, ich habe die Antwort in unserem Support-Code gefunden, insbesondere die PIC-Initialisierungsroutine. Mit dem folgenden Code werden IRQ-Leitungen bei Offset 20h und 28h im IDT für die Master- bzw. Slave-PICs abgebildet.

/* ICW2: master offset of 20 in the IDT, slave offset of 28 */

__outb(PIC_MASTER_IMR_PORT, 0x20); 
__outb(PIC_SLAVE_IMR_PORT, 0x28); 

Dies bedeutet, dass die Tastatur zu Vektornummer 2c und die primären und sekundären Kanäle abgebildet werden bis 2e und 2f jeweils zugeordnet wurde. Einige von euch hätten mir wahrscheinlich bessere Antworten geben können, wenn ich die Frage besser gestellt hätte, aber ich schätze die Hilfe trotzdem!

Tabelle 45 des Datenblattes 82801EB ICH5 beschreibt die IRQ-Leitungen des 8259, und in meinem Betriebssystem wird der Master einfach bei Offset 20h geladen und der Slave ist 28h.

Danke!

0

Wie ich mich erinnere, gibt es eine Vektortabelle am Anfang des Speicherplatzes, die auf die Routine zeigt, die aufgerufen werden soll, wenn ein bestimmter Interrupt auftritt. Ich könnte hier auf einem zu niedrigen Niveau treffen (alter x86 Assembly Programmer), aber auf der Basisebene wird Ihr Vektor in dieser Tabelle installiert, dann wird Ihre Routine aufgerufen. Ich habe kein altes Referenzmaterial bei mir, also kann ich Ihnen die eigentlichen Anrufe nicht geben, aber ich wäre überrascht, wenn die offizielle Methode außerhalb des BIOS funktioniert.

In diesen Tagen der GUIs bin ich sicher, es gibt andere, geeignetere Methoden, die Interrupt-Sharing und all diese guten Sachen zu ermöglichen.

EDIT: Ignorieren viel davon, ich habe gerade gesehen, dass Sie auf Interrupt 16 und darüber suchen, die außerhalb der Hardware-Interrupts sind. Ich entfernte mich von dieser Ebene der Programmierung, bevor es irgendwelche interessanten Bits an Hardware in diesem Raum gab, so dass ich mich immer nur mit den ersten 15 IRQs befasste (der 16. ist die Kaskade zwischen Controllern). Ich lasse es für den Fall, dass es für andere interessant ist :)

1

Es ist eine Weile her, seit ich mit diesem Zeug beschäftigt habe, so dass dies aus sein kann: Ich erinnere mich, dass der PC-Interrupt-Controller 15 IRQ-Linien hat. Diese werden spezifischen benachbarten x86-Interrupt-Vektoren zugeordnet. Wenn also ein Peripheriegerät eine IRQ-Leitung auslöst, unterbricht das PIC die CPU und teilt mit, zu welchem ​​Vektor gesprungen werden soll, als ob der entsprechende INT-Befehl ausgeführt würde. Einige IRQs sind für bestimmte Peripheriegeräte fest codiert, aber ich glaube, dass PCI-Geräte mit dem Betriebssystem für IRQs und einige andere Ressourcen verhandeln (wie die älteren ISA PnP-Geräte).

Ich verstehe nicht, was Sie mit "Wie würde das schließlich auf den Stapel als Interrupt-Vektor gesetzt werden?"

+0

Was ich meinte war, wie würde ich identifizieren, dass ein Interrupt-Vektor, der dem Kernel gegeben wird, einen primären IDE-Kanal sagt? Wie gesagt, wenn ein IDE-Kanal seine entsprechende IRQ-Leitung auslöst, woher weiß ich dann, welche Vektornummer mit dem IDE-Kanal assoziiert wird, der die Quelle war? –

1

Sie können die PICs (programmierbarer Interrupt-Controller) programmieren, um bestimmte Geräte-IRQs zuzuordnen.

Auf x86 gibt es zwei PICs, die verkettet sind und IRQ0-IRQ17 ergeben. IRQ0-7 wird vom 8259 und IRQ8-15 von einem zweiten 8259 verwaltet. Der erste signalisiert die CPU und ist der Master, wobei der zweite (der Slave) den ersten signalisiert.

Die IDT (Interruptdeskriptor-Tabelle) ordnet die Interrupts den Adressen von ISR (Interrupt Service Routinen) zu. Interrupts können direkt mit der INT-Anweisung (Software-Traps) ausgelöst werden.

Um zum Beispiel den Interrupt 0x80 zu erhöhen, führen Sie INT 0x80 aus.

Um 0x80, mov [0x80*4], int_80_handler zu behandeln. Unter der Annahme einer 32-Bit-Architektur wird die Adresse der int_80_handler-Funktion nun an der 0x80-ten Stelle in der IDT gespeichert.

Sie finden diese hilfreich sein:
http://en.wikipedia.org/wiki/Intel_8259
http://en.wikipedia.org/wiki/Interrupt_Handler
http://en.wikipedia.org/wiki/Interrupt
http://en.wikipedia.org/wiki/Interrupt_descriptor_table

+0

Ich denke, ich folge dir, aber meine Frage ist, wie würde ich einen Interrupt zuordnen, sagen 0x3c zum primären IDE-Kanal-Interrupt auf dem PIC? Wie in Ihrem Beispiel haben Sie int 0x80 verwendet. Mein Professor, wie hat das gemacht, aber ich hatte keine Chance, sein Gehirn zu suchen. –

1

Es gibt zwei Möglichkeiten für ein Gerät einen Interrupt zu bekommen:

  1. Verwenden Sie das Plug-and- Spiel oder Pci-Mechanismus. Wenn Sie dies tun, ruft das BIOS Ihr Peripheriegerät an und fragt nach den Ressourcenanforderungen. Anschließend kann Ihr Treiber die Plug-and-Play-Geräte aufzählen, nach dem unterstützten Gerät suchen und den Hardware-Interrupt vom Gerät abrufen.

  2. Wie es in den frühen Tagen gemacht wurde: Verwenden Sie nur einen Interrupt. Fügen Sie dem Gerät einen DIP-Schalter hinzu, mit dem der Benutzer zwischen verschiedenen Interrupts auswählen kann. Die Ressourcenzuordnung liegt jetzt bei den Benutzern. Der Benutzer wird die Unterbrechungsnummer auch zum Ladezeitpunkt irgendwie an den Treiber übergeben.

Nun, wie die Interrupt-Haken: Das auf dem OS abhängig ist und der Modus der x86-in läuft Für einen nackten, nackten Knochen System die IDT abfragen können (Interrupt Descriptor Table) über eine spezielle Anweisung.. Sobald Sie diese IDT haben, können Sie die Adresse abrufen und die Adresse des IRQ-Handlers in den richtigen Slot stecken. Für den Real-Modus weiß ich nicht mehr, wie es gemacht wird.

Wenn Sie mindestens ein kleines Echtzeit-Betriebssystem oder etwas OS-ähnliches ausgeführt haben, ist es wahrscheinlich, dass es bereits eine Kernel-Funktion gibt, die die harte Arbeit für Sie erledigt.

0

INT 21h/AH = 25h - Interrupt-Vektor setzen; Eingang: AL = Interrupt-Nummer. DS: DX -> neuer Interrupt-Handler.