Autor Thema: GDT Deskriptor wird falsch gesetzt  (Gelesen 5653 mal)

unsknown spammer

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« am: 29. October 2008, 19:50 »
Hallo erstmal!
Ich boote meinen Kernel ueber grub.
Dann lade ich meine eingene gdt.
Wenn ich das image jetzt unter bochs boote macht der direkt einen restart!

Auszug der Logfile:
Zitat
00011998349i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00011998349i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00011998349i[CPU0 ] |  DS:0010( 0002| 0|  0) ffffffff 000fffff 1 1
00011998349i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00011998349i[CPU0 ] |  ES:0010( 0002| 0|  0) ffffffff 000fffff 1 1
00011998349i[CPU0 ] |  FS:0010( 0002| 0|  0) ffffffff 000fffff 1 1
00011998349i[CPU0 ] |  GS:0010( 0002| 0|  0) ffffffff 000fffff 1 1
DIe Base wird falsch gesetzt!
Ausserdem wird ein anderes limit genommen als ich angegeben habe!
Ich sehe da einfach keinen fehler!

typedef struct gdt_entry{
WORD size0_15;
WORD base0_15;
BYTE base16_23;
BYTE access;
BYTE size16_19;
BYTE base24_31;
}gdt_entry;

typedef struct gdt_ptr{
WORD limit;
DWORD base;
}gdt_ptr;

gdt_ptr pgdt;
gdt_entry gdt[MAX_GDT_ENTRYS];
void init_gdt(){
WORD itemp=0;

//deskriptoren auf 0 setzen
for(itemp=0;itemp<MAX_GDT_ENTRYS;itemp++){
memset((BYTE*)&gdt[itemp],0,sizeof(gdt_entry));
}
//code deskriptor setzen
if(0!=set_gdt(1,0xFFFFF,0,GDT_DATA|GDT_CODE|GDT_PRESENT))return;
//daten deskriptor setzen
if(0!=set_gdt(2,0xFFFFF,0,GDT_DATA|GDT_PRESENT))return;
//limit und base der gdt speichern
pgdt.limit=MAX_GDT_ENTRYS*8 - 1;
pgdt.base=gdt;
//gdt laden und segmentregister aktualisieren
load_gdt();
}

void load_gdt(){
if(pgdt.limit!=0&&pgdt.base!=0){
asm("lgdt %0" : : "m" (pgdt));
//asm("jmp $0x8,$1f;1:");
asm("mov $0x10,%eax");
asm("mov %eax,%ds");
asm("mov %eax,%es");
asm("mov %eax,%fs");
asm("mov %eax,%gs");
//asm("mov %eax,%ss");
}
}

WORD set_gdt(WORD nr,DWORD size,DWORD base,BYTE access){
if(nr>=MAX_GDT_ENTRYS||nr==0)return 1;
gdt[nr].size0_15=size&0xFFFF;
gdt[nr].size16_19=((size>>16)&0xF)|0x80|0x40;
gdt[nr].base0_15=base&0xFFFF;
gdt[nr].base16_23=(base>>16)&0xFF;
gdt[nr].base24_31=(base>>24)&0xFF;
gdt[nr].access=access;
return 0;
}
mfg unknown spammer

jgraef

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 30. October 2008, 16:59 »
typedef struct gdt_entry{
WORD size0_15;
WORD base0_15;
BYTE base16_23;
BYTE access;
BYTE size16_19;
BYTE base24_31;
} __attribute__ ((packed)) gdt_entry;

typedef struct gdt_ptr{
WORD limit;
DWORD base;
} __attribute__ ((packed)) gdt_ptr;

Ersetz mal deine Structs damit. Bei deinen wird eventuell aligned und dann funktioniert das natürlich nicht mehr.

Ich frage mich außerdem wieso du den structs einen Namen gibst, wenn du ihnen sowieso einen Typnamen zuweist.

