Virtual 8086 Mode
虚拟8086模式是保护模式的子模式。 简而言之,虚拟8086模式是在保护模式下运行的CPU“模拟(Emulated)”得到的16位实模式机器。
进入V86
当在EFLAGS寄存器中设置VM位(位17)为1时,CPU在虚拟86模式下执行。 如果要进入虚拟86模式,则必须将此位设置为1。 修改EFLAG寄存器的一种方法是使用pushf和popf指令。 这些指令分别推送和弹出堆栈上的eflags寄存器。 所以你可以向栈推入寄存器,在堆栈上修改它,然后弹出它。 但是popf指令不会修改eblags寄存器中的位16和17。 设置VM标志的唯一方法是使用iret指令。 此指令通常用于从中断返回。 执行iret时,CPU会从堆栈中弹出eip,cs,eflags,esp,ss,并在新的eip上继续执行。
; 您应该将此函数声明为: ; extern void enter_v86(uint32_t ss, uint32_t esp, uint32_t cs, uint32_t eip); enter_v86: mov ebp, esp ; 保存堆栈指针 push dword [ebp+4] ; ss push dword [ebp+8] ; esp pushfd ; eflags or dword [esp], (1 << 17) ; 设置VM标志 push dword [ebp+12] ; cs push dword [ebp+16] ; eip iret
V86问题
v86模式最常见的问题是无法从v86任务内部进入保护模式。 换句话说,如果您正在运行Windows或内存中有emm386,则不能将“原始(raw)”切换到保护模式(这会导致异常)。 DOS extenders使用VCPI或DPMI接口切换到pmode来解决这个问题 (实际上,将其V86任务提升为 “常规” 用户任务)。 对于操作系统程序员来说,这样的接口毫无用处,因为它们是DOS操作系统的一部分。
人们在使用v86模式时还有一些其他的“技术”问题,主要是因为v86有一些指令是由v86监控程序(v86-monitor program)“模拟”产生的,因为CPU处于保护模式,有些指令在安全/保护级别上很高,直接运行这些指令会给操作系统带来无穷无尽的麻烦。
检测V8086
EFLAGS.在V86任务中使用PUSHFD,VM永远不会被推到栈上。 您需要首先检查CR0。PE=1,如果该位被设置1,才假定它是V86。(译者注:CR0的PE位是保护模式启用位)
detect_v86: smsw ax and eax,1 ;CR0.PE bit ret
VM模式检测主要用于编写DOS extenders或其他程序,这些程序可以从受保护模式系统以纯实模式或虚拟模式启动。 “普通的”bootloader不应该担心这一点,因为BIOS不会设置VM86来读取引导扇区。 ;)
用法
如果需要在保护模式下访问BIOS功能,VM86非常有用。 实际上,例如设置视频模式(video mode)时是必要的,因为许多现代的视频卡卡/芯片组缺乏对VBE3保护模式接口的支持, 因此,设置一个VM86任务来执行“设置视频模式”调用是首选方法。
1MB以下的内核
建议将内核映射到“高”逻辑地址(例如0xC0000000),以避免VM86任务干扰它。 对于1MB以下没有空间容纳VM86代码的大型内核,或者当更大的程序预计将在VM86机器中运行时,这一点尤其重要。
如果进入VM86模式,所需要的只是BIOS中断包装器,则应执行以下操作:
- 确保16位代码与任何32位代码位于单独的页面上
- 启用分页
- 使DPL3的内核页面不可写 (也不可读?),并仅允许用户访问包含16位代码的页面和包含BIOS代码或数据的页面。
使用VM86访问磁盘
虽然理论上是可能的,但这可能不是一个好主意。大多数BIOS磁盘访问将包括IRQ处理程序、DMA传输(无法从VM monitor中进行控制)、 并且可能会在BIOS等待中断响应时停留在VM86任务中,而 “好的” 驱动程序应使CPU可以用于其他进程。
Windows 9x在访问磁盘时遭遇系统冻结。 通常是由于INT13-through-VM86问题导致的。
另见
文章
论坛主题
外部链接
- 模板:IntelManualLink
- http://osdev.berlios.de/v86.html - by Tim Robinson (Wayback Machine Link)
- A virtual-8086 mode monitor - by Chris Giese
- x86emu - a BSD style licensed vitual-8086 mode emulator - very different from a monitor.
- [1] - x86emu and several other projects. See mdt for code getting VBE modes.
- Protected Mode BIOS Call Functionailty v2.0 - by Napalm