Interrupt BIOS in VM86, restarts the CPU x86

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
User avatar
Neo92
Member
Member
Posts: 28
Joined: Tue Jun 24, 2014 9:41 am

Interrupt BIOS in VM86, restarts the CPU x86

Post by Neo92 »

Hi all, i'm new of the forum, i have the problem. Why when i use the interrupts BIOS in VM86, the CPU restarts? An example is the video interrupt 0x10. For me is needful start and set the video mode, i use FASM. I exactly that the VM86 is work perfectly in Bochs, VirtualBox and VMachine but in CPU don't work, i append the code complete. Only the interrupts have problems. Thanks for your help. :) 8)

Code: Select all

org 7c00h

use16

cli
lgdt[gdt]
mov eax,cr4
or al,1
mov cr4,eax
mov eax,cr0
or al,1
mov cr0,eax
jmp gdt_code-gdt_table:pmode

vm86:
mov ax,3
int 10h                                 ;the problem is here! :/
mov bx,0b800h
mov es,bx
mov bx,0
mov byte[es:bx+2],42h
mov byte[es:bx+3],7
jmp $

use32

pmode:
mov ax,gdt_data-gdt_table
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov esp,9fffch
mov al,0f0h
out 60h,al
mov al,0
out 60h,al
scan1:
in al,60h
cmp al,1eh
jne scan1
mov byte[0b8000h],41h
mov byte[0b8000h+1],7
push 0
push 0
push 0
push 0
push 0
push 0fffeh
push 20000h
push 0
push vm86
iret

gdt:
dw gdt_table-1
dd gdt_table

gdt_table:
dd 0
dd 0

gdt_code:
dw 0ffffh
dw 0
db 0
db 9ah
db 0cfh
db 0

gdt_data:
dw 0ffffh
dw 0
db 0
db 92h
db 0cfh
db 0

times 510-($-$$) db 0
dw 0aa55h
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Interrupt BIOS in VM86, restarts the CPU x86

Post by alexfru »

You don't get what you want for free from virtual 8086 mode.

The int instruction will cause #GP in VM86 unless you properly set up/enable Pentium's VM86 extensions that help with interrupt forwarding to realmode interrupt handlers.

If you don't use those extensions, your #GP handler will have to do this work (parse the offending instruction, modify the state accordingly so that when the handler returns, execution continues in int 10h ISR, etc).

You need to learn more about protected mode and virtual 8086 mode as there must be a contributing bug somewhere, either related to VM86 or to protected mode, ultimately causing a sequence of these: #GP, #DF, triple fault and a CPU reset. Since you don't have an exception handler, you don't get any clues from the CPU itself.

One thing in particular that I don't like is your "lgdt[gdt]". What's in DS when this instruction executes?
User avatar
Neo92
Member
Member
Posts: 28
Joined: Tue Jun 24, 2014 9:41 am

Re: Interrupt BIOS in VM86, restarts the CPU x86

Post by Neo92 »

Thanks for reply Alex,

I usually load the registers in this order GS,FS,DS,ES,SS with value zero (segments of the real mode) or ignore. I tested the code implementing the operand 'HLT' producing a triple fault, here the code and Bochs log.

Neo92 :)

Code: Select all

org 7c00h

use16

jmp 0:rmode

rmode:
mov ax,0
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0fffeh
cli
lgdt[gdt]
mov eax,cr4
or al,1
mov cr4,eax
mov eax,cr0
or eax,1
mov cr0,eax
jmp gdt_code-gdt_table:pmode

vm86:
mov ax,0
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0fffeh
mov ax,3
int 10h
mov bx,0b800h
mov es,bx
mov bx,0
mov byte[es:bx+2],42h
mov byte[es:bx+3],7
hlt
jmp $

use32

pmode:
mov ax,gdt_data-gdt_table
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov esp,9fffch
mov al,0f0h
out 60h,al
mov al,0
out 60h,al
scan1:
in al,60h
cmp al,1eh
jne scan1
mov byte[0b8000h],41h
mov byte[0b8000h+1],7
push 0
push 0
push 0
push 0
push 0
push 0fffeh
push 20000h
push 0
push vm86
iret