unsknown spammer

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 30. October 2008, 17:48 »
Danke erstmal!
Ich bin auf einen anderen Compiler umgestiegen!
Mein alter Compiler hat da anscheinend nicht aligned!

Wieso ich den structs namen gebe?
Das habe ich noch von der zeit uebernommen als ich noch nicht mit typedef gearbeitet habe!

Jetzt bekomme ich allerdings eine Exception beim neuladen der Segment-Register:
Zitat
00012122274i[CPU0 ] >> mov ds, ax : 8ED8
00012122274e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
mfg unknown spammer

jgraef

  • Beiträge: 67
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 01. November 2008, 00:02 »
Danke erstmal!
Ich bin auf einen anderen Compiler umgestiegen!
Mein alter Compiler hat da anscheinend nicht aligned!

Wieso ich den structs namen gebe?
Das habe ich noch von der zeit uebernommen als ich noch nicht mit typedef gearbeitet habe!

Jetzt bekomme ich allerdings eine Exception beim neuladen der Segment-Register:
Zitat
00012122274i[CPU0 ] >> mov ds, ax : 8ED8
00012122274e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting

Da ist irgendein Fehler im Deskriptor und du bist an dem Punkt wo man so gut wie gar nicht debuggen kann. Viel Spaß beim suchen ;)

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #4 am: 03. November 2008, 10:39 »
Wie sehen denn die Definitionen aus?
(MAX_GDT_ENTRYS, GDT_DATA, ...)
 
Des Weiteren berechnet sich das limit meinem Wissensstand nach sie folgt (vorrausgesetzt, MAX_GDT_ENTRYS ist kein Macro für die Größe der struktur):
((Größe der Struktur) * Anzahl der Einträge) -1
Dann ist mir noch aufgefallen, dass du im gdt zeiger die Adresse zur GDT speichern musst:
// Anstatt folgendem:
pgdt.base=gdt;
// sollte es heißen:
pgdt.base=(DWORD)&gdt;

Das ist, was mir so auf den ersten Blick aufgefallen ist. Hier noch ein Link zu einem Tutorial, in dem die GDT auch in C implementiert wird: http://osdever.net/bkerndev/Docs/gdt.htm
Ich schreibe diesen Link, damit du einen alternativen Weg siehst, wie man das einbauen kann. Da es ein Teil eines Tutorials ist, kann man dies auch übernehmen.

*EDIT*
Eines noch: Nach dem du die GDT mit lgdt geladen hast, muss ein Sprung zum Codesegment gemacht werden.
« Letzte Änderung: 03. November 2008, 10:41 von ChristianF »

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 03. November 2008, 14:13 »
((Größe der Struktur) * Anzahl der Einträge) -1
Das macht er doch( Größe der Struktur = 8 )
 
Zitat
Dann ist mir noch aufgefallen, dass du im gdt zeiger die Adresse zur GDT speichern musst:
// Anstatt folgendem:
pgdt.base=gdt;
// sollte es heißen:
pgdt.base=(DWORD)&gdt;
gdt ist ein array, das erstere ist also (auch) richtig

@unsknownspammer
falls du den bochs-debugger verwendest, könnte ein 'info gdt' nach dem 'lgdt' hilfreiche informationen liefern
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

unsknown spammer

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 04. November 2008, 14:46 »
Danke erstmal fuer die antworten!
Ich habe den Fehler gefunden und zwar habe ich das Segment-Bit nicht auf 1 gesetzt!
Jetzt laeuft der Kernel!

Kann mir mal jemand erklaeren wofuer das Segment-Bit da ist?
mfg unknown spammer

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 04. November 2008, 16:57 »
Das Segment-Bit liefert der CPU informationen darüber, ob es sich bei dem jeweiligen Descriptor um ein Segment-Descriptor oder ein System-Descriptor( z.B. Gate-Descriptoren) handelt.
Je nach dem wird dann das Typ-Feld anders Interpretiert.
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

 

Einloggen