I can't switch to 32-bit protected mode.

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.
ThatGuy2244
Posts: 15
Joined: Wed Feb 02, 2011 2:15 pm

I can't switch to 32-bit protected mode.

Post by ThatGuy2244 »

I have tried to switch to 32-bit protected mode by setting up my GDT:

Code: Select all

GDTStart:
	dd 0x00000000 ;Descriptor 0 Null
	dd 0x00000000
	dw 0xffff ;Descriptor 1 Code
	dw 0x0000
	db 0x00
	db 10011010b
	db 11001111b
	db 0x00
	dw 0xffff ;Descriptor 2 Data
	dw 0x0000
	db 0x00
	db 10010010b
	db 11001111b
	db 0x00
GDTEnd:
and then setting up GTDInfo:

Code: Select all

GDTInfo:
	dw GDTEnd - GDTStart - 1
	dd GDTStart
Then switching to pmode:

Code: Select all

        lgdt [GDTInfo]
	mov eax, cr0
	or eax, 1
	mov cr0, eax
	jmp 0x08:pmode
My entire code is:

Code: Select all

	[BITS 16]
	org 0x100 ;this is a .COM file

	lgdt [GDTInfo]
	mov eax, cr0
	or eax, 1
	mov cr0, eax
	jmp 0x08:pmode
	
	GDTInfo:
	dw GDTEnd - GDTStart - 1
	dd GDTStart
	
	GDTStart:
	dd 0x00000000 ;Descriptor 0 Null
	dd 0x00000000
	dw 0xffff ;Descriptor 1 Code
	dw 0x0000
	db 0x00
	db 10011010b
	db 11001111b
	db 0x00
	dw 0xffff ;Descriptor 2 Data
	dw 0x0000
	db 0x00
	db 10010010b
	db 11001111b
	db 0x00
	GDTEnd:
	
	[BITS 32]
	
pmode:
This code every time I run it in DOSbox it gives me the error "JMP to Illegal Descriptor type 0" and then crashes. I have tried many things to try to get it to work be with no successes, any ideas on what could be wrong?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: I can't switch to 32-bit protected mode.

Post by Combuster »

dd GDTStart
That is a virtual address, not a 32-bit linear address as required. You still need to add segment * 16 to it before it points to the right location
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
ThatGuy2244
Posts: 15
Joined: Wed Feb 02, 2011 2:15 pm

Re: I can't switch to 32-bit protected mode.

Post by ThatGuy2244 »

I tried writing it as seg:offset but it got an error when I tried to assemble it.

Code: Select all

GDTInfo:
	dw GDTEnd - GDTStart - 1
	dd 0x00:GDTStart
I think it has something to do with the way I formatted it -- I don't know how to format a seg:offset in memory I assume it is something like when I use it in an instruction "mov [es:si], al".
User avatar
miker00lz
Member
Member
Posts: 144
Joined: Wed Dec 08, 2010 3:16 am
Location: St. Louis, MO USA

Re: I can't switch to 32-bit protected mode.

Post by miker00lz »