gdt:
dw gdt_table-1
dd gdt_table

gdt_table:
dd 0
dd 0

gdt_code:
dw 0ffffh
dw 0
db 0
db 9ah
db 0cfh
db 0

gdt_data:
dw 0ffffh
dw 0
db 0
db 92h
db 0cfh
db 0

times 510-($-$$) db 0
dw 0aa55h

Code: Select all

00014918918i[BIOS  ] Booting from 0000:7c00
00049566128e[CPU0  ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d)
00049566128e[CPU0  ] interrupt(): gate descriptor is not valid sys seg (vector=0x08)
00049566128i[CPU0  ] CPU is in v8086 mode (active)
00049566128i[CPU0  ] CS.mode = 16 bit
00049566128i[CPU0  ] SS.mode = 16 bit
00049566128i[CPU0  ] EFER   = 0x00000000
00049566128i[CPU0  ] | EAX=60000030  EBX=00000000  ECX=00090000  EDX=00000000
00049566128i[CPU0  ] | ESP=0000fffe  EBP=00000000  ESI=000e0000  EDI=0000ffac
00049566128i[CPU0  ] | IOPL=0 id vip vif ac VM RF nt of df if tf sf zf af pf cf
00049566128i[CPU0  ] | SEG sltr(index|ti|rpl)     base    limit G D
00049566128i[CPU0  ] |  CS:0000( 0001| 0|  3) 00000000 0000ffff 0 0
00049566128i[CPU0  ] |  DS:0000( 0002| 0|  3) 00000000 0000ffff 0 0
00049566128i[CPU0  ] |  SS:0000( 0002| 0|  3) 00000000 0000ffff 0 0
00049566128i[CPU0  ] |  ES:b800( 0002| 0|  3) 000b8000 0000ffff 0 0
00049566128i[CPU0  ] |  FS:0000( 0002| 0|  3) 00000000 0000ffff 0 0
00049566128i[CPU0  ] |  GS:0000( 0002| 0|  3) 00000000 0000ffff 0 0
00049566128i[CPU0  ] | EIP=00007c59 (00007c59)
00049566128i[CPU0  ] | CR0=0x60000011 CR2=0x00000000
00049566128i[CPU0  ] | CR3=0x00000000 CR4=0x00000001
00049566128i[CPU0  ] 0x0000000000007c59>> hlt  : F4
00049566128e[CPU0  ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
00049566128i[SYS   ] bx_pc_system_c::Reset(HARDWARE) called
00049566128i[CPU0  ] cpu hardware reset
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:

Re: Interrupt BIOS in VM86, restarts the CPU x86

Post by Combuster »

HLT is a privileged instruction, it will GPF (and as a consequence, crash because you lack an IDT).


Bottom line: You can't do v8086 mode without a virtual mode monitor.
"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 ]
User avatar
Neo92
Member
Member
Posts: 28
Joined: Tue Jun 24, 2014 9:41 am

Re: Interrupt BIOS in VM86, restarts the CPU x86

Post by Neo92 »

Hi Combuster, thanks for the advice. So, for create the virtual monitor, i should initialize a TSS right? Because i read the page on OSDev Wiki... but now i'm confused on how to start the virtual monitor. :? :?: Then, if i try to load the task register produces 'LTR doesn't point to an available TSS descriptor!' or 'fetch_raw_descriptor: GDT: index (27) 4 > limit (17)', i don't understand :(

http://wiki.osdev.org/Virtual_Monitor

Code: Select all

org 7c00h

use16

jmp 0:rmode

rmode:
mov ax,0
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0fffeh
cli
lgdt[gdt]
mov eax,cr4
or al,1
mov cr4,eax
mov eax,cr0
or eax,1
mov cr0,eax
jmp gdt_code-gdt_table:pmode

vm86:
mov ax,3
int 10h
mov bx,0b800h
mov es,bx
mov bx,0
mov byte[es:bx+2],42h
mov byte[es:bx+3],7
jmp $

use32

pmode:
mov ax,gdt_data-gdt_table
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov esp,9fffch
mov ax,20h                       ;don't load the TSS descriptor :?
ltr ax
mov al,0f0h
out 60h,al
mov al,0
out 60h,al
scan1:
in al,60h
cmp al,1eh
jne scan1
mov byte[0b8000h],41h
mov byte[0b8000h+1],7
push 0
push 0
push 0
push 0
push 0
push 0fffeh
push 20000h
push 0
push vm86
iret

gdt:
dw tss_sel-gdt_table-1
dd gdt_table

gdt_table:
dd 0
dd 0

gdt_code:
dw 0ffffh
dw 0
db 0
db 9ah
db 0cfh
db 0

gdt_data:
dw 0ffffh
dw 0
db 0
db 92h
db 0cfh
db 0

tss_sel:
dw 89h
dw 0f00h

times 510-($-$$) db 0
dw 0aa55h
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:

Re: Interrupt BIOS in VM86, restarts the CPU x86

Post by Combuster »

GDT: index (27) 4 > limit (17)'
Since the answer is actually right under your nose, do you know what the limit of the GDT is? Do you know what indexes into the gdt are? How large are each of your GDT entries? How are they numbered and used?
"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 ]
User avatar
Neo92
Member
Member
Posts: 28
Joined: Tue Jun 24, 2014 9:41 am

Re: Interrupt BIOS in VM86, restarts the CPU x86

Post by Neo92 »

Greaaaaaaaaaaaaaat! I'm successful :D The code work perfectly, the CPU doesn't restarts but stops to the final instruction of jump or 'jmp $'. :lol: :lol: :) Excuse me with Combuster for the mistake of before on the TSS :mrgreen: I don't was shrew that has been bad initialize. Thanks all, but specially to you Combuster :wink:

