2
« am: 01. October 2009, 21:29 »
Hi!
Hab ein mittelschweres Problem beim Laden meiner GDT. Ich hab mittlerweile alles mögliche probiert, doch sofort nachdem ich die Segmentregister neu lade wird die CPU resetet (sprich qemu rebootet).
Hier folgt mein (hoffentlich nicht all zu grausamer) C Code:
#include <triplex.h>
#define GDT_SIZE 5
#define GDT_CODESEG 0x0A
#define GDT_DATASEG 0x02
#define GDT_TSS 0x09
#define GDT_PRESENT 0x80
#define GDT_SEGMENT 0x10
#define SYS_CODE_SEL 0x08
#define SYS_DATA_SEL 0x10
#define USER_CODE_SEL 0x18
#define USER_DATA_SEL 0x20
#define TSS_SEL 0x28
typedef struct {
uint32_t size;
uint32_t base;
uint16_t base2;
uint16_t access;
uint16_t size2;
uint16_t base3;
} segment_descriptor;
segment_descriptor gdt[GDT_SIZE];
void gdt_set_descriptor(int i, uint64_t size, uint64_t base, uint16_t access, int dpl)
{
gdt[i].size = size & 0xFFFF;
gdt[i].size2 = ((size >> 16) & 0x0F) | 0xC0;
gdt[i].base = base & 0xFFFF;
gdt[i].base2 = (base >> 16) & 0xFF;
gdt[i].base3 = ((base >> 24) & 0xFF);
gdt[i].access = access | ((dpl & 3) << 5);
}
void load_gdt()
{
struct {
uint16_t size;
uint32_t base;
} __attribute__((packed)) gdt_ptr = {
.size = GDT_SIZE*8 - 1,
.base = (uint32_t)gdt,
};
asm("lgdtl %0\n\t"
"ljmpl $0x08, $1f\n\t"
"1:\n\t"
"mov $0x10, %%eax\n\t"
"mov %%eax, %%ds\n\t"
"mov %%eax, %%es\n\t"
"mov %%eax, %%fs\n\t"
"mov %%eax, %%gs\n\t"
"mov %%eax, %%ss\n\t" : : "m" (gdt_ptr) : "eax");
}
void init_gdt(void)
{
gdt_set_descriptor(0, 0, 0, 0, 0);
gdt_set_descriptor(1, 0x000FFFFF, 0x00000000, GDT_SEGMENT | GDT_PRESENT | GDT_CODESEG, 0);
gdt_set_descriptor(2, 0x000FFFFF, 0x00000000, GDT_SEGMENT | GDT_PRESENT | GDT_DATASEG, 0);
gdt_set_descriptor(3, 0x000FFFFF, 0x00000000, GDT_SEGMENT | GDT_PRESENT | GDT_CODESEG, 3);
gdt_set_descriptor(4, 0x000FFFFF, 0x00000000, GDT_SEGMENT | GDT_PRESENT | GDT_DATASEG, 3);
load_gdt();
}
Hoffe irgendjemand sieht den Fehler und kann mir helfen.
Danke
schneida