Autor Thema: Ständiges Rebooten mit outb() und inb()  (Gelesen 4607 mal)

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« am: 20. June 2013, 18:52 »
Hallo,

ich habe mich mal wieder hingesetzt und versucht einen Tastaturtreiber zu entwerfen, damit man auch was machen kann...

Leider wird ständig ein Reboot ausgeführt.


Meine Tastatur-Initialisierung:
void keyboard_init(void)
{
while ((inb(0x64) & 0x1)) {}

 
     
// Tastatur aktivieren
send_command(0xF4);

kprintf("Tastatur initialisiert!");
}

void send_command(uint8_t command)
{
while ((inb(0x64) & 0x2)) {}
outb(0x60, command);
}

Kommentiere ich die while-Schleife und send_command in keyboard_init() aus funktioniert alles normal.
Ich vermute, dass es an inb() und outb() liegt.

Hier mein Code für inb() und outb():
void outb(unsigned short _port, unsigned char _data)
{
__asm__ ("outb %0, %1" : : "a" (_data), "Nd" (_port));
}

unsigned char inb(unsigned short _port)
{
unsigned char result;
__asm__ ("inb %1, %0" : "=a" (result) : "Nd" (_port));
return result;
}

Der Compiler zeigt keine Fehler an.
Weiß jemand was das Problem ist und wie ich es beheben kann?

Schonmal Danke :-)

MrTom3715

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 20. June 2013, 18:58 »
Testest du in einem Emulator oder auf einem realen System? Wenn du qemu oder bochs nutzt, kannst du eventuell interessante Kenntnisse aus den Logs gewinnen, zum Beispiel welche Interrupt/Exception genau aufgetreten ist, und bei welchem Befehl. Logs kannst du z.B. in qemu aktivieren, indem du -d int übergibst. Dann wird eine Datei namens qemu.log (unter Linux /tmp/qemu.log) angelegt. Wenn du aus der Datei nicht schlau wirst, kannst du die bei einem Pastebin mal hochladen und hier verlinken.
« Letzte Änderung: 23. November 2014, 15:13 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 20. June 2013, 19:06 »
Ich teste in Qemu.

Hier ist der Log:
http://pastebin.com/DAA6VJH1

MrTom3715

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 20. June 2013, 19:30 »
Wenn du dir das Log mal anschaust, fällt dir sicherlich auf, dass sich die Blöcke darin immer wiederholen. Ein Block beginnt mit eine oder zwei Zeilen, die ein paar Informationen über den Interrupt liefert, und dann mehrere Zeilen Registerdump. Die ersten beiden Interrupts (SMM: enter und SMM: after RSM) treten in qemu immer auf, und haben nichts mit deinem OS zu tun. Der darauf folgende Interrupt (Zeile 39) ist interessant. In der Zeile steht v=21, was heißt, dass Interrupt 21h (der Keyboard IRQ) ausgelöst wurde. In Zeile 58 wird ein weiterer Interrupt ausgelöst und zwar Exception 13 (v=0d), was der General Protection Fault ist. Der Error Code e=010a besagt, dass es ein Problem mit dem IDT-Eintrag 21h gibt. (Wie man den Error Code interpretiert steht im Intel Manual, 6.13 Error Code). Du solltest also den Code prüfen, der die IDT einrichtet. Dass ein Double Fault und schließlich ein Triple Fault (Reboot) auftritt, lässt darauf schließen, dass alle Einträge in der IDT falsch sind.
Dieser Text wird unter jedem Beitrag angezeigt.

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 20. June 2013, 19:55 »
Ich habe meine IDT jetzt mal mit der aus dem Tutorial-Beispiel ersetzt.

Es klappt immer noch nicht...

Wenn ich keine den outb() Befehl auskommentiere, entsteht kein Double oder Triple Fault.

Meine PIC initialisierung besteht aber auch hauptsächlich nur aus outb() Befehlen und es tritt kein Fehler auf.

Hast du irgendeine Idee was sonst falsch sein könnte oder habe ich dich falsch verstanden?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 20. June 2013, 20:07 »
Der outb-Befehl scheint die Tastatur dazu zu veranlassen einen IRQ zu senden. Wenn du ihn auskommentierst, kommt kein IRQ und das Problem mit der IDT hat keine Auswirkungen.

Funktionieren irgendwelche anderen Interrupts?
Dieser Text wird unter jedem Beitrag angezeigt.

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 20. June 2013, 20:13 »
Interrupts haben bei mir bisher immer funktioniert.

Mich wundert es aber, dass selbst die IDT aus dem Tutorial nicht richtig funktioniert.
Gibt es vielleicht einen Fehler im Tutorial?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 20. June 2013, 20:16 »
Interrupts haben bei mir bisher immer funktioniert.
Das heißt Softwareinterrupts und Timer-IRQ funktionieren?

Mich wundert es aber, dass selbst die IDT aus dem Tutorial nicht richtig funktioniert.
Gibt es vielleicht einen Fehler im Tutorial?
Man kann Code nicht einfach so zusammenwerfen und erwarten, dass es funktioniert.
Dieser Text wird unter jedem Beitrag angezeigt.

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 20. June 2013, 20:29 »
Softwareinterrupts funktionieren und Timer auch.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 20. June 2013, 20:42 »
Dann fällt mir nichts mehr ein.
Dieser Text wird unter jedem Beitrag angezeigt.

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 20. June 2013, 20:53 »
Schade...
Aber trotzdem danke!

 

Einloggen