Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Hauke 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?
-
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?
-
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.)
-
wieder was gelernt... danke
zwar off topic aber wiso gibt es nicht so einen bedanken button hier im forum?
-
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 null
Ich kann mir denke was das bedeutet, aber nicht, wie das entsteht.
-
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. :?
-
IDT[n].offset_low = ((iBase) && 0xffff);
Du willst wahrscheinlich auch ein & und kein && (bitweise vs. logisches und) :wink:
-
Ja da muss ein & und kein && hin, deswegen auch die 1.
Funktioniert jetzt.
Danke :-)