OSDev.org https://forum.osdev.org/ |
|
Enter to V86, perform BIOS Interrupt and return back to PM https://forum.osdev.org/viewtopic.php?f=1&t=33390 |
Page 1 of 2 |
Author: | MrLolthe1st [ Mon Dec 24, 2018 10:06 am ] |
Post subject: | Enter to V86, perform BIOS Interrupt and return back to PM |
So, i'm have a, may be, very dumb question: how to enter to V86, perform BIOS Interrupt and return back to PM? I'm wrote that code(In kernel) to enter to a v86: Code: mov $_lo1, %ebx #Save return address to ebx pushf orl $131072, (%esp)#Turn on VM flag movl $0x0, %eax pushl %eax #Segment 0 mov $0x8400, %eax #Offset 0x8400 pushl %eax mov 24(%esp), %eax #Some arg to eax iret #Go to V86 _lo1: And now i'm trying to run that code(it executes, but on int 10h it fails) Code: mov dx,0 mov ss,dx mov sp, 0x8C00 mov dx, ax mov ax, 0x4f02 int 10h ;Crashes here ;How to retrun back? Thanks, Aleksandr |
Author: | pvc [ Mon Dec 24, 2018 10:30 am ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
Some hits: Try to jmp $ before int 0x10 in QEMU and see if you are really running v86 mode and if your registers are all correct using builtin monitor. Check if your IVT is mapped to virtual address 0 and is not trashed (happens easily if you have some uncaught NULL pointer dereferences). The way I return from v86 mode is I use int 0xFE instruction and catch it in the v86 monitor as a special interrupt. I assume you have proper v86 monitor (the emulation layer for privileged 16 bit instructions) in place. |
Author: | MrLolthe1st [ Mon Dec 24, 2018 10:40 am ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
Yes, i'm checked with bochs, i'm working in v86, and registers have right values. But, i'm never corrupt the IVT, because i'm run that code from kernel start(for easily debug). <bochs:9> xp /1w 0x40 [bochs]: 0x0000000000000040 <bogus+ 0>: 0xc0000152 <bochs:10> s Next at t=1597216600 (0) [0x000000008403] 0000:8403 (unk. ctxt): mov ss, bx ; 8ed3 <bochs:11> s Next at t=1597216601 (0) [0x000000008405] 0000:8405 (unk. ctxt): mov sp, 0x8c00 ; bc008c <bochs:12> s Next at t=1597216602 (0) [0x000000008408] 0000:8408 (unk. ctxt): mov dx, ax ; 89c2 <bochs:13> s Next at t=1597216603 (0) [0x00000000840a] 0000:840a (unk. ctxt): mov ax, 0x4f02 ; b8024f <bochs:14> s Next at t=1597216604 (0) [0x00000000840d] 0000:840d (unk. ctxt): int 0x10 ; cd10 <bochs:15> s 01597216604e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d) 01597216604e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08) 01597216604i[CPU0 ] CPU is in v8086 mode (active) 01597216604i[CPU0 ] CS.mode = 16 bit 01597216604i[CPU0 ] SS.mode = 16 bit 01597216604i[CPU0 ] EFER = 0x00000000 01597216604i[CPU0 ] | EAX=00004f02 EBX=00000000 ECX=00000000 EDX=0000010f ... |
Author: | pvc [ Mon Dec 24, 2018 10:58 am ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
Quote: 01597216604e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x0d) 01597216604e[CPU0 ] interrupt(): gate descriptor is not valid sys seg (vector=0x08) Looks like your v86 int instruction emulation is not in place or is not working. You get general protection fault at int 0x10 instruction (which is correct). And after that you get double fault. And then, I assume, triple fault (which means machine reset). The way v86 monitor works is that you are supposed to catch that first GPF and emulate that instruction. EDIT: Here you can see how you can do that. That's some standalone code I've sent to another user as an EXAMPLE (he didn't understand that piece I think and just blindly copypasted all of it into his kernel). EDIT2: Code in previous link had a nasty bug. download/file.php?id=3874 |
Author: | MrLolthe1st [ Mon Dec 24, 2018 11:09 am ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
What is a monitor? I've saw that: https://wiki.osdev.org/Virtual_Monitor, but understood nothing. |
Author: | pvc [ Mon Dec 24, 2018 11:16 am ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
V86 Monitor is a piece of code that emulates 16 bit, otherwise privileged, instructions. For example: You can't execute hlt instruction in 32 bit userland protected mode. It will generate GPF. But let's say you want hlt instruction to be available in userland so you catch an exception it generates and subtitute it with, let's say, current thread suspend code. The same applies to V86 since it's just 16 bit userland code. If you want to use int instruction you have to catch GPF it generates and emulate that instruction in your kernel. |
Author: | MrLolthe1st [ Mon Dec 24, 2018 11:57 am ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
But for what i'm need to emulate it? I'm want to execute BIOS interrupt. How i can catch GPFs? |
Author: | quirck [ Mon Dec 24, 2018 12:17 pm ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
Emulation is needed so that the real-mode code is executed in controlled manner, so that you can decide, for example, whether you allow it to perform i/o, etc. If you don't want to bother with v8086 monitor, maybe just returning to real mode, calling the int, and returning back to pm would be easier? |
Author: | MrLolthe1st [ Mon Dec 24, 2018 12:18 pm ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
quirck, скинь ВК/телегу |
Author: | pvc [ Mon Dec 24, 2018 12:23 pm ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
GPFs are just interrupts. Interrupts with number 13 to be exact. About instruction emulation. Some instructions can be considered unsafe. Some may lead to inconsistency in hardware (like in and out). These have to be emulated. Imagine that your multitasking OS is waiting for an interrupt from HDD and some other thread executes cli instruction and crashes just because. What will happen? . . . HDD driver will never receive that interrupt. And the system will freeze. That's why some instructions need to be emulated. |
Author: | MrLolthe1st [ Mon Dec 24, 2018 12:38 pm ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
So, i'm set handler for 13th interrupt, what next? What that handler must do(i'm won't use v86 for other tasks, only for change videomode)? |
Author: | pvc [ Mon Dec 24, 2018 12:43 pm ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
Good. Then you need to know what instruction caused the exception. For that you need to get faulting instruction EIP. From that you can get the instruction which caused the fault. |
Author: | MrLolthe1st [ Mon Dec 24, 2018 12:55 pm ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
But when fault throws, what i'm need to do, in example, on interrupt? |
Author: | pvc [ Mon Dec 24, 2018 1:00 pm ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
That's really OS dependent thing. in my example the code for instruction 'int n' was: Code: else if(opcode == 0xCD) { // int n byte intNo = peekb(state->CS, ++state->IP); if(intNo == 0xFE) { // special interrupt //memcpy(state, &vm86CPUState, sizeof(MachineState)); size_t size = sizeof(MachineState); byte *dst = (byte *)state; byte *src = (byte *)&vm86CPUState; while(size--) *dst++ = *src++; return true; } pushw(state, state->FLAGS); state->EFLAGS &= ~((1 << 8) | (1 << 9) | (1 << 18)); pushw(state, state->CS); pushw(state, ++state->IP); state->CS = peekw(0x0000, 4 * intNo + 2); state->IP = peekw(0x0000, 4 * intNo); return true; } I have no idea how your interrupt stack frame looks like. That's one thing YOU have to resolve. |
Author: | MrLolthe1st [ Mon Dec 24, 2018 1:17 pm ] |
Post subject: | Re: Enter to V86, perform BIOS Interrupt and return back to |
Ok. So, i've set GPF handler, but when i'm trying to call 'int 10h', GPF hadn't executed, qemu says: (qemu) qemu: fatal: invalid tss type |
Page 1 of 2 | All times are UTC - 6 hours |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |