These are my GDT structs
Code: Select all
struct GlobalDescriptorTableEntry
{
unsigned short limit_low; /* The lower 16 bits of the limit */
unsigned short base_low; /* The lower 16 bits of the base */
unsigned char base_mid; /* The next 8 bits of the base */
unsigned char access; /* Contains access flags */
unsigned char granularity; /* Specify granularity, and 4 bits of limit */
unsigned char base_high; /* The last 8 bits of the base; */
} __attribute__((packed)); /* It needs to be packed like this, 64 bits */
struct GlobalDescriptorTablePointer
{
unsigned short limit; /* Size of gdt table in bytes*/
unsigned int base; /* Address to the first gdt entry */
} __attribute__((packed));
Code: Select all
/* Build GDT pointer and load it */
.global gdt_load_and_set
gdt_load_and_set:
mov 4(%esp),%eax
lgdt (%eax)
mov $0x10, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
mov %ax, %ss
jmp $0x08,$flush
flush:
ret
Code: Select all
GlobalDescriptorTable::GlobalDescriptorTable()
{
GlobalDescriptorTablePointer gtdPointer;
gtdPointer.limit = (sizeof(GlobalDescriptorTableEntry) * GDT_NUM_ENTRIES) - 1 ;
gtdPointer.base = (unsigned int)&gdt_entries;
CreateEntry(0, 0, 0, 0, 0); // Null segment
CreateEntry(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); // Code segment
CreateEntry(2, 0, 0xFFFFFFFF, 0x92, 0xCF); // Data segment
// CreateEntry(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User mode code segment
// CreateEntry(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); // User mode data segment
gdt_load_and_set((unsigned int)>dPointer);
}
void GlobalDescriptorTable::CreateEntry(int num, unsigned int base, unsigned int limit, unsigned char access, unsigned char gran)
{
gdt_entries[num].base_low = (base & 0xFFFF);
gdt_entries[num].base_mid = (base >> 16) & 0xFF;
gdt_entries[num].base_high = (base >> 24) & 0xFF;
gdt_entries[num].limit_low = (limit & 0xFFFF);
gdt_entries[num].granularity = (limit >> 16) & 0x0F;
gdt_entries[num].granularity |= gran & 0xF0;
gdt_entries[num].access = access;
}