Neo92 :)

Code: Select all

org 7c00h

use16

jmp 0:rmode

rmode:
mov ax,0
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0fffeh
cli
lgdt[gdt]
mov eax,cr4
or al,1
mov cr4,eax
mov eax,cr0
or eax,1
mov cr0,eax
jmp gdt_code-gdt_table:pmode

vm86:
mov ax,3
int 10h
mov bx,0b800h
mov es,bx
mov bx,0
mov byte[es:bx+2],42h
mov byte[es:bx+3],7
jmp $

use32

pmode:
mov ax,gdt_data-gdt_table
mov gs,ax
mov fs,ax
mov ds,ax
mov es,ax
mov ss,ax
mov esp,9fffch
mov al,0f0h
out 60h,al
mov al,0
out 60h,al
scan1:
in al,60h
cmp al,1eh
jne scan1
mov byte[0b8000h],41h
mov byte[0b8000h+1],7
mov ax,18h
ltr ax
push 0
push 0
push 0
push 0
push 0
push 0fffeh
push 20000h
push 0
push vm86
iret

gdt:
dw gdt_end-gdt_table-1
dd gdt_table

gdt_table:
dd 0
dd 0

gdt_code:
dw 0ffffh
dw 0
db 0
db 9ah
db 0cfh
db 0

gdt_data:
dw 0ffffh
dw 0
db 0
db 92h
db 0cfh
db 0

tss_sel:
dw 0ffffh
dw 0
db 0
db 89h
db 8fh
db 0

gdt_end:

times 510-($-$$) db 0
dw 0aa55h
User avatar
Neo92
Member
Member
Posts: 28
Joined: Tue Jun 24, 2014 9:41 am

Re: Interrupt BIOS in VM86, restarts the CPU x86

Post by Neo92 »

Now my difficult is the interrupt 0x16 and 0x13, although i can remap the interrupt 0x16 through ports with 0x13 i see it hard. I'm trying to understand how to do. :-k
Post Reply