Autor Thema: iret verursacht absturz?  (Gelesen 1605 mal)

ian

  • Beiträge: 2
    • Profil anzeigen
Gespeichert
« am: 05. January 2011, 15:29 »
Hi, hab die Tage mal bissel probiert euer Tuturial umzusetzen. Aber irgendwie gehn mir die Ideen aus was bei den Interrupts falsch ist. Kann eine Testfunktion anspringen und darin eine Ausgabe machen, wenn ich aber ne asm Funktion anspringe in der nur ein iret drin steht stürtzt er ab. Währe euch wirklich dankbar wenn einer ne Idee hat.

hier der code der die idt baut:
template <uint16_t entrys>
class idt_c{
public:
const static uint16_t FLAG_IntGate = 0xE << 8;
const static uint16_t FLAG_TrapGate = 0xF << 8;
const static uint16_t FLAG_TaskGate = 0x5 << 8;

const static uint16_t FLAG_userland = 0x3 << 13;
const static uint16_t FLAG_kernlland = 0x0 << 13;
const static uint16_t FLAG_present = 0x1 << 15;
protected:
struct {
uint16_t isr0_15;
uint16_t csr0_15;
uint16_t flags;
uint16_t isr16_31;
} PACKED idt[entrys];

struct{
uint16_t size;
void *idt;
} PACKED idtp;
public:
idt_c();
~idt_c();
void set_entry(uint16_t index, void *isr, uint16_t csr, uint16_t flags);
void activate();
};

template <uint16_t entrys>
idt_c<entrys>::idt_c(){
this->idtp.size = (entrys * 8) - 1;
this->idtp.idt = this->idt;
}

template <uint16_t entrys>
idt_c<entrys>::~idt_c(){
}

template <uint16_t entrys>
void idt_c<entrys>::set_entry(uint16_t index, void *isr, uint16_t csr, uint16_t flags){
if(index >= entrys){
return;
}
this->idt[index].isr0_15 = ((uint32_t)isr) & 0xFFFF;
this->idt[index].csr0_15 = csr;
this->idt[index].flags = flags;
this->idt[index].isr16_31 = (((uint32_t)isr) & 0xFFFF0000) >> 16;
}

template <uint16_t entrys>
void idt_c<entrys>::activate(){
asm volatile ("lidt %0" : :"m"(this->idtp));
}

wird dann hier aufgerufen:
bs::core::idt_c<48> idt;
idt.set_entry(0, testasm, gdt.getSR(1, 0), idt.FLAG_IntGate | idt.FLAG_userland | idt.FLAG_present);
idt.activate();
asm volatile ("int $0x0");

die asm Funktion:
global testasm
testasm:
iret

das interesannte ist halt das es mit der Funktion als Handler erstmal geht:
void testisr(){
screen << "testisr\r\n";
asm volatile("cli; hlt"); // Prozessor anhalten
}

Viele Grüße und Danke schonmal

SHyx0rmZ

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 06. January 2011, 02:18 »
So wie ich das sehe liegt das daran, dass du vergisst, vorher etwaige Errorcodes und Interruptnummern vom Stack zu nehmen. Dazu musst du vor dem iret den Stack erhöhen (wenn ich mich nicht ganz vertue um 8). Deine letzte Funktion funktioniert deswegen, weil Sie die Ausführung anhält.
@X="krJhbuaesrytre c a cnR.ohut";while@X[/(..)(.)/];@X=@X[3..-1]+$1;print$2;end
"Scheiß auf Perl, wir haben Kekse" - Emperor Ruby

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 06. January 2011, 03:49 »
Wenn das dein vollständiger Code ist (d.h. insbesondere die Interrupts nicht aktiviert sind), glaube ich nicht, dass es an vergessenen Daten auf dem Stack liegt. Das einzige, was mir auffällt, ist, dass das Codeschnipsel so aussieht, als würde die IDT (bs::core::idt_c<48> idt;) auf dem Stack liegen. Das solltest du nicht tun, auch nicht zum Testen. Eine globale Variable wäre besser.

Eine Idee, die ich noch bieten könnte wäre, dass der Stackpointer schon vorher ins Nirvana zeigt oder der für den Stack verfügbare Raum zu knapp bemessen ist. Compiler-Optimierungen könnten dann alle Stackzugriffe bei der funktionierenden Variante verschleiern. Aber ein bisschen weit hergeholt ist das zugegebenermaßen schon.
Dieser Text wird unter jedem Beitrag angezeigt.

ian

  • Beiträge: 2
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 11. January 2011, 12:38 »
Danke für eure Hilfe, hab das alles noch versucht zu testen aber läuft irgendwie nicht. werd einfach nochmal alles löschen und neu machen, das hilft vielleicht.

 

Einloggen