Page 1 of 2

[SOLVED] Jumps in protected mode with GDT - not working

Posted: Fri Mar 01, 2013 12:56 pm
by HugeCode
Hi all. I followed tutorial from the web and I've create this code:

Code: Select all

org 0x1000
start:
	cli;
	lgdt [toc]
	sti;
	
	cli;
	mov eax, cr0
	or eax, 1
	mov cr0, eax
	;AFTER THIS POINT NOTHING WORKS
	jmp 0x8:pmode

BITS 32
pmode:
	mov edi, 0xB8000
	mov byte [edi], 0x43
	mov byte [edi+1], 0x07
	
	hlt;

; GDT CODE
gdt_start:
dd 0
dd 0

dw 0FFFFh 			
dw 0 				
db 0 				
db 10011010b 			
db 11001111b 	
db 0 	

dw 0FFFFh 
dw 0 				
db 0 				
db 10010010b 			
db 11001111b 			
db 0		
end_of_gdt:
toc: 
	dw end_of_gdt - gdt_data - 1 	
	dd gdt_data 	
	
Code stops working after moving eax back to cr0. It works perfectly to the jump. Since it, jumps don't work correctly, so I think there's something wrong with it. Does anybody know what? Code is loaded to 0x1000 in real mode by bootloader. Then, execution jumps to the "start" label of this code. Bootloader and stage2 are in separated files.

If anybody knows where can the problem be, please help.

Re: Jumps in protected mode with GDT - not works

Posted: Fri Mar 01, 2013 12:59 pm
by Gigasoft
You forgot to load DS.

Re: Jumps in protected mode with GDT - not works

Posted: Fri Mar 01, 2013 1:01 pm
by HugeCode
Data segment? Why is it needed for jumps?

Re: Jumps in protected mode with GDT - not works

Posted: Fri Mar 01, 2013 2:44 pm
by Combuster
Why would specifically the jump be wrong if you only demonstrated the code as a whole to be failing?

Hint: DS must change between its first and second usage. The second use is guaranteed to have the wrong value, and so might the first depending on your bootloader.

Re: Jumps in protected mode with GDT - not works

Posted: Fri Mar 01, 2013 3:51 pm
by iansjack
As Combuster asks, why do you say the fault is the jump? Are you running it under a debugger and have found the processor faults there? If not, what makes you suppose that the faulting instruction is not when you try to write to the screen (which is obviously going to fault if ds doesn't contain a valid selector) or any other instruction? How do you know it is even getting as far as the moves from and to the control register?

You haven't given us enough information, and you would appear to be making unwarranted assumptions. (On the other hand, it's possible that you are running under a debugger so know where the code is faulting. If that is the case, just look at the registers and it should be obvious what the fault is.)

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 5:04 am
by HugeCode
Virtual machine resets after reaching jump instruction. Here are states of regsiters.
Image
I have also changed the code a bit.

Code: Select all

cli;
mov eax, cr0
or eax, 1
mov cr0, eax
	
jmp 0x8:.setup
.setup:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
Problem is that the VM restarts and returns to 0x7C00 - bootloader. Does anybody know why? What can be the problem?

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 5:11 am
by iansjack
Either I'm being stupid, or your CS is wrong. As far as I can see you have not defined a descriptor for that value. But, you are jumping to 0x08:xxxx, and your CS is 0x1000; your code has never tried to execute the jump. Something is wrong earlier, probably an invalid GDT.

Edit: Hang about! What's "gdt_data"?

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 6:06 am
by Combuster
Code is loaded to 0x1000 in real mode by bootloader.
Breakpoint 13, 0x00010019
That just proved your original statement was false.

In other words, the first bug is the org statement, and from CS != 0, may more bugs will follow.

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 6:23 am
by HugeCode
Yes, that's true. It's loaded to es=0x1000, so it means it's loaded to 0x10000. I have "repaired" my origin to 0x10000. What's wrong next? What do I need to do?

gdt_data is the beginning of GDT.

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 6:37 am
by iansjack
gdt_data is the beginning of GDT
Not in the code you have given us, it isn't.

I'd suggest that you single-step the code under a debugger, inspect your GDT, and see exactly where the fault is happening. It really ought to be fairly obvious.

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 7:09 am
by HugeCode
Repaired, still same behaivor. But i've done single steps and I found out that my code jumps to 0x1e = code descriptor start(0) + 1e instruction start. How can I jump correctyl to my label? When I set origin to 0x1000 before label and I try to jump there by

Code: Select all

jmp 0x8:pmode
by debugger it jumps to 0xFFFFFFF0. ???

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 7:41 am
by iansjack
Just as a matter of interest, what assembler are you using, and what is the value of CS at the start of your code?

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 7:58 am
by HugeCode
I'm using NASM for compilation, GDB for debugging (with intel syntax set for disasm). On the beginning of stage2 (code I've posted here), it's 0x1000 (value got by gdb info registers).

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 8:46 am
by egos
10000h+1000h=11000h, isn't it?

Try this:

Code: Select all

  org 0
  lgdt [gdtr] ; I hope that cs=ds=1000h 
  ...

  align 8
gdt:
  ...
gdt_end:

gdtr:
  dw gdt_end-gdt-1
  dd 10000h+gdt ; convert gdt offset into linear address

Re: Jumps in protected mode with GDT - not works

Posted: Sat Mar 02, 2013 9:37 am
by HugeCode
still not works. I've checked if the GDT is loaded from good address by debugger, and it is.