[SOLVED] Jumping into real from 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.
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

[SOLVED] Jumping into real from protected mode

Post by HugeCode »

Hi all. It's me with my GDT again. I met another problem when setting ES to my 16bit entry... Here is my code:

Code: Select all

; gdt real:				
	dw 0FFFFh 			; limit low
	dw 0 				; base low
	db 0 				; base middle
	db 10011010b 			; access, RW|EXE|Ring0
	db 00001111b 			; size = 0 (16bit), granularity = 0 (1B for everything in limit)
	db 0				; base high
Does anybody any idea where can be the problem? Please help.

Code: Select all

...
mov ax, 0x18
mov es, ax         ;after executing this instruction the GPF occurs

jmp es:0x8400
GPF occured
GPF occured
Last edited by HugeCode on Sun May 12, 2013 6:01 am, edited 1 time in total.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Jumping into real from protected mode

Post by Brendan »

Hi,
HugeCode wrote:

Code: Select all

	db 10011010b 			; access, RW|EXE|Ring0
How can a segment be readable, writable and executable?

Note: This decodes as: present, DPL=0, system (not code or data), and "reserved".


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Jumping into real from protected mode

Post by HugeCode »

I've cleared that bit but it still isn't working.
Do I have to make two realmode descriptors? I don't think so because I'm not writing in it, after far jump I clear cr0:0 to turn pmode off and I make another far jump....
I don't think problem's there. I tried to clear executable bit and GPF still occurs.
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: Jumping into real from protected mode

Post by Mikemk »

HugeCode wrote:Do I have to make two realmode descriptors?.
There's no such thing as a real mode descriptor. Pmode requires 32-bit, V8086 requires 16-bit.

Also, your gpf is in the jump.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Jumping into real from protected mode

Post by Brendan »

Hi,

