Autor Thema: Problem mit IDT unter C/C++  (Gelesen 3164 mal)

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« am: 20. October 2008, 16:41 »
Ich will mit C/C++ die IDT Laden. Im Boot Loader hab ich noch die Hardware Interrups umgeleitet:

irq:
mov al, 00010001b ;Das ICW in AL schreiben
out 0x20, al ;ICW an PIC1 senden
out 0xA0, al ;ICW an PIC2 senden

mov al, 0x20 ;AL auf 32 setzen
out 0x21, al ;ICW2 an ersten PIC senden
mov al, 0x28 ;AL auf 40 setzen
out 0xA1, al ;ICW2 an zweiten PIC senden

mov al, 00000100b ;Die IRQ2 Leitung auf 1 setzen
out 0x21, al ;An den Master-PIC senden
mov al, 2 ;Hier nun die NUMMER der IRQ-Leitung angeben
out 0xA1, al ;An den Slave-PIC senden

mov al, 00000001b ;Die Bits wie oben beschrieben setzen
out 0x21, al ;ICW4 an Master-PIC senden
out 0xA1, al ;ICW4 an Slave-PIC senden
retn
Und im C Kernel hab ich dazu folgenden Code:

struct idt_daten{
    unsigned short limit;
    unsigned int base;
  }  __attribute__((packed));

struct idt_entry
{
unsigned short offset_low;
unsigned short selector;
unsigned char zero;
unsigned char access;
unsigned short offset_high;
} __attribute__((packed));

struct idt_entry IDT[256];

void setup_IDT()
{
unsigned char i;
make_IDT(i,(unsigned int) int0,8,0x8E);
make_IDT(i,(unsigned int) int1,8,0x8E);



make_IDT(i,(unsigned int) int50,8,0x8E);

for(i = 51; i < 256; i++)
{
make_IDT(i,(unsigned int) int00,8,0x8E);
}
}


void make_IDT(unsigned char n, unsigned int iBase, unsigned short shSelector, unsigned char cAccess)
{
IDT[n].offset_low = ((iBase) && 0xffff);
IDT[n].selector =shSelector;
IDT[n].zero =0;
IDT[n].access = cAccess;
IDT[n].offset_high = ((iBase >> 16) & 0xffff);
}

void LoadIDT()
{
  struct idt_daten idt_ptr;
  idt_ptr.limit  = 256*8 - 1;
  idt_ptr.base  = (unsigned int)IDT;

  //IDT laden
  asm("lidt %0" : : "m" (idt_ptr));
}
Und eine Funktion im asm Teil.
_int50:
mov esi, 0xb8030
mov byte [esi], 'T'
mov byte [esi+1], 10
iret


Und der Aufruf in der Main Funktion:
setup_IDT();
LoadIDT();
asm("int $50");
Jedoch sehe ich kein Ergebnis auf den Bildschirm.
Woran kann das liegen?

chris12

  • Beiträge: 134
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 20. October 2008, 16:50 »
ich kenn mich mit c/c++ zwar nicht so aus aber wieso hast du
asm("int $50");
geschrieben in asm hießt es doch
int 0x50
oder
int 50h
also müsste es doch asm("int 0x50");
oder
asm("int 50h");

oder nicht?
OS? Pah! Zuerst die CPU, dann die Plattform und _dann_ das OS!

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 20. October 2008, 17:02 »
void setup_IDT()
{
unsigned char i;
make_IDT(i,(unsigned int) int0,8,0x8E);
make_IDT(i,(unsigned int) int1,8,0x8E);



make_IDT(i,(unsigned int) int50,8,0x8E);
Das i in make_IDT ist nicht richtig. du solltest es gegen 0, 1, ... 50 ersetzen. int $50 ist korrekt. (das $ bedeutet einfach "zahl" und es ist 50 dezimal nicht hexadezimal gemeint, deswegen kein 0x.)
« Letzte Änderung: 20. October 2008, 17:03 von PorkChicken »
Dieser Text wird unter jedem Beitrag angezeigt.

chris12

  • Beiträge: 134
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 20. October 2008, 17:20 »
wieder was gelernt... danke

zwar off topic aber wiso  gibt es nicht so einen bedanken button hier im forum?
OS? Pah! Zuerst die CPU, dann die Plattform und _dann_ das OS!

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 21. October 2008, 13:03 »
Ja du hast recht das muss durch Nummeriert werden und außerdem muss das i mindestens ein unsigned short sein, weil sonst die Schleife nie zu Ende geht. (weil i ja nicht 256 sondern dann wieder 0 wird). Jetzt stürzt er immer ab, wenn ein Interrupt aufgerufen wird.

Ich hatte auch zwischen durch eine Fehlermeldung von Bochs, die ich zur Zeit nicht mehr bekomme, obwohl ich eigentlich nichts geändert habe
call_protected: CS selector nullIch kann mir denke was das bedeutet, aber nicht, wie das entsteht.

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 22. October 2008, 13:55 »
Hab halbwegs den Fehler gefunden.
Irgendwie schreibt  make_IDT  in IDT[x].offset_low immer eine 1 hinein, wenn ich jetzt in der Main Funktion, für z.B. IDT[50] das eintrage funktioniert das für INT 50:
        int a;
char H[12];
        IDT[50].offset_low = (((unsigned int) int50) & 0xffff);
a = IDT[50].offset_low;

Video.IntToStr(a,H);
Video.TextOut(H,10);
Ich hab auch überprüft, ob andere Funktion auf IDT zugreifen, was keine, außer die gewünschten, tut. (einmal Lokal IDT deklariert)
Ich weis nicht, woran das im Moment noch liegen kann. :?

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #6 am: 22. October 2008, 14:21 »
Zitat
IDT[n].offset_low = ((iBase) && 0xffff);
Du willst wahrscheinlich auch ein & und kein && (bitweise vs. logisches und) :wink:
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Hauke

  • Beiträge: 113
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 22. October 2008, 14:53 »
Ja da muss ein & und kein && hin, deswegen auch die 1.
Funktioniert jetzt.
Danke  :-)

 

Einloggen