Page 1 of 2
Problem with GDT pointer
Posted: Tue Mar 11, 2008 3:30 pm
by billion_boi
hey,
Ive managed to compile my bootloader using NASM with no errors , but the code doesnt run beyond the GDTpointer that ive marked below...I can print a string befor the line...but not after...Any ideas as to why?
Its not like ive loaded the segment register that my string function uses with the descriptor offsett yet...
Code: Select all
GDT:
.Gdt_null:
Dw 0
Dw 0
Dw 0
Dw 0
.Gdt_code:
Dw 1
Dw 0
Db 0
Db 10011010
Db 11011111
Db 0
.Gdt_data:
Dw 1
Dw 0
Db 0
Db 10010010
Db 11011111
Db 0
.Gdt_end:
.Gdt_pointer:
Dw .Gdt_end - .Gdt_code -1 ;****Error here
Dd .Gdt_code
Posted: Tue Mar 11, 2008 3:53 pm
by jzgriffin
You aren't supposed to "run" the GDT--you're supposed to load it with lgdt [gdtpointer]. Perhaps you could post the rest of your code?
Posted: Tue Mar 11, 2008 4:00 pm
by billion_boi
Code: Select all
[BITS 16]
[ORG 0X7E00] ;
jmp main
main:
;****segment DS register is already set at 00000 for you by the bootloader
mov si, BootstrapLoaded ;Load into the index register the offsett of the string
call PrintMsg
Call GDT
mov si,GDTLoaded
Call PrintMsg
jmp $
;The following GDT notes are written in Notes3 file
GDT:
.Gdt_null:
Dw 0
Dw 0
Dw 0
Dw 0
.Gdt_code:
Dw 1
Dw 0
Db 0
Db 10011010
Db 11011111
Db 0
.Gdt_data:
Dw 1
Dw 0
Db 0
Db 10010010
Db 11011111
Db 0
.Gdt_end:
.Gdt_pointer:
Dw .Gdt_end - .Gdt_code -1
Dd .Gdt_code
.Gdt_load
CLI
Lgdt [.Gdt_pointer]
Ret
PrintMsg: ;The datasegment register for the bootstrap is loaded in the first stage bootsector
mov ah, 0x0e
mov bh, 0x00
mov bl, 0x07
.NextChar:
mov al, [ds:si]
inc si ;
or al, al
jz .Break
int 0x10
jmp .NextChar
.Break:
ret
BootstrapLoaded: db "The bootstrap(extended bootloader) is running", 13, 10, 0
GDTLoaded: db "GDT is loaded",13,10,0
Posted: Tue Mar 11, 2008 4:04 pm
by Combuster
should be
for the reason previously explained
Posted: Tue Mar 11, 2008 4:18 pm
by billion_boi
i see, so i could however enable the pmode bit in the Cr0 register first...and then run and load the GDt right?
Posted: Tue Mar 11, 2008 4:53 pm
by Combuster
Posted: Tue Mar 11, 2008 4:54 pm
by jzgriffin
You need to load the GDT prior to enable protected mode. See the
Wiki page for Protected mode.
Posted: Tue Mar 11, 2008 5:00 pm
by Combuster
Actually, you don't need a GDT in order to set the PE bit successfully.
Posted: Tue Mar 11, 2008 5:19 pm
by billion_boi
Here is my restructured code in which im only loading the GDT not running it.
But i still have the issue that the code doesnt run beyond the pointer.
Code: Select all
[BITS 16]
[ORG 0X7E00]
jmp main
main:
;****segment DS register is already set at 00000 for you by the bootloader
mov si, BootstrapLoaded
call PrintMsg
mov si, MSGPmode
Call PrintMsg
Call GDT_load
jmp $
;The following GDT notes are written in Notes3 file
GDT_run:
.Gdt_null: ;Offset 0, descriptor code 0
Dw 0
Dw 0
Dw 0
Dw 0
.Gdt_code: ;Offset 8 bytes down, 0x8h
Dw 1
Dw 0
Db 0
Db 10011010
Db 11011111
Db 0
.Gdt_data: ;Offsett 16 bytes down, 0x10h
Dw 1
Dw 0
Db 0
Db 10010010
Db 11011111
Db 0
.Gdt_end:
GDT_load:
.Gdt_pointer:
Dw GDT_run.Gdt_end - GDT_run.Gdt_code -1
Dd GDT_run.Gdt_code
;*******************************Problem here....String doesnt print...*******************
mov si, OK;Load into the index register the offsett of the string
Call PrintMsg
.Gdt_load
CLI
Lgdt [.Gdt_pointer]
Ret
PrintMsg:
mov ah, 0x0e
mov bh, 0x00
mov bl, 0x07
.NextChar:
mov al, [ds:si] ;DS (segment selecter not necessar, NASM will assume current data segment)
inc si
or al, al ; if al=0 (the last character=null) then 0 flag is set
jz .Break
int 0x10
jmp .NextChar
.Break:
ret
BootstrapLoaded: db "The bootstrap(extended bootloader) is running", 13, 10, 0
MSGPmode: db "Loading Protected Mode",13,10,0
OK: db "[OK]",13,10,0
Posted: Tue Mar 11, 2008 5:37 pm
by nekros
you are "running" the gdt pointer. Call .gdt_load gdt_load doesn't do anything.
Posted: Tue Mar 11, 2008 5:55 pm
by billion_boi
nekros, Jeremiah, Combuster...I think i figured out what youve been trying to tell me this whole time...So now in what i hope is the last example, im not running the GDT, ive only set up the pointer...But still i cant get the string to print...Any ideas as to why?
Code: Select all
Call GDT_run.Gdt_pointer
jmp $
GDT_run:
.Gdt_null: ;Offset 0, descriptor code 0
Dw 0
Dw 0
Dw 0
Dw 0
.Gdt_code: ;Offset 8 bytes down, 0x8h
Dw 1
Dw 0
Db 0
Db 10011010
Db 11011111
Db 0
.Gdt_data: ;Offsett 16 bytes down, 0x10h
Dw 1
Dw 0
Db 0
Db 10010010
Db 11011111
Db 0
.Gdt_end:
ret
.Gdt_pointer:
Dw GDT_run.Gdt_end - GDT_run.Gdt_code -1
Dd GDT_run.Gdt_code
;*******************************Problem here....String doesnt print...*******************
mov si, OK;Load into the index register the offsett of the string
Call PrintMsg
ret
Posted: Tue Mar 11, 2008 6:01 pm
by jzgriffin
You're still trying to run the GDT. Replace the call with this:
Code: Select all
lgdt [GDT_run.Gdt_pointer]
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
jmp 0x08:Flush
Flush:
mov si, OK;Load into the index register the offsett of the string
Call PrintMsg
Posted: Tue Mar 11, 2008 6:17 pm
by nekros
Please tell me you understand that :'( If you do not, RTFM. The idea is not to execute the pointer. It is to LOAD the pointer into the gdtr.
Posted: Tue Mar 11, 2008 6:24 pm
by billion_boi
Since in the code i havent used thr LGDT instruction, or called the function that sets up the descriptors.... rather just set the limit and base adress in the pointer. Why or how is it that im running the GDT?
Posted: Tue Mar 11, 2008 6:26 pm
by jzgriffin
You're jumping to the address of the GDT pointer, where you've dw/dd'd some bytes. When the processor sees those bytes it tries to execute them as opcodes. You are trying to run data as code.