Page 1 of 1

Enter 8086 virtual monitor

Posted: Thu Feb 26, 2009 7:34 am
by fabitone
Hello, I am new in this forum. I am making 8086 virtual monitor, but i need generate the PF to enter it. Currently, my code changes to a task v86 through IRET with the values pushed in the stack. Once inside, I need to cause a PF to access to the monitor but not like doing it. I followed a Tim Robinson's manual of VM86. Sorry my bad english!

Re: Enter 8086 virtual monitor

Posted: Thu Feb 26, 2009 7:44 am
by AJ
Hi and Welcome,

Generally, the VMM should only be triggered by events that actually require kernel intervention. This means that AFAIK, the only events that should cause the kernel to be notified, already cause the kernel to be notified.

This means that if your v86 task accesses unpaged memory, a PFE happens and the kernel deals with it. That's the correct way to go about that. If the v86 tries port accesses without permission, a GPF happens and the kernel deals with it.

Presumably, you also have some sort of tick counter enabled, which is interrupting the v86 task periodically. That can be an opportunity for the kernel to get other stuff done too.

What is it you're trying to signal the kernel about. Perhaps we can suggest another way of doing the same thing.

Cheers,
Adam

Re: Enter 8086 virtual monitor

Posted: Thu Feb 26, 2009 9:16 am
by fabitone
Hi Adam,
The idea is to make a function that simulates int instruction.
To do this I created a Task selector and load it, I have prepared a structure for tss v86 and pushed it to stack and call a IRET. In theory, should generate a exception and redirect to GPF handler. But instead of doing this, enter virtual 8086 mode and go to cs:ip adress.

This is the TSS struct:

Code: Select all

typedef struct
{
	unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax; /* PUSHA/POP */
	unsigned ds, es, fs, gs;
	unsigned which_int, err_code;
	unsigned eip, cs, eflags, user_esp, user_ss; /* INT nn/IRET */
	unsigned v_es, v_ds, v_fs, v_gs; /* V86 mode only */
} uregs_t;

values:

int_num = 10

ivt_off = (int_num & 0xFF) * 4;

regs->cs = peekw(0, ivt_off + 2);
regs->eip = peekw(0, ivt_off + 0);
regs->eflags = 0x00020002L; /* VM=1, IOPL=0 */ or regs->eflags = 0x00023002L
regs->eax = 0x4F02;
regs->edi = 0;
regs->v_es = stackv86
This is the func:

;C prototype: void start_v86(uregs_t *regs);

Code: Select all

start_v86:
	pusha
	sub esp,92
	mov esi,[esp + 128] ; (uregs_t *regs)
	mov edi,esp
	mov ecx,92 ; sizeof(uregs_t)
	cld
	rep movsb      // copy uregs in top of the stack

to_user:
	lea eax,[esp + 76]

	test dword [esp + 64],20000h ; test VM bit in stacked EFLAGS
	je set_tss_esp0
	lea eax,[esp + 92]

set_tss_esp0:
	mov [_tss_esp0],eax
	popa			; pop EAX...EDI (7 regs; 8 dwords)
	pop es			; pop segment registers
	pop ds
	pop fs
	pop gs
	add esp,byte 8		; drop int_num and err_code
	iret			; pop EIP...GS (9 regs)

thanks!

Re: Enter 8086 virtual monitor

Posted: Thu Feb 26, 2009 9:26 am
by fabitone
I have consulted many pages, but in all they teach you how to execute code snippets 16bit virtual mode. Do not they teach you how to execute the opcode of the stack directly

Fabián