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.
I finally after 3 days of trying, got my boot code to successfully go into PMode. Only in the GDT the null descriptor is used as the base and limit of the table and its size is set to 24 (null+2 descriptors) however I want to be able to put the GDT at 0:0 how can I move the GDT and also how to I dynamically add descriptors to the table once it is there?
I have been looking at the Intel manuals but they dont seem to explain it very well, if at all, so I thought I would ask you guys who have already encountered such situations.
Is it possible for me to create another one later when I need it. If so do I use the SGDT instruction to store the new one? I am not too sure about the SGDT instruction or what it does, I have the Intel manuals but I cant seem to follow them very well.
Thanks again to Krom for his help on my boot code.
I'm not a pmode guru, i have only play a little with it. The only thing i made in pmode is that boot sector and one program to test it.
About SGDT it stores the pointer to GDT, i mean, if you doesnt know where is the gdt, you can know using this instruction. more or less LGDT is like MOV GDT, POINTER and SGDT is MOV POINTER, GDT.
You can put your GDT in any place you wants, but you wants to put it at 0:0 like this way you are trashing the real mode IDT and the BIOS data segment(the one at 40:0). You may think you doesnt need this data, but it is very usefull, i recomend dont touch it, it is only 1.1k and you may need in future.
I think once you put GDT in place and if you have reserved more space for more selectors, you doesnt need to touch it again. When you change or add new selectors just reload the segment register with the selector that you have change and it is done.
I doesnt know if the CPU stores the GDT internaly so when you change some selector's data you must reload the GDT, is a good question, i hope someone will answer this for us.
anyway i have stoped my pmode os project and i have started a real mode os project. Doing a pmode os without knowing how a os sould be is like trying to make a "steel sword" and still didnt discover how to make the "steel"
1. Make a temporary GDT in your boot process and jump to protected mode.
2. Load the GDT from a file/kernel/etc to 0000:0000 or copy your current temporary GDT to 0000:0000
3. Change your GDT pointer to match the new address.
4. Load the GDTR with the GDT pointer.
5. Execute a process similar to the initial protected mode switch.
PS: SGDT is only to store the GDT Register (GDTR) to a location in memory, it is an equivalent of storing a variable pointer.
I have tried loading a new GDT but my cpu just freezes I am not sure if I need to keep on adding 0x7C00 to data offsets or not, anyway here is my complete boot code if anyone wants to try and show me what I could do:
; ====================================
; Code Segment Descriptor, 0x08
db 11111111b ; 4GB Limit
db 11111111b ; 4GB limit
db 00000000b ; Base 0
db 00000000b ; Base 0
db 00000000b ; Base 0
db 10011010b ; Present : Ring 0 : Code\Exec : Non-Conforming : Readable : Not Accessed
db 11001111b ; 4KB Granularity : 32Bit : 4GB Limit
db 00000000b ; Base 0
; ====================================
; Data Segment Descriptor, 0x10
db 11111111b ; 4GB Limit
db 11111111b ; 4GB limit
db 00000000b ; Base 0
db 00000000b ; Base 0
db 00000000b ; Base 0
db 10010010b ; Present : Ring 0 : Data : Expand Up : Writable : Not Accessed
db 11001111b ; 4KB Granularity : 32Bit : 4GB Limit
db 00000000b ; Base 0
gdt_end
; ====================================
; BootLoader Starting Position
PlayOS:
I suppose that you doesnt see the 'A' that should be in the beggining of the screen once you are in pmode. If this happen you should put another letter in the screen once you enable the A20, who knows, maybe you never finish enabling A20.
Another thing i see is that you doesnt initialize ESP once you are in pmode. You already initialized it in real mode, but only SP, maybe there is some bits in ESP that **** the things, should not be a problem, but is better to be safe.
One last thing, whenever is possible dont put SP=0XFFFF, put it at 0XFFFE, and when you put ESP put it in something that finish in C or 8 or 4 or 0, try to avoid other numbers, it may slow the code.
I did not understand your plans.
I thought you wanted to set a new GDT at 0x00000000
from your kernel.
In fact you want to do it fromm your bootloader so you must copy it to
that address because your bootloader is 512 bytes long and loaded at
0x00007c00 so you can not put in it a GDT at 0x00000000 directly !!!!
I either want it there from the boot code or to make a new one from my kernel, I am still not sure about whether to keep the RM IDT, if I wait until my kernel to setup the final GDT then I can still use the RM IDT for loading the kernel and getting VESA info and stuff like that, what do you think is the best way to go about it?