Doh - I got my "system" flag around the wrong way :oops:
HugeCode wrote:Do I have to make two realmode descriptors?
You can load an "executable, read-only" segment into ES, but you can't load an "executable, read-only" segment into SS, so you will need to make 2 descriptors.
HugeCode wrote:I don't think so because I'm not writing in it, after far jump I clear cr0:0 to turn pmode off and I make another far jump....
Are you sure that the "mov es, ax" causes the exception (and that the exception isn't caused by a different instruction afterwards)? If it's definitely the "mov es,ax" causing the exception then the only other thing is the GDT (e.g. dodgy GDT limit or something).

Also; I don't know which assembler you're using; and don't know what the "jmp es:0x8400" instruction is. Is it "jmp 0x8400" with an ignored segment override prefix, or is it "jmp [es:0x8400]" (near jump to the value stored at es:0x8400)? It looks like "jump to es:0x8400" but there is no such instruction.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Jumping into real from protected mode

Post by HugeCode »

I'm absolutely sure it's the GDT. I removed code with moving ax to es and manually wrote far jump instruction. When I come to that instruction, GPF occurs.
My jump code (gdb translates it as normal ljmp):

Code: Select all

_emit(0xEA);
_emit(0x00);   //offset
_emit(0x84);   
_emit(0x00);
_emit(0x00);
_emit(0x18);   //selector
_emit(0x00);
My newest GDT:

Code: Select all

; gdt real:				; data descriptor
dw 0FFFFh 			; limit low
dw 0 				; base low
db 0 				; base middle
db 10001000b 			; access, EXE|Ring0|Present
db 00100111b 			; granularity, size = 0 (16bit), granularity = 0 (1B for everything in limit)
db 0				; base high
BTW wiki says that:
RW: Readable bit/Writable bit.
Readable bit for code selectors: Whether read access for this segment is allowed. Write access is never allowed for code segments.
Writable bit for data selectors: Whether write access for this segment is allowed. Read access is always allowed for data segments.
So if I have RW bit set, it shouldn't be problem, will it?

EDIT: does anybody have some working code which switches OS to real mode? Maybe I can compare it with mine to see what's different.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Jumping into real from protected mode

Post by Brendan »

Hi,
HugeCode wrote:I'm absolutely sure it's the GDT. I removed code with moving ax to es and manually wrote far jump instruction. When I come to that instruction, GPF occurs.
My jump code (gdb translates it as normal ljmp):

Code: Select all

_emit(0xEA);
_emit(0x00);   //offset
_emit(0x84);   
_emit(0x00);
_emit(0x00);
_emit(0x18);   //selector
_emit(0x00);
At least that answers one of my questions - the original jump was meant to be "jmp far 0x0018:0x8400" (assuming NASM - still don't know which assembler).
HugeCode wrote:My newest GDT:

Code: Select all

; gdt real:				; data descriptor
dw 0FFFFh 			; limit low
dw 0 				; base low
db 0 				; base middle
db 10001000b 			; access, EXE|Ring0|Present
db 00100111b 			; granularity, size = 0 (16bit), granularity = 0 (1B for everything in limit)
db 0				; base high
You're making random guesses and screwing things up more (this is worse than the original code). Sooner or later you'll realise it's easier to read the relevant part of the Intel manual.. ;)
HugeCode wrote:BTW wiki says that:
RW: Readable bit/Writable bit.
Readable bit for code selectors: Whether read access for this segment is allowed. Write access is never allowed for code segments.
Writable bit for data selectors: Whether write access for this segment is allowed. Read access is always allowed for data segments.
So if I have RW bit set, it shouldn't be problem, will it?
It also says that Bit 11 (the "Ex" bit) determines if the descriptor is executable (where the "RW" bit is actually a "readable or not readable" bit) or if the descriptor is data (where there RW bit is actually a "read only or read write" bit).

Basically:

Code: Select all

Ex RW
0  0 = read only data
0  1 = read/write data
1  0 = execute only
1  1 = execute/read
HugeCode wrote:EDIT: does anybody have some working code which switches OS to real mode? Maybe I can compare it with mine to see what's different.
Did you search the wiki?


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Jumping into real from protected mode

Post by HugeCode »

Yes, I was following that tutorial. There isn't any GDT example....
BTW what's wrong with my GDT now? To make this descriptor I used osdev wiki.
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: Jumping into real from protected mode

Post by Mikemk »

BTW, the table in the wiki is confusing, and nasm moves your stuff around anyway due to endianness. If you have windows 7/8, the programming calculator is an excellent tool for calculating GDTs (how ironic)

It'll be the first thing I produce in my OS.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Jumping into real from protected mode

Post by HugeCode »

It's disease! Not GDT error. It looks like I don't have right to change segment registers... :?: :?: :?: :?: :?: :?:
Screenshot_1.png
Screenshot_1.png (11.4 KiB) Viewed 3005 times
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: Jumping into real from protected mode

Post by Combuster »

It's disease!
In your brain, possibly. But again I only see "I think"'s rather than meaningful information. So you're getting a GPF and you're probably not even printing it correctly. What does that help us?

Learn to debug.
"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 ]
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Jumping into real from protected mode

Post by HugeCode »

I've debugged it with VMWare. It still occurs on the mov.
HugeCode
Member
Member
Posts: 112
Joined: Mon Dec 17, 2012 9:12 am

Re: Jumping into real from protected mode

Post by HugeCode »

Ok. I found out that the 0x10 as a selector works, but the descriptor doesn't.
I also tried to use usermode descriptor:

Code: Select all

; gdt data:				; data descriptor
dw 0FFFFh 			; limit low (Same as code)
dw 0 				; base low
db 0 				; base middle
db 11110010b 			; access
db 11001111b 			; granularity
db 0				; base high
This doesn't work either. Can you see any problem in it?
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: Jumping into real from protected mode

Post by Mikemk »

HugeCode wrote:I also tried to use usermode descriptor:
You are still making random guesses. PS, VMWare doesn't have debugging capabilities, at least mine doesn't.
Let me ask you this:
Does it make any sense whatsoever to use a ring 3 descriptor for ring 0? If not, why even try?

Here's some hints. Hopefully, you'll use them to find your answer.
  1. The bit number x means, 2^x = value in bit x
  2. NASM knows that intel is little endian. Bit fields are typically big endian (I mixed big and little up, didn't I?)
  3. I recommend storing it as a single 64-bit hexadecimal number, that way NASM doesn't mess it up.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Jumping into real from protected mode

Post by DavidCooper »

What are you actually trying to do? Are you trying to use real mode in protected mode; are you trying to use 16-bit protected mode (in addition to 32-bit protected mode); are you trying to set up unreal mode; or what?

In your older GDT thread you set up two descriptors for using 32-bit protected mode and you eventually got that to work. It should be a simple step from there to work out how to set up two descriptors for 16-bit protected mode and to jump into it in the normal way.

(You may be able to manage with just one descriptor depending on what you're trying to do - e.g. you might only be going through 16-bit protected mode as a momentary step on the way back into real mode, but you'd avoid loading data segment registers altogether.)
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Post Reply