Hey,
I'm trying to write an interrupt that'll accept a register set, and an interrupt number, which will call the requested _real mode_ interrupt, and return the resultant register set.
I didn't want to create an entirely new vm86 task for this, so I decided to have the interrupt create a stack frame for a vm86 task and "iret" to it... but my knowledge of this is kind of fuzzy.
This is possible, correct?
If so, wouldn't it look something like this:
push dword real_mode_gs
push dword real_mode_fs
push dword real_mode_ds
push dword real_mode_es
push dword real_mode_ss
push dword real_mode_esp
pushfd (with vm86 bit = 1)
push dword real_mode_cs
push dword real_mode_eip
iretd
Is this right? Should cs:eip be real mode segments, or actual linear addresses?
My code segfaults at the iretd, so I'm guessing it's a messed stack frame, but I can't find good info on what the vm86 stack frame looks like.
Thanks,
Jeff
iret to vm86 proceedure
RE:iret to vm86 proceedure
You can't cheat like that, since when you are in pmode, all segment adresses are selectors. So if
you wont to have real-mode segments you need to create vm86 task.
you wont to have real-mode segments you need to create vm86 task.
RE:iret to vm86 proceedure
True... to a certain extent.
I've done some experimentation, and it is indeed possible to iret to a vm86 task, to a real mode cs:ip part. You just have to make sure that cs:ip are mapped, and withen the first 1mb (which, of course, the cs:ip's for real mode interrupts are... they're located at 0x0, and exist between 0xA0000 and 0xFFFFF.
The problem, of course, and what you've probably noticed well before I did, is passing the register set. Passing real mode values into eax - edx, edi, and esi are no problem, making most of the video bios possible with such a system. However, passing real mode values in ds, es, fs, gs are impossible. These registers would have to be loaded with real mode values _before_ the call to the protected mode, and would, of course, result in a gpf.
It would be possible to pass these onto the stack, to the real mode interrupt, and then copy to the vm86 stack frame, and have the vm86 code pop them in, but that's getting more complicated then I like.
You're right... I tried to cheat it It is, indeed, possible, but I've decided to revamp the code and use a full vm86 task and monitoring task. It's more code, but with VME, it's probably actually simpler... and more general purpose.
Cheers,
Jeff
I've done some experimentation, and it is indeed possible to iret to a vm86 task, to a real mode cs:ip part. You just have to make sure that cs:ip are mapped, and withen the first 1mb (which, of course, the cs:ip's for real mode interrupts are... they're located at 0x0, and exist between 0xA0000 and 0xFFFFF.
The problem, of course, and what you've probably noticed well before I did, is passing the register set. Passing real mode values into eax - edx, edi, and esi are no problem, making most of the video bios possible with such a system. However, passing real mode values in ds, es, fs, gs are impossible. These registers would have to be loaded with real mode values _before_ the call to the protected mode, and would, of course, result in a gpf.
It would be possible to pass these onto the stack, to the real mode interrupt, and then copy to the vm86 stack frame, and have the vm86 code pop them in, but that's getting more complicated then I like.
You're right... I tried to cheat it It is, indeed, possible, but I've decided to revamp the code and use a full vm86 task and monitoring task. It's more code, but with VME, it's probably actually simpler... and more general purpose.
Cheers,
Jeff