how can switch back to real 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.
Post Reply
behzad24b
Posts: 5
Joined: Sun Aug 24, 2008 3:33 am

how can switch back to real mode ?

Post 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 ?
User avatar
cr2
Member
Member
Posts: 162
Joined: Fri Jun 27, 2008 8:05 pm
Location: ND, USA

Re: how can switch back to real mode ?

Post 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:
Last edited by cr2 on Fri Aug 29, 2008 6:52 am, edited 1 time in total.
OS-LUX V0.0
Working on...
Memory management: the Pool
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: how can switch back to real mode ?

Post 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).
behzad24b
Posts: 5
Joined: Sun Aug 24, 2008 3:33 am

Re: how can switch back to real mode ?

Post 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<
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

Re: how can switch back to real mode ?

Post by xyjamepa »

Hi,

Okay... take a look at this
The man who follows the crowd will usually get no further than the crowd.
The man who walks alone is likely to find himself in places
no one has ever been before.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: how can switch back to real mode ?

Post 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
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Re: how can switch back to real mode ?

Post 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:
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: how can switch back to real mode ?

Post 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
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Re: how can switch back to real mode ?

Post 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
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Re: how can switch back to real mode ?

Post 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.
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: how can switch back to real mode ?

Post 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
If you have seen bad English in my words, tell me what's wrong, please.
sebihepp
Member
Member
Posts: 195
Joined: Tue Aug 26, 2008 11:24 am
GitHub: https://github.com/sebihepp

Re: how can switch back to real mode ?

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