#include "gdt.h" unsigned short create_selector(unsigned short index, unsigned char type, unsigned char rpl) { unsigned short ret = 0; ret += index << 3; ret += type & 0x0004; ret += rpl & 0x0003; return ret; } struct gdt_entry create_gdt_entry(unsigned int start, unsigned short n) { struct gdt_entry ret; ret.size = ((n * 8) - 1) & 0xFFFF; ret.address = start; return ret; } struct segment_descriptor create_descriptor(unsigned int base, unsigned int limit, unsigned char dpl, unsigned char segment_type) { /* unsigned short base_1 = (base & 0x0000FFFF) << 4; unsigned char base_2 = (base & 0x00FF0000) << 2; unsigned char base_3 = (base & 0xFF000000); unsigned short limit_1 = (limit & 0x0000FFFF) << 4; */ struct segment_descriptor ret; ret.first_bytes = (base & 0x0000FFFF) + ((limit & 0x0000FFFF) << 16); ret.last_bytes = ((base & 0x00FF0000) >> 16) + (((segment_type & 0x0F) + ((dpl & 0x03) << 5) + 0x90) << 8 ) + (limit & 0x000F0000) + (base & 0xFF000000); return ret; } void add_in_gdt(unsigned int i, unsigned int start, struct segment_descriptor desc) { int index = i * 8; struct segment_descriptor *ptr = (struct segment_descriptor *) start; *(ptr + index) = desc; } void config_gdt(void) { /* int base = 0x00000010; */ int base = 0x00008f60; struct gdt_entry entry = create_gdt_entry(base, 10); /* unsigned short data_selector = create_selector(2, 0, 0); */ struct segment_descriptor null = {0, 0}; struct segment_descriptor code_kernel = create_descriptor(0, 0xFFFFFFFF, 0, 0x0A); struct segment_descriptor data_kernel = create_descriptor(0, 0xFFFFFFFF, 0, 0x02); load_cs(); load_registers(); add_in_gdt(0, base, null); add_in_gdt(1, base, code_kernel); add_in_gdt(2, base, data_kernel); load_gdt(&entry); }