Page 1 of 1

GDT Stuff

Posted: Mon Aug 19, 2002 8:24 am
by PlayOS
Hey everyone, :)

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.

Thanks.

Re:GDT Stuff

Posted: Mon Aug 19, 2002 9:26 am
by PlayOS
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.

Re:GDT Stuff

Posted: Mon Aug 19, 2002 5:21 pm
by Alfhiger
SGDT is not needed.

You can just declare a new GDT and load it as in your
booter.

Or copy it to address 0 and load it with a new GDTPointer :

Code: Select all


GDTPointer : 
     dw 23
     dd  0
........................
........................

lgdt [GDTPointer ]

jmp 0x08:NewGDT

NewGDT :
........................
........................

Re:GDT Stuff

Posted: Mon Aug 19, 2002 7:34 pm
by Krom
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"

Re:GDT Stuff

Posted: Tue Aug 20, 2002 12:36 am
by DynatOS
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.

Re:GDT Stuff

Posted: Tue Aug 20, 2002 7:28 am
by PlayOS
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:


[BITS 16]
[ORG 0x0]

jmp short PlayOS

; ====================================
; The GDT Setup Entries
gdt_start
   ; ====================================
   ; Null Segment Descriptor, 0x00
   dw 0x18
   dd gdt_start + 0x7C00
   dw 0

   ; ====================================
   ; 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:

; ====================================
; Initialize Segment Regs
   xor      ax, ax
   mov      ds, ax
   mov      es, ax
   mov      fs, ax
   mov      gs, ax

; ====================================
; Setup a Real Mode Stack
   cli
   mov      ax, 0x9000
   mov      ss, ax
   mov      sp, 0xFFFF

; ====================================
; Enable the A20 Gate
   call   Empty_8042
   mov      al, 0xD1
   out      0x64, al

   call   Empty_8042
   mov      al, 0xDF
   out      0x60, al

   call   Empty_8042
   jmp      A20_GateDone

Empty_8042:

   mov      al, 0xD0
   in      al, 0x64
   test   al, 2
   jnz      Empty_8042
   ret

A20_GateDone:

; ====================================
; Load the GDTR
   lgdt   [0x7C00 + gdt_start]

; ====================================
; Set PM Bit
   mov      eax, cr0
   or      eax, 1
   mov      cr0, eax

; ====================================
; Jump into PMode Code
   jmp      0x08:0x7C00 + EnterPMode

[BITS 32]
EnterPMode:

; ====================================
; Set Data and Stack Segments
   mov      ax, 0x10
   mov      ds, ax
   mov      es, ax
   mov      fs, ax
   mov      gs, ax
   mov      ss, ax

; ====================================
; Prove that we get here, poke an 'A' into Video Memory
   mov      word [0xB8000], 0x1E41

; ====================================
; Loop forever
HaltPlayOS:
   jmp    short HaltPlayOS

times 510-($-$$) db 0
PlayOS_Signature dw 0xAA55

thanks

Re:GDT Stuff

Posted: Tue Aug 20, 2002 8:06 am
by Krom
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.

Re:GDT Stuff

Posted: Tue Aug 20, 2002 8:35 am
by Alfhiger
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 !!!!

Code: Select all

[BITS 16]
[org 0x7c00]

jmp short PlayOS

; ====================================
; The GDT Setup Entries
gdt_start
; ====================================
; Null Segment Descriptor, 0x00
dw 0x17   ; 3*8-1 !!!!
dd 0     ; YOU WANT IT !!!!
dw 0

; ====================================
; 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:

; ====================================
; Initialize Segment Regs
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

; ====================================
; Setup a Real Mode Stack
cli
mov ax, 0x9000
mov ss, ax
mov sp, 0xFFFF

; ====================================
; Enable the A20 Gate
call Empty_8042
mov al, 0xD1
out 0x64, al

call Empty_8042
mov al, 0xDF
out 0x60, al

call Empty_8042
jmp A20_GateDone

Empty_8042:

mov al, 0xD0
in al, 0x64
test al, 2
jnz Empty_8042
ret

A20_GateDone:
; ====================================
; Copy GDT at 0x00000000
mov si, gdt_start
mov di, 0x00000000
mov cx, 0x18
rep movsb

; ====================================
; Load the GDTR
lgdt [0x00000000] ; gdtp is at 0x00000000

; ====================================
; Set PM Bit
mov eax, cr0
or eax, 1
mov cr0, eax

; ====================================
; Jump into PMode Code
jmp 0x08:EnterPMode

[BITS 32]
EnterPMode:

; ====================================
; Set Data and Stack Segments
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax

; ====================================
; Prove that we get here, poke an 'A' into Video Memory
mov word [0xB8000], 0x1E41

; ====================================
; Loop forever
HaltPlayOS:
jmp short HaltPlayOS

times 510-($-$$) db 0
PlayOS_Signature dw 0xAA55

Re:GDT Stuff

Posted: Tue Aug 20, 2002 8:46 am
by PlayOS
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?