Page 1 of 2

Problem with protected mode jump

Posted: Wed Oct 08, 2008 3:43 am
by Ferrarius
hi,

I'm still quite early in the development of my kernel. Which I wanted to build from the ground up and run in protected mode. After writing a bootloader succesfully enabling the A20 line and loading the kernel (both has been succesfully tested in bochs). I decided to move to the kernel as quickly as possible and make the kernel responsible for strting PM. After creating a GDT I decided to firt test whether this would work before moving on. As follows the GDT and kernel test code:

Code: Select all

GDT:

;####Null-Descriptor####
 dw 0x0000
 dw 0x0000
 db 0x00
 db 0x00
 db 0x00
 db 0x00

;####Code Ring 0####
 dw 0xFFFF   ;Limit
 dw 0x0000   ;Base
 db 0x00     ;Base
 db 0x9A     ;Present, Code|Execute/Read
 db 0xCF     ;Granu,32bits|Limit    
 db 0x00     ;Base

;####Data Ring 0####
 dw 0xFFFF   ;Limit
 dw 0x0000   ;Base
 db 0x00     ;Base
 db 0x92     ;Present, Data|R/W E-up
 db 0xCF     ;Granu,32bits|Limit
 db 0x00     ;Base

;####Code Ring 3####
 dw 0xFFFF   ;Limit
 dw 0x0000   ;Base
 db 0x00     ;Base
 db 0xFA     ;Present, Code|Execute/Read
 db 0xCF     ;Granu,32bits|Limit
 db 0x00     ;Base

;####Data Ring 3####
 dw 0xFFFF   ;Limit
 dw 0x0000   ;Base
 db 0x00     ;Base
 db 0xF2     ;Present, Data|R/W E-up
 db 0xCF     ;Granu,32bits|Limit
 db 0x00     ;Base

;####Task State Segment####
 dw 103      ;Limit
 dw 0        ;Base
 db 0        ;Base
 db 0x89     ;Ring 0, Present, Non-Busy
 db 0x00     ;BS
 db 0xC0     ;Base
GDTEND:

Code: Select all

[ORG 0x00020000]
[BITS 16]
main:
mov   ax,0xB800
mov   es,ax
mov   byte[es:0],'b'
cli
xor   ax,ax
mov   ds,ax

lgdt  [GDTDESC]
mov   eax,cr0
or    eax,1
mov   cr0,eax
jmp   0x08:enter_pmode

[BITS 32]
enter_pmode:
mov   ax, 0x08
mov   cs, ax
mov   ax, 0x10
mov   ds, ax
mov   ss, ax
mov   esp,0x90000

.print_char:
mov   byte[ds:0x0B8002],'a'
mov   byte[ds:0x0B8003],0x7F

.hang:
jmp .hang

%include "d:\vinitech\mik\gdt006.asm"

GDTDESC:
dw (GDTEND - GDT - 1)
dd GDT
I've tried several ways to get this working but I've reached the end of my Latin. According to bochs the kernel triple faults when jumping to enter_pmode

Re: Problem with protected mode jump

Posted: Wed Oct 08, 2008 5:57 am
by Martijn
Remove 'mov cs, ax'. Mov can't place a value in the cs register.
Only 'far' control-transfer instructions (retf, jmp 0x?:0x?, ...) can change cs.

Re: Problem with protected mode jump

Posted: Wed Oct 08, 2008 6:55 am
by System123
Ferrarius wrote:[BITS 32]
enter_pmode:
mov ax, 0x08
mov cs, ax
mov ax, 0x10
mov ds, ax
mov ss, ax
mov esp,0x90000
Your problem like Martijn said is that you can not change cs like you have. You have alreaady changed the cs register when you jumped like:
Ferrarius wrote:jmp 0x08:enter_pmode

Re: Problem with protected mode jump

Posted: Wed Oct 08, 2008 11:54 am
by Ferrarius
I've changed the oversight, it however changes nothing about the triple faults.

Re: Problem with protected mode jump

Posted: Wed Oct 08, 2008 12:19 pm
by Martijn
I think your compiler already does this for you automatically, but you can give it a try.

Replace: jmp 0x08:enter_pmode
With: jmp pword 0x08:enter_pmode

Re: Problem with protected mode jump

Posted: Thu Oct 09, 2008 4:56 am
by egos
And what this means?

Code: Select all

[ORG 0x00020000]
...
xor   ax,ax
mov   ds,ax

lgdt  [GDTDESC]
Segment size in the real mode is 0x10000. Whether you indicated not too large displacement.

