Page 1 of 1

how can switch back to real mode ?

Posted: Wed Aug 27, 2008 9:59 am
by behzad24b
hi.
please help to me , how can i switch back to real mode in C language and inline assembly ?
can you write an example here ?

Re: how can switch back to real mode ?

Posted: Wed Aug 27, 2008 10:55 am
by cr2
here goes...

MSVC++:

Code: Select all

// enters pmode (leaves real mode)
_asm
{
        mov eax, cr0
        or  al, 1
        mov cr0, eax
}
// leaves pmode (enters real mode)
_asm
{
        mov eax, cr0
        and al, 0FEh
        mov cr0, eax
}
GCC:

Code: Select all

// enters pmode (leaves real mode)
unsigned int cr0;
asm volatile ("mov %%cr0, %0" : "=r"(cr0));
cr0 = cr0 | 1;
asm volatile ("mov %0, %%cr0" : : "r"(cr0));

// leaves pmode (enters real mode)
unsigned int cr0;
asm volatile ("mov %%cr0, %0" : "=r"(cr0));
cr0 = cr0 & 0xFE;
asm volatile ("mov %0, %%cr0" : : "r"(cr0));
If you are trying to execute BIOS interrupts, try v86 or unreal mode. :wink:

Re: how can switch back to real mode ?

Posted: Wed Aug 27, 2008 1:12 pm
by bewing
There is a bit more to it than that, of course, but it takes some setup.

After flipping the bit in CR0, you need to reset the segment registers, and you need to set up a stack.
Setting the CS register involves doing a far jump, to some code that is already stored in low memory (below 1M).
You probably also have to switch back to the Real Mode IVT (at physical address 0).

Re: how can switch back to real mode ?

Posted: Wed Aug 27, 2008 11:37 pm
by behzad24b
thanks for your info.
what is the v86 mode and how can i use that in pmode and call interrupts ?
please give me more info about that [-o<

Re: how can switch back to real mode ?

Posted: Thu Aug 28, 2008 12:27 am
by xyjamepa
Hi,

Okay... take a look at this

Re: how can switch back to real mode ?

Posted: Thu Aug 28, 2008 1:55 am
by AJ
Note that v86 mode isn't a "fix all" solution. While it is useful for display functions (VESA), it may not be wise to use it for disk I/O. Also, if you ever try a 64 bit OS, v86 mode is not available. If you want something more general purpose, stick with switching to real mode.

In my (C++) second stage boot loader, I have a function called realMode (genius :roll: ) which is passed the address of a real mode function, parameter count and then a variable number of parameters. This (PMode) function automatically does the switch to real mode, converts to a 16 bit CS:IP, executes the function with given parameters and returns.

It's a bit of work setting up such a system but well worth it if you have a lot of real mode work to do.

Cheers,
Adam

Re: how can switch back to real mode ?

Posted: Thu Aug 28, 2008 2:33 am
by inflater
I can just recommend the switching instead of using v8086. Coding a macro or function that will temporarily jump to rmode and back will cost you about 10 minutes, with v8086 you need first to provide full multitasking and all that stuff :roll:

Re: how can switch back to real mode ?

Posted: Thu Aug 28, 2008 5:55 am
by sebihepp
I am having trouble with switching back to RealMode, too.
I do the following in my BootLoader:

Code: Select all

[BITS 32]
[ORG 0x0000]

;Some Stuff

SwitchToRealMode:
  mov eax, cr0
  and al, 0xFE
  mov cr0, eax
  jmp 0x07C0:RealMode

[BITS 16]
RealMode:
  call DisableA20Gate
  jmp $

; the rest of the bootloader
But in Bochs I always got a restart, because the segment registers are in 32Bit and cs=0xf0000000 and ip=0xFFFE0.
What did I wrong?

Sebihepp

Re: how can switch back to real mode ?

Posted: Thu Aug 28, 2008 11:20 am
by Dex
Here is a vesa demo i wrote that switch to and from pmode to realmode for vesa mode switching, it may help.
http://dex4u.com/demos/VesaDemo.zip

Re: how can switch back to real mode ?

Posted: Thu Aug 28, 2008 11:47 am
by inflater
@Sebihepp: Make sure your code is under 640K, or relocate it there.
BTW you don't need to disable the A20 gate when entering real mode.

Re: how can switch back to real mode ?

Posted: Fri Aug 29, 2008 1:22 am
by egos
sebihepp wrote:What did I wrong?
You must set hidden part of segment registers.

Code: Select all


org 0

...

; descriptor for 16-bit code segment selected by CODE16
desc 0x7C00, 0xFFFF, \ ; base & limit
DF_PRESENT \ ; default
or DF_CODE or DF_DUALACTION \ ; i.e. readable code
or DF_USE16 or DF_BYTED ; default when granularity byte is equal to 0

; descriptor for 16-bit data segment selected by DATA16
desc 0x7C00, 0xFFFF, \ ; base & limit
DF_PRESENT \ ; default
or DF_DATA or DF_DUALACTION \ ; i.e. writable data
or DF_USE16 or DF_BYTED ; default when granularity byte is equal to 0

...

use32
SwitchToRealMode:
jmp CODE16:@f

use16
@@:
mov ax,DATA16
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax

mov eax,cr0
and al,0xFE
mov cr0,eax
jmp 0x7C0:@f

@@:
mov ax,0x7C0
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax

Re: how can switch back to real mode ?

Posted: Fri Aug 29, 2008 9:41 am
by sebihepp
Ah, okay. I think the descriptor of my code and the data was not set to 16 bit.
It was an 0x7C00 and has the size 0xFFFF and the size is counted in bytes.

I will try to set the descriptors to 16bit.

Thanks Sebihepp