Virtual 8086 mode is a sub-mode of ProtectedMode. In short, virtual 8086 mode is whereby the cpu (in protected mode) is running a "Emulated" 16bit 'segmented' model (real mode) machine.
I don't enable V86 myself. Why should i care ?
The most common problem with v86 mode is that you can't enter ProtectedMode inside a v86 task. In other words, if you are running Windows or have emm386 in memory, you can't do a "raw" switch into protected mode (it causes an exception, iirc). DOS extenders worked around that problem using either VCPI or DPMI interfaces to switch into pmode (actually, promoting their V86 task as a 'regular' user task). For an OS programmer such interfaces are simply useless as they're part of another OS.
There are a few other more "technical" problems people have when using v86 mode, mostly because v86 has some instructions "emulated" by what's known as a v86-monitor program, as the cpu is in protected mode, some instructions are high up on the security/protection level and running those directly would cause no-end of trouble for the OS.
Such technicalities are beyond the scope of a simple FAQ. If you wish to learn more about virtual mode, i suggest you read the corresponding chapter of the
HollyIntelManual.
How do i detect v8086 ?
EFLAGS.VM is NEVER pushed onto the stack if the V86 task uses PUSHFD. You should check if CR0.PE=1 and then assume it's V86 if that bit is set.
detect_v86:
smsw ax
and eax,1 ;CR0.PE bit
ret
VM mode detection is mainly useful when writing DOS extenders or other programs that could be started either in plain real mode or in virtual mode from a protected mode system. An 'ordinary' bootloader shouldn't worry about this since the BIOS will not set up VM86 to read the bootsector ;)
I heard it could help me. How can i support it ?
Indeed, VM86 can be of high interrest if you need to access BIOS functions while you're in ProtectedMode. This is essentially useful in order to set up video mode. As many modern card/chipsets lack support for VBE3 protected mode interface, setting up a VM86 task that will perform the proper 'set video mode' call remains the method.
TimRobinson has provided a very nice
tutorial about VM86 mode. BeyondInfinity also has a working implementation (combined VM86+VBE task). See VirtualMonitor page for more implementation considerations.
Argh! My kernel is below 1MB! what can i do ?
TimRobinson and many others suggests that you put your kernel at a 'high' logical address (e.g. 0xC0000000) to avoid VM86 tasks to interfere with it. This is especially important when your kernel is large and leaves no room for VM86 code below 1MB, or when you plan to run 'full programs' within your VM86 box.
If all you need is a BIOS interrupt wrapper, then you can easily do the following:
- ensure that your 16bits code is on a separate page from any 32 bits code
- enable paging
- make kernel pages unwritable (and unreadable ?) for DPL3 and allow user-access only to those pages that contains your 16 bits code and pages that contains BIOS code or data.
Can i use VM86 for disk access ?
Theorically yes, though it is probably not a
GoodIdea(tm), as most BIOS disk access will include IRQ handlers, DMA transfers which you can hardly control from your VM monitor, and may stick in VM86 task while the BIOS waits for an interrupt response while a 'good' driver would have let the CPU free for other processes.
Remember of your old MS9x system freezing when doing a disk access ? that was most of the time due to an INT13-through-VM86 problem.
Categories: FAQ, HardWareCpu
Related forum threads
Creating vm86 task
VM86 and INT10h
kernel location & VM86
add yours here
Additionnal links
add yours here