granted, i havent really done any 32-bit assembly (not much anyway, i've dicked around with a lot of 16-bit assembly on ancient machines) but shouldnt you do:

Code: Select all

dw 0
dd GDTStart
or something similar?
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: I can't switch to 32-bit protected mode.

Post by Owen »

ThatGuy2244 wrote:I tried writing it as seg:offset but it got an error when I tried to assemble it.

Code: Select all

GDTInfo:
	dw GDTEnd - GDTStart - 1
	dd 0x00:GDTStart
I think it has something to do with the way I formatted it -- I don't know how to format a seg:offset in memory I assume it is something like when I use it in an instruction "mov [es:si], al".
You write seg:off addresses as

Code: Select all

   dw offset, segment
Regardless, the information you place in the GDTR is a linear address, not a segment address

Because you're writing a DOS COM file, you don't know what your segment is at link time... therefore, its your job to work that out.

And just to check: The DOS you're running this under needs to be vary plain. EMS, XMS, VCPI or DCPI servers are likely to prevent you from switching to protected mode this way.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: I can't switch to 32-bit protected mode.

Post by gerryg400 »

The DOS you're running this under needs to be vary plain. EMS, XMS, VCPI or DCPI servers are likely to prevent you from switching to protected mode this way.
You should be able to boot and run a protected mode kernel using XMS. Just use XMS services to allocate and lock all the memory above 1M and use it. If you're very careful you ought to be able to free the memory and return to DOS when you're done without rebooting.
If a trainstation is where trains stop, what is a workstation ?
ThatGuy2244
Posts: 15
Joined: Wed Feb 02, 2011 2:15 pm

Re: I can't switch to 32-bit protected mode.

Post by ThatGuy2244 »

I have tried to do the formatting of the seg:off as "dw GDTStart, 0x00"and it still didn't work and gave me the same error. So what should I do to make it work?
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: I can't switch to 32-bit protected mode.

Post by gerryg400 »

I dunno much about assembler or com files but I think you'll need to read a segment register to find out where your program has been loaded. Then as Combuster said, calculate the linear address to give to LGDT. I don't think your assembler will know the segment value.
If a trainstation is where trains stop, what is a workstation ?
ThatGuy2244
Posts: 15
Joined: Wed Feb 02, 2011 2:15 pm

Re: I can't switch to 32-bit protected mode.

Post by ThatGuy2244 »

gerryg400 wrote:I dunno much about assembler or com files but I think you'll need to read a segment register to find out where your program has been loaded. Then as Combuster said, calculate the linear address to give to LGDT. I don't think your assembler will know the segment value.
Well I do know were the program is loaded and then told the assembler were it will be loaded so it should work, that's what the "org 0x100" is for, it tells the assembler (nasm) that the program will be loaded at the linear address 0x100. I know this is correct because I have done different programs with this, as a .COM files, and they have all worked.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: I can't switch to 32-bit protected mode.

Post by gerryg400 »

So does that mean that your CS and DS registers both contain 0 while you are in real mode ? If they are not 0 (and I suspect that they are not) then your code will not work.
If a trainstation is where trains stop, what is a workstation ?
ThatGuy2244
Posts: 15
Joined: Wed Feb 02, 2011 2:15 pm

Re: I can't switch to 32-bit protected mode.

Post by ThatGuy2244 »

gerryg400 wrote:So does that mean that your CS and DS registers both contain 0 while you are in real mode ? If they are not 0 (and I suspect that they are not) then your code will not work.
Well they are what ever DOS sets them to by default which I assume is 0, but all I know is, that my program is loaded to 0x100 and when I use that as the base address my code works.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: I can't switch to 32-bit protected mode.

Post by gerryg400 »

My apologies. If your code is working add "[Solved]" to the subject line of the thread and we can consider the thread closed.
If a trainstation is where trains stop, what is a workstation ?
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: I can't switch to 32-bit protected mode.

Post by Owen »

COM files are loaded with whatever segment DOS chooses for them. That segment will never be zero.

The ORG directive gives a virtual, not linear address. When doing OS development you would be wise to learn the distinction
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: I can't switch to 32-bit protected mode.

Post by Chandra »

Hi,
Then switching to pmode:

Code: Select all

Code:
   lgdt [GDTInfo]
   mov eax, cr0
   or eax, 1
   mov cr0, eax
   jmp 0x08:pmode
All references to the memory locations are made via ds:offset so, just set the data segment to 0 before you execute the lgdt instruction and that should work(IMO).
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: I can't switch to 32-bit protected mode.

Post by gerryg400 »

The solution is, as Combuter posted just 5 minutes after the question was asked and that Owen clarified shortly after, this ....

Code: Select all

GDTInfo:
   dw GDTEnd - GDTStart - 1
   dd GDTStart       ;  <<===== This should be a linear address calculated at RUNTIME equal to GDTStart + (DS << 4) NOT a segment relative value
It's very frustrating that the answer when given was simply ignored.

[Edit] Changed (DS >>4) to (DS << 4)
Last edited by gerryg400 on Mon Jun 20, 2011 12:10 am, edited 2 times in total.
If a trainstation is where trains stop, what is a workstation ?
Post Reply