Guten Morgen,
und noch ein neuer Thread
Ich bin momentan dabei, alles rauszuschmeißen und neuzuschreiben, was aus Tutorials übernommen wurde, bzw. den kompletten Kernel neuzuschreiben.
Leider leider hänge ich schon bei der GDT
Und zwar initialisiere ich diese und nach dem Sprung, um die GDT neuzuladen, hängt Bochs in einer endlosschleife. Hier erst einmal die Ausgaben des Debuggers, die wichtig sein sollten:
Nun zu meinem geschriebenen unrat. Meine Struktur für die Einträge habe ich so angelegt, wie es in den Intel Dokumenten steht. Damit GCC nix optimiert, habe ich das auch noch gepackt:
Für das Initialisieren der GDT rufe ich einfach oben die aufgeführte Funktion 5 mal auf (0, Kernelcode, Kerneldata, Usercode, Userdata (später 6 mal, da noch die TSS hinzu kommt)).
Nun habe ich die Informationen für das Register GDTR nur lokal in der Funktion abgelegt, da es ja eigentlich nur einmal gebraucht wird. Und da ich auf zusätzliche Funktionen verzichten wollte, habe ich den Wechsel auch gleich in inline assembler geschrieben. Das ganze sieht dann wie folgt aus:
Da der Code nicht funktioniert, muss ich irgendwo einen Fehler haben, doch wo? Ich sehe hier keine Unstimmigkeiten. Wenn ich nun aus ax eax mache, passiert auch nichts anderes...
Was kann ich hier machen?
und noch ein neuer Thread

Ich bin momentan dabei, alles rauszuschmeißen und neuzuschreiben, was aus Tutorials übernommen wurde, bzw. den kompletten Kernel neuzuschreiben.
Leider leider hänge ich schon bei der GDT

Und zwar initialisiere ich diese und nach dem Sprung, um die GDT neuzuladen, hängt Bochs in einer endlosschleife. Hier erst einmal die Ausgaben des Debuggers, die wichtig sein sollten:
Code: [Auswählen]
(0) [0x00100129] 0008:0000000000100129 (unk. ctxt): lgdt ss:[esp+0x1e] ; 0f0154241e
(0) [0x0010012e] 0008:000000000010012e (unk. ctxt): mov ax, 0x0010 ; 66b81000
(0) [0x00100132] 0008:0000000000100132 (unk. ctxt): mov ds, ax ; 8ed8
(0) [0x00100134] 0008:0000000000100134 (unk. ctxt): mov es, ax ; 8ec0
(0) [0x00100136] 0008:0000000000100136 (unk. ctxt): mov fs, ax ; 8ee0
(0) [0x00100138] 0008:0000000000100138 (unk. ctxt): mov gs, ax ; 8ee8
(0) [0x0010013a] 0008:000000000010013a (unk. ctxt): mov ss, ax ; 8ed0
(0) [0x0010013c] 0008:000000000010013c (unk. ctxt): jmp far 0008:00100143 ; ea430110000800
(0) [0x00110142] 0008:0000000000100143 (unk. ctxt): add byte ptr ds:[eax], al ; 0000
(0) [0x00110144] 0008:0000000000100145 (unk. ctxt): add byte ptr ds:[eax], al ; 0000
(0) [0x00110146] 0008:0000000000100147 (unk. ctxt): add byte ptr ds:[eax], al ; 0000
(0) [0x00110148] 0008:0000000000100149 (unk. ctxt): add byte ptr ds:[eax], al ; 0000
(0) [0x0011014a] 0008:000000000010014b (unk. ctxt): add byte ptr ds:[eax], al ; 0000
(0) [0x0011014c] 0008:000000000010014d (unk. ctxt): add byte ptr ds:[eax], al ; 0000
....
Nun zu meinem geschriebenen unrat. Meine Struktur für die Einträge habe ich so angelegt, wie es in den Intel Dokumenten steht. Damit GCC nix optimiert, habe ich das auch noch gepackt:
Code: [Auswählen]
struct segment_descriptor
{
unsigned short base_low;
unsigned short limit_low;
unsigned char base_mid;
unsigned char access;
unsigned char granularity;
unsigned char base_high;
} __attribute__((packed));
Meine Funktion zum setzen eines Eintrags ist auch nicht unähnlich der, die im Tutorial genutzt wurde, allerdings selbst geschrieben:Code: [Auswählen]
void gdt_set_descriptor(unsigned int num, unsigned int base, unsigned int limit, unsigned char access, unsigned char granularity)
{
// sollte nicht passieren ;)
if(num >= GDT_NUM_MAX_ENTRIES)
return;
// basis adresse
kgdt[num].base_low = (base & 0xFFFF);
kgdt[num].base_mid = ((base >> 16) & 0xFF);
kgdt[num].base_high = ((base >> 24)); // sollte man weglassen können: & 0xFF
// limit
kgdt[num].limit_low = (limit & 0xFFFF);
kgdt[num].granularity = ((limit >> 16) & 0x0F);
// der rest
kgdt[num].access = access;
kgdt[num].granularity |= (granularity & 0xF0);
}
Für das Initialisieren der GDT rufe ich einfach oben die aufgeführte Funktion 5 mal auf (0, Kernelcode, Kerneldata, Usercode, Userdata (später 6 mal, da noch die TSS hinzu kommt)).
Nun habe ich die Informationen für das Register GDTR nur lokal in der Funktion abgelegt, da es ja eigentlich nur einmal gebraucht wird. Und da ich auf zusätzliche Funktionen verzichten wollte, habe ich den Wechsel auch gleich in inline assembler geschrieben. Das ganze sieht dann wie folgt aus:
Code: [Auswählen]
void gdt_install(void)
{
// gdtr
struct {
unsigned short limit;
unsigned int base;
}__attribute__((packed)) gp = {
.limit = (sizeof(struct segment_descriptor) * GDT_NUM_MAX_ENTRIES) - 1,
.base = (unsigned int)kgdt
};
// NULL-Segment
gdt_set_descriptor(0, 0, 0, 0, 0);
// kernel code
gdt_set_descriptor(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
// kernel data
gdt_set_descriptor(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
// user code
gdt_set_descriptor(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
// user data
gdt_set_descriptor(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
// task state segment
//gdt_set_descriptor(5, &..., sizeof(...), 0x89, 0x4F);
asm("lgdt %0\n\t"
"mov $0x10, %%ax\n\t"
"mov %%ax, %%ds\n\t"
"mov %%ax, %%es\n\t"
"mov %%ax, %%fs\n\t"
"mov %%ax, %%gs\n\t"
"mov %%ax, %%ss\n\t"
"ljmp $0x08,$1f\n\t"
"1:\n\t"
: : "m"(gp) : "ax");
}
Da der Code nicht funktioniert, muss ich irgendwo einen Fehler haben, doch wo? Ich sehe hier keine Unstimmigkeiten. Wenn ich nun aus ax eax mache, passiert auch nichts anderes...

Was kann ich hier machen?

Übersicht
Wiki
Hilfe
Suche
Einloggen
Registrieren
Drucken


Gespeichert

