VBE with VirtualPC
VBE with VirtualPC
Hello,
I'm posting here to ask if someone already had the same problem as me
In BOCHS, Qemu and VMWare my VBE module switches mode and displays my GUI properly (except VirtualBox which doesn't support VBE)
But in VirtualPC it doesn't work at all
I call int0x10 with EAX=0x4F00 to get informations about the device ; I store a list of available modes
For each mode I call int0x10 with EAX=0x4F01 to get informations about it ; I filter the 8 bits/pixel modes and modes that don't support linear frame buffer
Then I try switching to mode 0x12e (but the mode doesn't matter), and here the strange thing happens:
VirtualPC's window gets resized to the size of the mode I chose... but the call fails (EAX = 0xFE at the end of interrupt 0x10)
If I simply ignore the errorcode and try writing to the framebuffer, I can't: if I write a byte to it and read it back, its value has not been modified
The content of the frame buffer is full of 0xFF bytes despite the screen being black (it should be white )
I know that's not the kind of problems where people on a forum can help you, but I'm stuck on this for a long time now and I just have no idea about what is going on
Who knows, maybe someone encountered the same problem and could help
Thanks
I'm posting here to ask if someone already had the same problem as me
In BOCHS, Qemu and VMWare my VBE module switches mode and displays my GUI properly (except VirtualBox which doesn't support VBE)
But in VirtualPC it doesn't work at all
I call int0x10 with EAX=0x4F00 to get informations about the device ; I store a list of available modes
For each mode I call int0x10 with EAX=0x4F01 to get informations about it ; I filter the 8 bits/pixel modes and modes that don't support linear frame buffer
Then I try switching to mode 0x12e (but the mode doesn't matter), and here the strange thing happens:
VirtualPC's window gets resized to the size of the mode I chose... but the call fails (EAX = 0xFE at the end of interrupt 0x10)
If I simply ignore the errorcode and try writing to the framebuffer, I can't: if I write a byte to it and read it back, its value has not been modified
The content of the frame buffer is full of 0xFF bytes despite the screen being black (it should be white )
I know that's not the kind of problems where people on a forum can help you, but I'm stuck on this for a long time now and I just have no idea about what is going on
Who knows, maybe someone encountered the same problem and could help
Thanks
MysteriOS
Currently working on: TCP/IP
Currently working on: TCP/IP
-
- Member
- Posts: 134
- Joined: Thu Aug 18, 2005 11:00 pm
- Location: Sol. Earth. Europe. Romania. Bucuresti
- Contact:
Re: VBE with VirtualPC
I use VBE with Virtual PC in my SOLAR_OS and it works just fine (as expected). Hence it "must" be something wrong in your code.
One thing that I have encountered with emulators is that they do not emulate ALL encodings for instructions and hardware less used features. Also when they translate your code (for speed optimization) they can make mistakes in cases of self modifying code or complex code.
Hence if your assembler or compiler does generate "exotic" or less used opcodes in an attempt to optimize code then the code might not work as expected in an emulator.
This is one of the reasons why so many linux distributions do not work in Virtual PC: they either use "undocumented" / "exotic" opcodes or they attempt to use too advanced hardware features that are not emulated exactly and get unexpected results in emulator.
One thing that I have encountered with emulators is that they do not emulate ALL encodings for instructions and hardware less used features. Also when they translate your code (for speed optimization) they can make mistakes in cases of self modifying code or complex code.
Hence if your assembler or compiler does generate "exotic" or less used opcodes in an attempt to optimize code then the code might not work as expected in an emulator.
This is one of the reasons why so many linux distributions do not work in Virtual PC: they either use "undocumented" / "exotic" opcodes or they attempt to use too advanced hardware features that are not emulated exactly and get unexpected results in emulator.
Ambition is a lame excuse for the ones not brave enough to be lazy; Solar_OS http://www.oby.ro/os/
Re: VBE with VirtualPC
Well.. I'm compiling with -march=386 and -O0 (though I sometimes test with -O3 to see if it works) so I don't think GCC will generate exotic thingsbontanu wrote:Hence if your assembler or compiler does generate "exotic" or less used opcodes in an attempt to optimize code then the code might not work as expected in an emulator.
I'm jealous of all the sourceccodes I find ; they do exactly like mine (well, in fact mine does exactly like them ) but mine doesn't work for some obscure reason
Apparently the real mode code for interruption 0x10 uses interruption 0x6D ; first I thought my code (virtual manager) that handles this was wrong, but VMWare does the same and it works :-/
MysteriOS
Currently working on: TCP/IP
Currently working on: TCP/IP
Re: VBE with VirtualPC
On virtual PC this is 1152*768*32, if no error. Try other tooTomaka17 wrote:Then I try switching to mode 0x12e (but the mode doesn't matter)
Make sure you add 0x4000 to the mode number when you call "set mode" function, it ensure you enable LFB ...
Are you sure that palette color define 0xFF value to white ?Tomaka17 wrote:The content of the frame buffer is full of 0xFF bytes despite the screen being black (it should be white )
I'm actually work on vesa driver , try the file "vesa.asm" in init project, loader directory , maybe usefull.
[ Grub 2 | Visual Studio 2013 | PE File ]
The OsDev E.T.
Don't send OsDev MIB !
The OsDev E.T.
Don't send OsDev MIB !
Re: VBE with VirtualPC
Thanks for trying to help :p
I've tested modes 0x112, 0x114, 0x115 and 0x117 (and 0x12E) and none of them is working
They all return EAX = 0xFE and their memory cannot be overwritten
What is strange is that VirtualPC's window is resized to the good resolution, but it still returns an error
Anyway even if it was palette color, I should be able to modify the content of the video memory
I'm going to check your code to see if I forgot something
EDIT : hmm on your website the source code for the vesa driver is only a few lines long :s
I've tested modes 0x112, 0x114, 0x115 and 0x117 (and 0x12E) and none of them is working
They all return EAX = 0xFE and their memory cannot be overwritten
What is strange is that VirtualPC's window is resized to the good resolution, but it still returns an error
Yes I'm doing thisMake sure you add 0x4000 to the mode number when you call "set mode" function, it ensure you enable LFB ...
If I'm right, only "packed pixel" modes use palettes (usually modes with 8 bits per pixel), no?Are you sure that palette color define 0xFF value to white ?
Anyway even if it was palette color, I should be able to modify the content of the video memory
I'm going to check your code to see if I forgot something
EDIT : hmm on your website the source code for the vesa driver is only a few lines long :s
MysteriOS
Currently working on: TCP/IP
Currently working on: TCP/IP
Re: VBE with VirtualPC
init/loader/vesa.asm
- Detect VESA
- Get VESA info
- Check Width, heigh, bits per pixel, LFB
- Copie mode info block
- Set mode
Kernel use VESA and mode info block
Works on Virtual PC, Bochs, Virtualbox, VMWare, Qemu, real PC (nVidia 8400 GS)
- Detect VESA
- Get VESA info
- Check Width, heigh, bits per pixel, LFB
- Copie mode info block
- Set mode
Kernel use VESA and mode info block
Works on Virtual PC, Bochs, Virtualbox, VMWare, Qemu, real PC (nVidia 8400 GS)
[ Grub 2 | Visual Studio 2013 | PE File ]
The OsDev E.T.
Don't send OsDev MIB !
The OsDev E.T.
Don't send OsDev MIB !
Re: VBE with VirtualPC
0xff is the usual value of you try to read memory that is not present. Since the call returns an error, the LFB address is not valid.Tomaka17 wrote:The content of the frame buffer is full of 0xFF bytes
JAL
Re: VBE with VirtualPC
If I had to guess, the VirtualPC's routine is accepting the mode setting, sets up the screen to the desired resolution, then encounters some internal error and aborts, without properly resetting stuff. 0xFE for EAX seems like a very odd error code, I cannot find it in the specs. In fact, it should return AH = 01h in case the function call fails.Tomaka17 wrote:What is strange is that VirtualPC's window is resized to the good resolution, but it still returns an error
JAL
Re: VBE with VirtualPC
VBE RETURN STATUSbut the call fails (EAX = 0xFE at the end of interrupt 0x10)
AL == 4Fh: Function is supported
AL != 4Fh: Function is not supported
AH == 00h: Function call successful
AH == 01h: Function call failed
AH == 02h: Function is not supported in the current hardware configuration
AH == 03h: Function call invalid in current video mode
In your case : AL != 4Fh: Function is not supported
[ Grub 2 | Visual Studio 2013 | PE File ]
The OsDev E.T.
Don't send OsDev MIB !
The OsDev E.T.
Don't send OsDev MIB !
Re: VBE with VirtualPC
..oops I was looking at the wrong filegedd wrote:init/loader/vesa.asm
I agree with that, but why do other Operating Sytems using VESA work with VirtualPC?If I had to guess, the VirtualPC's routine is accepting the mode setting, sets up the screen to the desired resolution, then encounters some internal error and aborts, without properly resetting stuff. 0xFE for EAX seems like a very odd error code, I cannot find it in the specs. In fact, it should return AH = 01h in case the function call fails.
In fact AL != 0x4F means function not supported, but I doubt that 0xFE as a return value is intended
Just in case I removed the whole mode detections thing (in case where previous int 0x10 would make the last one crash) but no change...
Here is my code (but I doubt it will help):
Code: Select all
struct ivt_entry {
uint16_t offset;
uint16_t segment;
} __attribute__((packed))* ivt = (struct ivt_entry*)0xC0000000; // this offset is mapped to physical addr 0x0
memory_context_t* memContext = memory_context_create();
process_thread_t* thread = process_thread_createSystem(0, PROCESS_THREAD_FLAG_I386_VIRTUALMODE | PROCESS_THREAD_FLAG_NOAUTOSTART);
process_thread_useMemoryContext(thread, memContext);
process_thread_modifyRegister(thread, "eax", 0x4F02);
process_thread_modifyRegister(thread, "ebx", vbeModeID | 0x4000); // 0x4000 = use flat mode addressing
process_thread_modifyRegister(thread, "cs", ivt[0x10].segment);
process_thread_modifyRegister(thread, "eip", ivt[0x10].offset);
process_thread_start(thread);
while (process_thread_isStarted(thread)) // virtual thread automatically stops when encountering an 'IRET' with no corresponding 'INT'
process_thread_sleepCurrentThread(50);
unsigned int returnCode = process_thread_readRegister(thread, "eax");
process_thread_delete(thread);
memory_context_delete(memContext);
if ((returnCode & 0xffff) != 0x4F) {
printf("Mode changing failed! Return code: 0x%X\r", returnCode);
return;
}
MysteriOS
Currently working on: TCP/IP
Currently working on: TCP/IP
Re: VBE with VirtualPC
Let's take it by the beginning
1 - Get mode list by function 4F00
2 - Get information on each mode [choose the good one for you]
3 - Set only mode wich are present in list
It's the only way ....
1 - Get mode list by function 4F00
2 - Get information on each mode [choose the good one for you]
3 - Set only mode wich are present in list
It's the only way ....
[ Grub 2 | Visual Studio 2013 | PE File ]
The OsDev E.T.
Don't send OsDev MIB !
The OsDev E.T.
Don't send OsDev MIB !
Re: VBE with VirtualPC
That's what I was doing
What I said in my last post is that I tried to directly switch to mode 0x12E, but it gives the same result
What I said in my last post is that I tried to directly switch to mode 0x12E, but it gives the same result
MysteriOS
Currently working on: TCP/IP
Currently working on: TCP/IP
Re: VBE with VirtualPC
It doesn't explicitly say whether AH must be set if AL != 4Fh, or does it? I'd expect AH = 1. Also, most VBE implementation return 00h in AL on failure, iirc. 0xFE really sounds like an odd return value, expecially since the function call seems to be supported as the window size is already changed.gedd wrote:VBE RETURN STATUSbut the call fails (EAX = 0xFE at the end of interrupt 0x10)
AL == 4Fh: Function is supported
AL != 4Fh: Function is not supported
AH == 00h: Function call successful
AH == 01h: Function call failed
AH == 02h: Function is not supported in the current hardware configuration
AH == 03h: Function call invalid in current video mode
In your case : AL != 4Fh: Function is not supported
JAL
Re: VBE with VirtualPC
Have you already seen this link: DJGPP VBE 2.0 Graphics
Re: VBE with VirtualPC
Ok I dumped VirtualPC's int0x10 handler (thank you serial port redirected to a file )
The main code is like:
At %cs:0x11ae there is a table containing addresses of functions
Depending on AL, a different one is called
But when calling with AL = 2, the function modifies some memory offsets and finally jumps to a location where there is:
According to Ralf Brown's interrupts list, interrupt 0x6D is the video BIOS entry point for many video cards
The handler for 0x6D then checks the value of AX
At the time of 'int 0x6D', AX already equals 0xFE
The value of AH is zero so it jumps to another routine which analyzes AL
But as AL is too large (0xFE), it IRETs without modifying the return code
So the problem is: AX shouldn't be equal to 0xFE at the time of 'int 0x6D'
Tomaka17 continuing investigations
EDITs : typos
The main code is like:
Code: Select all
pushfl
pushal
push %ds
push %es
push %fs
push %gs
call *%cs:0x11ae(%al * 2)
movb $0x4f, 0x24(%bp)
jb at 'movb $0x1' just below, the flags are certainly modified by the call just above
movb $0x0, 0x25(%bp)
jmp at 'pop %gs'
movb $0x1, 0x25(%bp)
jmp at 'pop %gs'
pop %gs
pop %fs
pop %es
pop %ds
popal
popfl
iret
Depending on AL, a different one is called
But when calling with AL = 2, the function modifies some memory offsets and finally jumps to a location where there is:
Code: Select all
int 0x6D
iret
The handler for 0x6D then checks the value of AX
At the time of 'int 0x6D', AX already equals 0xFE
The value of AH is zero so it jumps to another routine which analyzes AL
But as AL is too large (0xFE), it IRETs without modifying the return code
So the problem is: AX shouldn't be equal to 0xFE at the time of 'int 0x6D'
Tomaka17 continuing investigations
EDITs : typos
Last edited by Tomaka17 on Tue May 05, 2009 3:14 am, edited 2 times in total.
MysteriOS
Currently working on: TCP/IP
Currently working on: TCP/IP