Re: Problem with protected mode jump

Posted: Thu Oct 09, 2008 9:44 am
by System123
Why are you doing [ORG 0x20000] is that where your code is loaded?

try this code in place of
Ferrarius wrote: cli
xor ax,ax
mov ds,ax

lgdt [GDTDESC]
mov eax,cr0
or eax,1
mov cr0,eax
jmp 0x08:enter_pmode

Code: Select all

	cli				; clear interrupts
	xor	ax, ax			; null segments
	mov	ds, ax
	mov	es, ax
	mov	ax, 0x9000		; stack begins at 0x9000-0xffff
	mov	ss, ax
	mov	sp, 0xFFFF
	sti	

	lgdt  [GDTDESC]

        cli
        mov   eax,cr0
        or    eax,1
        mov   cr0,eax
        jmp   0x08:enter_pmode

Re: Problem with protected mode jump

Posted: Thu Oct 09, 2008 9:51 am
by AJ
Hi,

lgdt[GDTDESC] actually loads from ds:[GDTDESC]. This means that clearing DS by loading it with a null AX stops you from accessing the GDT descriptor if you are above the 0xFFFF mark. That ORG 0x20000 also definitely dodgy to me in RMode.

Do you actually mean ORG 0x0000? In this case, you could place JMP 0x2000:entry at the start of your code, meaning that you are actually running at your desired offset.

Cheers,
Adam

Re: Problem with protected mode jump

Posted: Thu Oct 09, 2008 12:44 pm
by sebihepp
Hi,

hmmm... does the assembler not add 0x2000 to the ds:[GDTDESC], because of the org directive?
So that should be right.
But when you jump to the PMode, your assembler adds 0x2000 to the address of enter_pmode too.
But you can only use 16 bit for this address and that results, that the assembler adds 0x0002 to the
GDT-Value of the jump. You can change the base of the GDT-Entry, you jump to, to 0x2000, but this
will cause you to change many things in your code.

Greetings Sebihepp

Re: Problem with protected mode jump

Posted: Thu Oct 09, 2008 12:57 pm
by Ferrarius
[ORG 0x00020000] is indeed the place I've loaded the program into memory.

The jump is made now, the program arrives at enter_pmode. It however still triple faults at

Code: Select all

mov ds,ax

Re: Problem with protected mode jump

Posted: Fri Oct 10, 2008 12:15 pm
by sebihepp
hmmm, just try

Code: Select all

mov ax, (2<<3)
I had the same problem earlier and this solved it.
But I don't know why, because (2<<3) is equal to 0x10. It should be equal
at least...

Re: Problem with protected mode jump

Posted: Fri Oct 10, 2008 11:06 pm
by System123
I had the same problem however this was due to a fault in the pmode jump. Just double check the code. Post your new source here so we can have a look.

Re: Problem with protected mode jump

Posted: Sun Oct 12, 2008 9:25 am
by Ferrarius
The ocde as it stands now:

Code: Select all


[ORG 0x00020000]
[BITS 16]
main:
mov   ax,0xB800
mov   es,ax
mov   byte[es:0],'b'
cli
xor   ax,ax
mov   ds,ax
mov   es,ax
mov   ax,0x9000
mov   ss,ax
mov   sp,0xffff
sti

lgdt  [GDTDESC]
cli
mov   eax,cr0
or    eax,1
mov   cr0,eax
jmp   dword enter_pmode

%include "d:\vinitech\mik\gdt006.asm"

GDTDESC:
dw (GDTEND - GDT - 1)
dd GDT

[BITS 32]
enter_pmode:
mov   eax, 0x10
mov   ds,ax
mov   es,ax
mov   esp,0x00090000
sti

.print_char:
mov   byte[ds:0x000B8002],'a'
mov   byte[ds:0x000B8003],0x7F

.hang:
jmp .hang


times 512 - ($ - $$) db 0

Re: Problem with protected mode jump

Posted: Sun Oct 12, 2008 11:26 pm
by egos
You did not remove the error mentioned by me.

Code: Select all

mov   ax,0x9000
mov   ss,ax
mov   sp,0xffff
I'm crying seeing this: mov sp,0xffff :cry:
Furthermore, you try to use Extended BDA as a stack.

Re: Problem with protected mode jump

Posted: Mon Oct 13, 2008 7:18 am
by System123
Ferrarius wrote:jmp dword enter_pmode
You need to set the cs! rather jump like so:

Code: Select all

jmp 08h:enter_pmode
The other thing is you can't enable interrupts "sti" until you have an IDT set up. the CPU is getting confused.