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.
Alas, to my great unhappiness, i have to tell you, that you 're gonna need a vm86 monitor to catch all the privileged instructions: in, out, push, pop, int ... they all occur, even in 16 bit bios code, which you're definitely gonna call to switch to any vbe/vesa graphics mode.
Besides, depending on your memory setup, you'll have to do a lot more stuff to get the vm86 task up and running.
Hint: google for "tim robinson vm86 tutorial" to get some fine stuff about vm86 monitors.
astrocrep wrote:I do NOT plan on running 16bit code in my OS, I also do not plan on executing 16bit drivers in my OS. However, I do need 16bit vm86 for VESA.
In this case you'd need to setup a real mode compatible environment - e.g. a dummy IDT, identity map the video card's ROM at 0x000C0000, setup a real mode stack, etc. You'd also need a VM86 monitor, which mostly means handling some things in your general protection fault handler (emulating CLI, STI, I/O port instructions, etc) and working out what happens with IRQs (IIRC there's 2 different mechanisms for this).
There's an alternative though - you can run an emulator. For example, several open source projects use something called "x86emu" to initialize and use real mode video BIOS code.
There's also another alternative - setup the video mode before you switch to protected mode.
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Ok, so the first 4mb is identity mapped. Though, I don't understand why I am going to need push/pop and in/out. Are they something the video init code calls?
I know the small amount of code that will actually go through the vm86 will just be pseudo int calls to set the video mode or get vesa info, and niether of those commands need push/pop or in/out.
astrocrep wrote:Ok, so the first 4mb is identity mapped. Though, I don't understand why I am going to need push/pop and in/out. Are they something the video init code calls?
I know the small amount of code that will actually go through the vm86 will just be pseudo int calls to set the video mode or get vesa info, and niether of those commands need push/pop or in/out.
Thanks,
Rich
Wouldn't be easier to switch to real mode for now and then jump back to protected mode? I can send some code (in assembly though) but it may not be compatible with your OS.
However, If my instruction pointer is somewhere off at physical 1.1mb mark, how to I get it to run code down at some lower mark, say 300k mark? Also how can I be sure I don't clobber my existing setup. Would it really be just as easy as switching off the PM BIT, running the interrupt, and then loading the PM BIT back on? Or do I need to rebuild paging and setup my gdt/ldt/idt again?
Yea, I would be really interested in seeing some code.
However, If my instruction pointer is somewhere off at physical 1.1mb mark, how to I get it to run code down at some lower mark, say 300k mark? Also how can I be sure I don't clobber my existing setup. Would it really be just as easy as switching off the PM BIT, running the interrupt, and then loading the PM BIT back on? Or do I need to rebuild paging and setup my gdt/ldt/idt again?
Yea, I would be really interested in seeing some code.
Thanks,
Rich
*cough**cough*Paging?*cough*
I never implemented paging in my OS (well I am just learning protected mode segmentation, and comparing the differences between real mode), so you will have to setup your GDT and IDT (and paging too) all over again, if you want to switch to real mode. But I suggest that you really call INT 10h with VESA before entering protected mode...
Here is some code (again, not my code, but may help you) attached.
well, you have to realize that your vm86 monitor must be able to take care of the actual video BIOS code
"int 10" or whatever doesn't do any sort of magic, it just looks up entry #10 in the real mode IDT and loads CS:IP from there (you must of course emulate this behaviour too)
these new CS:IP values usually point to the relevant function in the BIOS code, which in turn does the hardware interfacing which of course needs in/out
pushf/popf was just another example of something you must emulate (because the real mode code is usually not allowed to modify certain flags)
astrocrep wrote:What I still don't get is how edo I get the 16bit code below the 1mb mark?
One of the good things about v8086 is you can use paging. Say you create a simple real mode task that is linked to run at real-mode address 0x1000:0x0000. All you have to do is load it anywhere in physical memory, create a new page directory for your v8086 task and one page table for the lowest 4MB, map the program to virtual address 0x10000, map the first 4kB of physical memory and 640kB - 1MB linearly and run the task. This means you can have multiple v8086 tasks running at once, all from the same linear address. Obviously you still need a v8086 monitor. pcmattman posted one a while back that seemed quite decent.
If you want to do it by dropping back to real mode, then I guess you'll need to memcpy the executable from wherever you load it to its load address under 1MB before you drop back.
I have VM86 working just for use with VESA. I didn't implement a full monitor, just a special check in the general fault handler to see if the error occurred while in vm86 mode.
If the error ocurred in vm86 mode then the running process is killed and the parent(the one that spawned the vm86 process) is signalled that the vm86 task has completed.
I mark int 0x40 in the TSS iomap(think that is what its called) so that a call to int 0x40 from vm86 mode triggers a gp fault.
Basically, only my vesa code needs this, so a full blown vm86 monitor was unnecessary.
I'll give a full explanation of how I did it,Once I gather all the relevant lines of code.
p.s. This method works on real pc,vmware and Bochs. It seems not to work in qemu.(dont know why)
bluecode wrote:Why did none of you mention Virtual-8086-Mode Extensions? With that you don't need a virtual-8086-monitor.
You'll still need it for when a program wants to exit v8086 mode
"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 ]