Setting up the GDT

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
narke
Member
Member
Posts: 119
Joined: Wed Dec 26, 2007 3:37 am
Location: France

Setting up the GDT

Post by narke »

Hello,

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");
			
	
}
sources: http://narke.free.fr/operating_systems/kernelkit.zip

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
User avatar
narke
Member
Member
Posts: 119
Joined: Wed Dec 26, 2007 3:37 am
Location: France

Post by narke »

I bypassed the problem by adapting the GDT from bran's kernel tutorial.
Post Reply