Page 1 of 1

unreal mode problem again

Posted: Tue Mar 25, 2008 2:48 pm
by packet50071

Code: Select all

[BITS 32]
global _etry, _multi_b, _halt, _kernel_stack,_do_16v,_RealModeCS,_do_rm , _ke , _unrealmode 

extern _linkd,_linkb, _linkt,_kernel

MULTIBOOT_PAGE_ALIGN     equ 1<<0
MULTIBOOT_AOUT_KLUDGE    equ 1<<16
MULTIBOOT_HEADER_MAGIC   equ 0x1BADB002
MULTIBOOT_HEADER_FLAGS   equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_AOUT_KLUDGE
MULTIBOOT_CHECKSUM       equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

STACKSZ equ 0x4000 

[SECTION .text]
   _RealModeCS:
	    dw 0
	_etry:
        jmp short _startup
        align 4
    _multi_b:
        dd MULTIBOOT_HEADER_MAGIC
        dd MULTIBOOT_HEADER_FLAGS
        dd MULTIBOOT_CHECKSUM
        dd _multi_b
        dd _etry
        dd _linkd
        dd _linkb
        dd _linkt
     _startup:
    
     mov esp, _kernel_stack+STACKSZ      
     push eax                         
     push ebx 
     ;call _kernel 
    
    _unrealmode:
	mov eax, cr0
	and al, 0xFE
	mov cr0, eax
	jmp _ke
	
	_ke :
	mov ax, 1234h 
    int 3 
    _halt:
      hlt   
    
[SECTION .bss]
     resb STACKSZ
    _kernel_stack:
When i run this code VM completly crashes I have to restart my pc to make my Vm work again

Any thing i got Wrong ??

thx for future help

Posted: Tue Mar 25, 2008 4:17 pm
by Combuster
you can't disable protected mode while in a 32-bit mode.

Posted: Tue Mar 25, 2008 5:59 pm
by packet50071
i am officially lost now !

can you / someone explain further pls ?

I got the code form this topic http://www.osdev.org/phpBB2/viewtopic.p ... f7dfa47b66

Posted: Tue Mar 25, 2008 7:23 pm
by Brendan
Hi,
packet50071 wrote:i am officially lost now !

can you / someone explain further pls ?
The CPU caches segment register details like the segment type, base address , limit, etc. Your code starts running in 32-bit protected mode (probably above 1 MB in memory), then you disable protected mode which leaves you in real mode with messed up values for the cached segment register details while still trying to execute code above 1 MB in memory.

To do it properly you need to:
  • - copy some code below 1 MB so it can actually be used during and after the switch to un/real mode.
    - transfer control to the code below 1 MB
    - load 16-bit protected mode segments for (at least) CS and SS
    - disable protected mode
    - load real mode segments for all segment registers.
You're only doing one of these things...


Cheers,

Brendan

Posted: Tue Mar 25, 2008 10:51 pm
by elderK
Out of curiousity, Is it possible to continue using all of the BIOS' functions when in Unreal mode?

I worry that BIOS code could... mess up the 'kludged segment data' in the caches.

Is this worrying in vain?

~z

Posted: Wed Mar 26, 2008 8:30 am
by JAAman
simple answer? no its not


some (though not all, and its subject to dependance on which version of which BIOS...) BIOS calls are handled in PMode -- when it returns from PMode, it will properly reset the segment registers
also, even code which doesnt use PMode, may change the segment registers, which will reset the hidden portion, and return you to 'proper' RMode

this is just theory for me though, so perhaps someone else can tell you how common these scenarios are

Posted: Wed Mar 26, 2008 9:04 am
by elderK
Well, In my experimentation, I've found this to be precisely the case.

That being the cached segment descriptor being reset to something valid, due to the BIOS changing selectors inside one of its routines.

~Z

Posted: Wed Mar 26, 2008 2:54 pm
by packet50071
thx for the reply s -- I will try that after I finish reading the Intel manual :wink:

Posted: Wed Mar 26, 2008 8:08 pm
by Brendan
Hi,
zeii wrote:I worry that BIOS code could... mess up the 'kludged segment data' in the caches.
In my experience almost all BIOS functions leave your unreal mode segments setup. This is mostly because most BIOS functions should also work in virtual8086 mode. Code running in virtual8086 mode can't enable protected mode, and therefore code that works in virtual8086 mode won't switch to protected mode and won't mess up your unreal mode segments when it's not running in virtual8086 mode.

There are a few BIOS functions that need to use protected mode, that will mess up your unreal mode segments - one that does 32-bit data copying and a "switch to protected mode" BIOS function. If you use these functions it's fairly obvious that they'll mess up your unreal mode segments (and if you're using unreal mode you probably have no reason to use these BIOS functions anyway) so they aren't worth worrying much about.

I've also had problems with ROM code for network booting (specifically etherboot). The problem here is that the PXE specification has a 32-bit protected mode interface and a real mode interface, so AFAIK etherboot only implements 32-bit protected mode functions and then (for the real mode interface) switches to protected mode, calls the 32-bit function, then returns to real mode. Also note that this does cause problems with some OSs (one of the *BSDs IIRC).

A wise person would create a "setUnrealMode()" function and call it after using any suspicious BIOS functions. A paranoid person would call their "setUnrealMode()" function after using any BIOS function.This only leaves one potential problem - IRQ handlers that switch to protected mode and back. However, I've been using unreal mode for over 10 years and have never had any problems on any computer, and I have a habit of testing my code on every computer I can get my fingers on....

Note: It's extremely likely that the BIOS will mess with segment bases, but that doesn't matter as it doesn't effect the modified segment limits.


Cheers,

Brendan

Posted: Thu Mar 27, 2008 3:39 am
by Ready4Dis
Brendan wrote:Hi,
zeii wrote:I worry that BIOS code could... mess up the 'kludged segment data' in the caches.
In my experience almost all BIOS functions leave your unreal mode segments setup. This is mostly because most BIOS functions should also work in virtual8086 mode. Code running in virtual8086 mode can't enable protected mode, and therefore code that works in virtual8086 mode won't switch to protected mode and won't mess up your unreal mode segments when it's not running in virtual8086 mode.
I concur that most won't, but it still happens. What I do is reserve memory below 1mb, drop to real-mode (real-real mode), call bios function, go to unreal mode, and copy that memory > 1mb, and loop until all data is loaded, I do not rely on the bios to support unreal mode, mostly because I don't trust anything that I didn't write or have access to sources, so when problems arise, i'm not tracking down a bios interrupt that changed the value in ES, the restored it on exit (meaning the value in ES never 'changed', but now isntead of holding 0x10 meaning desciptor 2, it's holding 0x10 meaning offest 0x100 :P. So, for me, it's easier to not rely on the bios for anything, especially since there is no standard saying it can't modify things if it puts them back.

* Edited away part of the quote as per request below, will try to remember from now on.

Posted: Thu Mar 27, 2008 4:42 am
by AJ
[moan]OT: Can I just be a miserable git and point out that there is no need to quote the preceding post in its entirity - by all means quote snippets of posts that your reply relates to. This is not a personal attack - I have noticed it a few times lately from different people and I don't think I'll be the only one it annoys.[/moan]

Cheers,
Adam