vm86, iret and TSS

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
xyz1
Posts: 14
Joined: Fri Jan 05, 2007 8:15 am

vm86, iret and TSS

Post by xyz1 »

I have the code, to enter in vm86:

vm86_bios:
;B+ Call bios interrupt in virtual 86 mode
push dword 0x1000 ;gs
push dword 0x1000 ;fs
push dword 0x1000 ;ds
push dword 0x1000 ;es
push dword 0x1000 ;ss
push dword 0xffff ;esp
;===EFLAGS=== pushfd with vm86 bit = 1
push dword 0x23202 ;0x20200 ;0x23202
push dword 0x1000 ;cs
push dword vm86-0x10000 ;eip
iret ;<--################################
.exit:
;pop stack ...
add esp,9*4
ret

use16
vm86:
;B+ Test
; end only...
; int 0x40
jmp $ ;<--$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;E:.
use32
;E:.

If I start this code, than I receive the error:
interrupt(): SS is not writable data segment
Wath is wrong???

Debugging this code with bochs, I found, that:

BEFORE:
esp:0x0007ff94 eip:0x000190a0
eflags:0x00000297 = IF+SF+AF+PF+CF
cs:s=0x0008, dl=0x0000ffff, dh=0x00df9a00, valid=1
ss:s=0x08b0, dl=0x000000ff, dh=0x01d09308, valid=7
ds:s=0x0010, dl=0x0000ffff, dh=0x00df9300, valid=3
es:s=0x0010, dl=0x0000ffff, dh=0x00df9300, valid=1
tr:s=0x0090, dl=0x07800080, dh=0x00108904, valid=1
gdtr:base=0x00019e61, limit=0xc47
idtr:base=0x0001aab1, limit=0x807

AFTER:
esp:0x0000fffd eip:0x000090a6
eflags:0x00023202 = 100011001000000010 = VM+IOPL=3+IF
cs:s=0x1000, dl=0x0000ffff, dh=0x0000fb01, valid=1
ss:s=0x1000, dl=0x0000ffff, dh=0x0000f301, valid=5
ds:s=0x1000, dl=0x0000ffff, dh=0x0000f301, valid=1
es:s=0x1000, dl=0x0000ffff, dh=0x0000f301, valid=1
tr:s=0x0090, dl=0x07800080, dh=0x00108904, valid=1
gdtr:base=0x00019e61, limit=0xc47
idtr:base=0x0001aab1, limit=0x807

This is only for additional information.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Does bochs panic during vm entry or during vm exit? (i.e. what is the failing instruction)?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

You aren't pushing the right value for SS onto the stack. Make sure that the right values are being used, and remember that you can't access memory above the 1MB mark.

Edit: I think that's what is happening...
xyz1
Posts: 14
Joined: Fri Jan 05, 2007 8:15 am

Post by xyz1 »

>Does bochs panic during vm entry or during vm exit?
Case is "during vm exit". I wrote essential row in bold:
interrupt(): SS is not writable data segment
The log file is (i.e. only the end):

Code: Select all

01857301543e[CPU0 ] interrupt(): SS is not writable data segment
01857301543e[CPU0 ] interrupt(): SS is not writable data segment
01857301543e[CPU0 ] interrupt(): SS is not writable data segment
01857301543i[CPU0 ] v8086 mode
01857301543i[CPU0 ] CS.d_b = 16 bit
01857301543i[CPU0 ] SS.d_b = 16 bit
01857301543i[CPU0 ] | EAX=00000002  EBX=0001000a  ECX=00eaea0e  EDX=00000028
01857301543i[CPU0 ] | ESP=0000ffff  EBP=00000002  ESI=00787cd8  EDI=0000003e
01857301543i[CPU0 ] | IOPL=3 id vip vif ac VM RF nt of df IF tf sf zf af pf cf
01857301543i[CPU0 ] | SEG selector     base    limit G D
01857301543i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
01857301543i[CPU0 ] |  CS:1000( 0001| 0|  3) 00010000 0000ffff 0 0
01857301543i[CPU0 ] |  DS:1000( 0002| 0|  3) 00010000 0000ffff 0 0
01857301543i[CPU0 ] |  SS:1100( 0116| 0|  3) 00011000 0000ffff 0 0
01857301543i[CPU0 ] |  ES:1000( 0002| 0|  3) 00010000 0000ffff 0 0
01857301543i[CPU0 ] |  FS:1000( 0002| 0|  3) 00010000 0000ffff 0 0
01857301543i[CPU0 ] |  GS:1000( 0002| 0|  3) 00010000 0000ffff 0 0
01857301543i[CPU0 ] | EIP=000090a5 (000090a5)
01857301543i[CPU0 ] | CR0=0x00000019 CR1=0 CR2=0x00000000
01857301543i[CPU0 ] | CR3=0x00070018 CR4=0x00000000
01857301543i[CPU0 ] >> jmp .+0xfffe (0x000190a5) : EBFE
01857301543e[CPU0 ] exception(): 3rd (10) exception with no resolution, shutdown status is 00h, resetting
>You aren't pushing the right value for SS onto the stack.
No, the value is correct! This is vm86 stack value. I even use "push ax" in vm86 mode, and it is working!
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Just shows what I know about V8086 mode :D :lol:
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

I think you forgot to correctly load the SS0/ESP0 fields in the TSS
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
xyz1
Posts: 14
Joined: Fri Jan 05, 2007 8:15 am

Post by xyz1 »

I think you forgot to correctly load the SS0/ESP0 fields in the TSS
Tank you! This solve the problem.

But I have one another question:
If I am in vm86, and some hrdware interrupt occure, then GPF will be send. Haw can I handle this events correctly (i.e. to find int number).
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Post by Pype.Clicker »

xyz1 wrote: If I am in vm86, and some hrdware interrupt occure, then GPF will be send. Haw can I handle this events correctly (i.e. to find int number).
Hmm, not to my knowledge. Hardware interrupts are still delivered through the IDT, not through the old interrupt vector table of real mode.

Unless you configured the processor to use VirtualModeExtensions (which i bet you didn't) and unless you have no descriptor installed for IRQs in your IDT, you shouldn't get GPFs but rather see the proper descriptor invoked on SS0:ESP0.
Post Reply