1
0
Fork 0
kernel_premier/src/gdt.c
2023-10-05 23:28:32 +02:00

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);
}