Failure on long jump to PM

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.
Post Reply
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Failure on long jump to PM

Post by Mikae »

Hello all.

I've run into an obstacle, that a very simple code, switching CPU to PM doesn't work in VMWare and on real hardware, but excellent works in Bochs.

Code: Select all

org 0x7C00

 xor ax, ax
 mov ds, ax
 mov es, ax
 mov ss, ax
 mov sp, 0x7C00

 cli
 lgdt [GDTR]
 mov eax, cr0
 or al, 0x1
 mov cr0, eax
;This jump causes reboot.
 jmp 0x8:pm

use32
pm:
 jmp $

GDT_START:
;Empty descriptor
 dq 0x0
;CS
 dw 0xFFFF    ;limit
 dw 0x0       ;dw_base
 db 0x0       ;db_base2
 db 10011010b ;AR (P=1,DPL=0,S=1,TYPE=e/r,A=0)
 db 11001111b ;G=1,D=1,L=0,U=0,LIMIT=1111b
 db 0x0       ;db_base3
GDT_SIZE = $ - GDT_START - 1

GDTR:
dw GDT_SIZE
dd GDT_START
It seems to me that I've lost in a three trees... Any ideas?..

TIA,

Mikae.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

I don't see anything wrong with that code, not sure what is going on. Wonder why it works in bochs and not others. Mine works in bochs and qemu, and real hardware and is setup as such:

Code: Select all

[bits	16]
[org	0x7c00]

	cld
	xor		ax,		ax
	mov		ss,		ax
	mov		es,		ax
	mov		ax,		0x7c00
	mov		sp,		ax

	lgdt	[gdt_desc]
	cli										;Clear interrupts before we switch to 32-bit mode

	mov		eax,	cr0
	inc		eax
	mov		cr0,	eax

	jmp		0x8:Go32						;Jump to 32-bit code
[bits	32]
Go32:
	mov		eax,		0x10
	mov		ds,		eax
	mov		es,		eax
	mov		gs,		eax
	mov		fs,		eax
	mov		ss,		eax
	mov		esp,		0x7000
.hang jmp .hang

gdt:                    ; Address for the GDT
gdt_null:               ; Null Segment
		dw	0
		dw	0
		db	0
		db	0
		db	0
		db	0

gdt_code:               ; Code segment, read/execute, nonconforming
        dw 0xFFFF
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0

gdt_data:               ; Data segment, read/write, expand down
        dw 0xFFFF
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0
gdt_end:						; Used to calculate the size of the GDT

gdt_desc:                       ; The GDT descriptor
        dw gdt_end - gdt - 1    ; Limit (size)
        dd gdt                  ; Address of the GDT
A lot of this was cut/pasted, there was a lot more code that I stripped, and added the hang loop in there, I actually load/jump to my kernel, not hang ;).
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

What about if you add Data descriptor etc ? .
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

He is not accessing data, there is no need for one. He doesn't even have to set up his real mode stack since he calls no interrupts nor pushes anything onto the stack.
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Post by Mikae »

Ready4Dis, did you try to execute the code above on a real harware? (Exactly that code, I mean)

Dex, originally, the code contained data segment, but I removed it for clairity. Anyway, this code doesn't work in VMWare too

Code: Select all

org 0x7C00

 xor ax, ax
 mov ds, ax
 mov es, ax
 mov ss, ax
 mov sp, 0x7C00

 cli
 lgdt [GDTR]
 mov eax, cr0
 or al, 0x1
 mov cr0, eax
;This jump causes reboot.
 jmp 0x8:pm

use32
pm:
 jmp $

GDT_START:
;Empty descriptor
 dq 0x0
;CS
 dw 0xFFFF    ;limit
 dw 0x0       ;dw_base
 db 0x0       ;db_base2
 db 10011010b ;AR (P=1,DPL=0,S=1,TYPE=e/r,A=0)
 db 11001111b ;G=1,D=1,L=0,U=0,LIMIT=1111b
 db 0x0       ;db_base3

;DS, ES, ES
 dw 0xFFFF    ;limit
 dw 0x0       ;dw_base
 db 0x0       ;db_base2
 db 10010010b ;AR (P=1,DPL=0,S=1,TYPE=drw,A=0)
 db 11001111b ;G=1,D=1,L=0,U=0,LIMIT=1111b
 db 0x0       ;db_base3
GDT_SIZE = $ - GDT_START - 1

GDTR:
dw GDT_SIZE
dd GDT_START
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Yes, it runs on an Intel Celeron 2.4ghz 256mb ram compaq laptop i have, like I said, I removed a lot, but that is the code that I use to enter pmode, cut and pasted. It does a lot in between, like load the kernel and some supporting drivers from disk, check for memory, enable the a20 line, enable paging, and some text and hex display functions. I can paste my entire bootloader if you really wanted, but it will probably confuse more than help, it's 2 sectors long btw.
Mikae
Member
Member
Posts: 94
Joined: Sun Jul 30, 2006 1:08 pm

Post by Mikae »

Oops, I found the problem. Loader which runs in Bochs and loader, which runs on my hardware are different. I've totally forgot about it. Sorry for disturbing :? .
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Mikae wrote:Oops, I found the problem. Loader which runs in Bochs and loader, which runs on my hardware are different. I've totally forgot about it. Sorry for disturbing :? .
lol, well at least I feel better for telling you that everything looked like it should work and I couldn't see any problems :P. Glad you figured it out.
Post Reply