GDT troubles
Posted: Mon Nov 17, 2014 11:22 pm
I've spent some time looking over the wiki's article on setting up the GDT, and I've also spent a fair amount of time looking at other tutorials and explanations, but I still can't initialize it properly (so I can move on to interrupts) and I have a few questions.
The way the wiki is phrased suggests that if I want a paging kernel, all I need to do is set up the GDT to a bare minimum.
Here's the bare minimum I've been led to believe I need: http://wiki.osdev.org/GDT_Tutorial#Flat_Setup
Thanks in advance for any and all help.
The way the wiki is phrased suggests that if I want a paging kernel, all I need to do is set up the GDT to a bare minimum.
Here's the bare minimum I've been led to believe I need: http://wiki.osdev.org/GDT_Tutorial#Flat_Setup
- Is this correct? Since memory access will be handled by paging, I don't need to worry about specifically setting ring modes for memory blocks, right?
Could someone explain to me what the reference to the Tss pointer is? I gather that it has some importance for multitasking, but I can't find any information with examples on where to get an initial tss pointer. When I wrote my code, I took the liberty of assuming it null.
The article gives no information on the struct of a gdt entry. I understand that it says that it's complicated and somewhat outdated, but how am I supposed to form a valid GDT entry without knowing what amount of information I need? Since I can't find this information anywhere on either the tutorial page or the GDT page in the wiki, I made a naive attempt at a GDT entry struct here:Based off the aforementioned assumptions, I wrote the following test function to attempt to initialize my GDT:Code: Select all
struct gdt_entry { uint32_t base; uint32_t limit; char type; }typedef gdt_entry gdt_entry_t;
Also, for completeness' sake, here is my definition of setGdt in assembly:Code: Select all
extern void setGdt(uint32_t, size_t); //Returns size of initialized GDT //**TODO** //Get working //Clean up magic numbers size_t gdt_init(gdt_entry_t* gdt){ gdt[0].base = 0; gdt[0].limit = 0; gdt[0].type = 0; gdt[1].base = 0; gdt[1].limit = 0xffffffff; gdt[1].type = 0x9A; gdt[2].base = 0; gdt[2].limit = 0xffffffff; gdt[2].type = 0x92; gdt[3].base = 0; //TSS is null gdt[3].limit = sizeof(void*); //Assume Tss is a pointer gdt[3].type = 0x89; //GDT is of size 4. setGdt(gdt, 4); return 4; }
Code: Select all
[GLOBAL setGdt] ; Allows the C code to call setGdt(). gdtr DW 0 ; For limit storage DD 0 ; For base storage setGdt: MOV EAX, [esp + 4] ADD EAX,0x100000 ;;Start of kernel MOV [gdtr + 2], EAX MOV AX, [ESP + 8] MOV [gdtr], AX LGDT [gdtr] ;; Now flush JMP 0x08:reload_CS reload_CS: MOV AX, 0x10 MOV DS, AX MOV ES, AX MOV FS, AX MOV GS, AX MOV SS, AX RET
Thanks in advance for any and all help.