switching back to real mode from GRUB

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.
Curufir

Re:switching back to real mode from GRUB

Post by Curufir »

EclipseOS wrote: [ORG 0x10000]
[BITS 32]

...
mov eax, cr0
xor eax, 1
mov cr0, eax
...
jmp word 0x00:real_mode
...
[BITS 16]

real_mode:
This isn't going to work. There might be errors elsewhere, but this isn't going to work.

The assembler can't take your 32-bit org statement and intelligently create a 16 bit label for a long jump using it. Second problem is that you've turned the PE bit back on. Third problem is that you've shown us nothing to say that 0x0 is actually a 16-bit code descriptor (Which you'll need for the switch back).
EclipseOS

Re:switching back to real mode from GRUB

Post by EclipseOS »

Okay, well thats why I need help. Everybody keeps telling me what to do, but not how to do it. I have been searching the internet on google and other search engines for a code that will do this for me. I boot my kernel with GRUB which sets up protected mode for me and I don't have a chance to save real mode values to get back into real mode for a graphics switch or a ATX poweroff. So could someone please give me code that actually works? thanx.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:switching back to real mode from GRUB

Post by Pype.Clicker »

The Mobius can do this. you can find it at mobius.sf.net, iirc ... Explaining why rather than showing how is one of the principles of this forum. I cannot show you how with 100% accuracy as i don't have code that make it, still i can provide you advices that have been helpful for other people ...

Code: Select all

mov eax,cr0
xor eax,1
mov cr0,eax
This one is redundant. I suggest you take time to figure out how AND, OR, XOR etc. really work before going any further (except if you're already slamming your forhead repeating "how could i have left such an horror").

-- @ schol-r-lea: don't you had a tutorial on these in the General Programming Forum ?

As the "AND eax, 7FFFFFFE" == "AND eax, ~80000001" already switched off the PG and the PE bit, "XOR eax, 00000001" toggles it back to on and so the jmp you take after cannot work ...
EclipseOS

Re:switching back to real mode from GRUB

Post by EclipseOS »

Okay, I did some more research and got this code. Sorry for my rudeness before, I was just frustrated at my code.

Here it is:

[BITS 32]

start:

   cli

   mov   eax,cr0
   and   eax,0x7FFFFFFF
   mov   cr0,eax
   xor   eax,eax
   mov   cr3,eax

   jmp   0x0008:prot16

[BITS 16]

prot16:

   mov   ax,0x0010
   mov   ds,ax
   mov   es,ax
   mov   fs,ax
   mov   gs,ax
   mov   ss,ax

   mov   ax,0x03FF
   mov   [newidt],ax
   xor   ax,ax
   mov   [newidt+2],ax
   mov   [newidt+4],ax
   lidt   [newidt]

   mov   eax,cr0
   and   eax,0xFFFFFFFE
   mov   cr0,eax

   jmp   dword 0x0000:real16

real16:

   xor   ax,ax
   mov   ds,ax
   mov   es,ax
   mov   fs,ax
   mov   gs,ax
   mov   ss,ax

   sti

   mov   ax,5304h
   sub   bx,bx
   int   15h

   mov   ax,5301h
   sub   bx,bx
   int   15h

   mov   ax,5308h
   mov   bx,1
   mov   cx,bx
   int   15h

   mov   ax,530Dh
   mov   bx,1
   mov   cx,bx
   int   15h

   mov   ax,530Fh
   mov   bx,1
   mov   cx,bx
   int   15h

   mov   ax,530Eh
   sub   bx,bx
   mov   cx,102h
   int   15h

   mov   ax,5307h
   mov   bx,1
   mov   cx,3
   int   15h

My only problem is the place I got the code from didn't specify what newidt is. What is newidt? thanx.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:switching back to real mode from GRUB

Post by Pype.Clicker »

EclipseOS wrote: My only problem is the place I got the code from didn't specify what newidt is. What is newidt? thanx.
that shouldn't really matter as long as its some memory you can access through the descriptor 0x10 as read/write data.

Note that obviously, this code assume that 0x08 and 0x10 will be 16 bits code and data segments while most of us use them as the *32bits* segments. make sure it is consistent with your environment.
EclipseOS

Re:switching back to real mode from GRUB

Post by EclipseOS »

Question 1. Would 0x1000 work for newidt?

Qyestion 2. What would be a 16-bit descriptor if mine are not?

thanx
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:switching back to real mode from GRUB

Post by Pype.Clicker »

i didn't said yours were not. So far you're the only one to know as only you know what's in your GDT.

0x1000 could be a nice newidt, if you have nothing else there.
EclipseOS

Re:switching back to real mode from GRUB

Post by EclipseOS »

Well I compiled and ran my code and my OS picked it up as an "Invalid Opcode". I don't understand why this code isn't working, I got it from a guy who said he used it before. I didn't setup my GDT or IDT, I am using GRUB which sets all that up and I have no way of changing it. Thanx
Curufir

Re:switching back to real mode from GRUB

Post by Curufir »

So just setup your own GDT with some 16-bit code/data selectors. The multiboot specification (AFAIK) actually says that you should setup your own GDT as soon as possible and not rely on the one from GRUB.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:switching back to real mode from GRUB

Post by Pype.Clicker »

when executing [bits 16] with a 32 bits code selector, some operations will be mis-interpreted as arguments for the previous instruction

Code: Select all

mov ax,1234
push si
mov ax,0x9090
will be read as

Code: Select all

mov eax,a1561234
nop
nop
no need to say "invalid opcodes" are *very* likely to occur in such conditions :P
EclipseOS

Re:switching back to real mode from GRUB

Post by EclipseOS »

Should this code work correctly?

Codestart
----------------------------------------------------------
[BITS 32]

; See IA-32 Dev vol 3 sec 8.9.2 & 1 for explanation of steps mentioned below

cli ; 8.9.2. Step 1.

mov eax,cr0 ; 8.9.2. Step 2.
and eax,0x7FFFFFFF
mov cr0,eax
xor eax,eax
mov cr3,eax

jmp 0x007:prot16 ; 8.9.2. Step 3.

[BITS 16]

prot16:

mov ax,0x0010 ; 8.9.2. Step 4.
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax

mov ax,0x03FF ; 8.9.2. Step 5.
mov [newidt],ax
xor ax,ax
mov [newidt+2],ax
mov [newidt+4],ax
lidt [newidt]

mov eax,cr0 ; 8.9.2. Step 6.
and eax,0xFFFFFFFE
mov cr0,eax

jmp dword 0x0000:real16 ; 8.9.2. Step 7.

real16:

xor ax,ax ; 8.9.2. Step 8.
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax

sti ; 8.9.2. Step 9.

newidt equ 0x632
---------------------------------------------------------
Code end.

Please could someone try it and see if they can get it to work for them because it sure doesn't seem to be working for me.
Thanx.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:switching back to real mode from GRUB

Post by Brendan »

Hi,
EclipseOS wrote: Should this code work correctly?

Please could someone try it and see if they can get it to work for them because it sure doesn't seem to be working for me.
I didn't try it, but you'd need to set up a real mode stack before enabling interrupts. Also you'd have to make sure that the state of every device in the computer is the same as what the BIOS is expecting.


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.
Post Reply