I started to code a kernel library.
But I have a problem with the GDT setup.
When I call cpu_gdt_setup(), the generated .iso is freezing under Qemu.
I found that the part which is responsible of this was the inline assembly part.
I imitated this: http://www.osdever.net/bkerndev/Docs/gdt.htm
I tried different asm code, browsed osdev, but my problem still persist.
Can someone tell me what is going wrong?
Thanks in advance.
Code: Select all
#include "gdt.h"
void cpu_set_null_descriptor(struct x86_segment_descriptor* null_descriptor)
{
null_descriptor->limit_15_0 = 0x0000;
null_descriptor->base_address_15_0 = 0;
null_descriptor->base_address_23_16 = 0;
null_descriptor->segment_type = 0x0;
null_descriptor->descriptor_type = 1;
null_descriptor->descriptor_privilege_level = 0x0;
null_descriptor->segment_present = 0;
null_descriptor->limit_19_16 = 0x0;
null_descriptor->available = 0;
null_descriptor->zero = 0;
null_descriptor->operation_size = 0;
null_descriptor->granularity = 0;
null_descriptor->base_address_31_24 = 0;
}
void cpu_set_code_segment_descriptor(struct x86_segment_descriptor* code_segment_descriptor)
{
code_segment_descriptor->limit_15_0 = 0xffff;
code_segment_descriptor->base_address_15_0 = 0;
code_segment_descriptor->base_address_23_16 = 0;
code_segment_descriptor->segment_type = 0xb;
code_segment_descriptor->descriptor_type = 1;
code_segment_descriptor->descriptor_privilege_level = 0x0; /* ring 0 */
code_segment_descriptor->segment_present = 1;
code_segment_descriptor->limit_19_16 = 0xf;
code_segment_descriptor->available = 0;
code_segment_descriptor->zero = 0;
code_segment_descriptor->operation_size = 1;
code_segment_descriptor->granularity = 1;
code_segment_descriptor->base_address_31_24 = 0;
}
void cpu_set_data_segment_descriptor(struct x86_segment_descriptor* data_segment_descriptor)
{
data_segment_descriptor->limit_15_0 = 0xffff;
data_segment_descriptor->base_address_15_0 = 0;
data_segment_descriptor->base_address_23_16 = 0;
data_segment_descriptor->segment_type = 0x3;
data_segment_descriptor->descriptor_type = 1;
data_segment_descriptor->descriptor_privilege_level = 0x0; /* ring 0 */
data_segment_descriptor->segment_present = 1;
data_segment_descriptor->limit_19_16 = 0xf;
data_segment_descriptor->available = 0;
data_segment_descriptor->zero = 0;
data_segment_descriptor->operation_size = 1;
data_segment_descriptor->granularity = 1;
data_segment_descriptor->base_address_31_24 = 0;
}
void cpu_gdt_setup()
{
struct x86_gdt_register gdtr;
struct x86_segment_descriptor null_segment;
struct x86_segment_descriptor code_segment;
struct x86_segment_descriptor data_segment;
static struct x86_segment_descriptor gdt_array[3];
cpu_set_null_descriptor(&null_segment);
cpu_set_code_segment_descriptor(&code_segment);
cpu_set_data_segment_descriptor(&data_segment);
gdt_array[0] = null_segment;
gdt_array[1] = code_segment;
gdt_array[2] = data_segment;
gdtr.base_address = (uint32)&gdt_array;
gdtr.limit = (sizeof(struct x86_segment_descriptor) * 3) - 1;
__asm__ __volatile__("lgdt %0 \n\t"
"movw $0x10, %%ax \n\t"
"movw %%ax, %%ds \n\t"
"movw %%ax, %%es \n\t"
"movw %%ax, %%fs \n\t"
"movw %%ax, %%gs \n\t"
"movw %%ax, %%ss \n\t"
"ljmp $0x08, $flush2 \n\t"
"flush2: \n\t"
:
:"m"(gdtr)
:"memory","eax");
}
To comile the library:
cd kernelkit
make all
To compile the cpu demo:
cd kernelkit/demo/cpu
make all
-> An .iso image will be generated
Code: Select all