OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 5:09 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Enter to V86, perform BIOS Interrupt and return back to PM
PostPosted: Mon Dec 24, 2018 10:06 am 
Offline
Member
Member

Joined: Sat Sep 24, 2016 12:06 am
Posts: 90
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


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 10:30 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
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.


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 10:40 am 
Offline
Member
Member

Joined: Sat Sep 24, 2016 12:06 am
Posts: 90
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
...


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 10:58 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
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


Last edited by pvc on Mon Dec 24, 2018 11:10 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 11:09 am 
Offline
Member
Member

Joined: Sat Sep 24, 2016 12:06 am
Posts: 90
What is a monitor? I've saw that: https://wiki.osdev.org/Virtual_Monitor, but understood nothing.


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 11:16 am 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
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.


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 11:57 am 
Offline
Member
Member

Joined: Sat Sep 24, 2016 12:06 am
Posts: 90
But for what i'm need to emulate it? I'm want to execute BIOS interrupt. How i can catch GPFs?


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 12:17 pm 
Offline
Member
Member

Joined: Sun Nov 23, 2008 5:56 am
Posts: 42
Location: Russia, Saint-Petersburg
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?


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 12:18 pm 
Offline
Member
Member

Joined: Sat Sep 24, 2016 12:06 am
Posts: 90
quirck, скинь ВК/телегу :)


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 12:23 pm 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
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.


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 12:38 pm 
Offline
Member
Member

Joined: Sat Sep 24, 2016 12:06 am
Posts: 90
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)?


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 12:43 pm 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
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.


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 12:55 pm 
Offline
Member
Member

Joined: Sat Sep 24, 2016 12:06 am
Posts: 90
But when fault throws, what i'm need to do, in example, on interrupt?


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 1:00 pm 
Offline
Member
Member
User avatar

Joined: Mon Jan 15, 2018 2:27 pm
Posts: 201
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.


Top
 Profile  
 
 Post subject: Re: Enter to V86, perform BIOS Interrupt and return back to
PostPosted: Mon Dec 24, 2018 1:17 pm 
Offline
Member
Member

Joined: Sat Sep 24, 2016 12:06 am
Posts: 90
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


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], DotBot [Bot] and 73 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group