65 lines
1.8 KiB
C
65 lines
1.8 KiB
C
#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);
|
|
}
|