VMWare VBE Problem.
Posted: Sat Nov 14, 2015 8:20 am
Hello, osdev forum!
I was developing my VBE driver and i have a problem now...
My VESA driver works great in VirtualBox, QEMU and Real hardware.
But in Bochs and VMWare i have strange problems...
I tried mode switching and etc with my both int32 (turns the real mode back does the interrupt and reenters the protected mode again, then loads the system state) and v8086 monitor, but same results in int32 and v8086, no difference...
I'm sure both v8086 and int32 working, i tested different interrupts and different video modes (0x12h, 0x13h, and etc) and it worked in all virtual machines and real hardware.
The problem is:
If i try setting the mode with an old legacy standardized video mode number (Like 0x117) in get controller info and get mode info, bochs and vmware returns success (0x004F), too like other virtual machines and real hardware. But when setting the mode, in VMWare and Bochs, system crashes (accidentally freezes, no turn back or error [error and exception handling works great in my system, tested too much times], system magically freezes, display stays same, i can't get the value in ax, because system crashes like i said) but in other virtual machines and real hardware, it works great again.
If i use http://wiki.osdev.org/Getting_VBE_Mode_Info 's get best display mode function, in bochs and vmware can't get any video mode from Video Mode Pointer, the Modes list i get from Video Mode Pointer is empty. But if i try in real hardware or other virtual machines it gets the modes, also sets the mode without problem again...
The debug output from both VMWare and other working virtual machines:
VMWare (When i try first way) (Mode is 0x114) (With LFB):
Get Controller Info:
Video Mode Pointer = 0xC00063BE
AX = 0x4F
Version = 2.0
Signature = VESA
Get 0x114 (With LFB) Mode Info:
Width = 800
Height = 600
Depth = 16
AX = 0x4F
Base pointer = (A correct value but i forgot it now)
Set Mode:
Nothing, system crashes, display looks same and interrupts being disabled.
--------------------------------------------------------------------------------------------------------------------------
VMWare (When i try first way) (Mode is 0x114) (Without LFB):
Get Controller Info:
Video Mode Pointer = 0xC00063BE
AX = 0x4F
Version = 2.0
Signature = VESA
Get 0x114 (Without LFB) Mode Info:
Width = 65535
Height = 512
Depth = 4
AX = 0x14F
Base pointer = (An incorrect value but i forgot it, too)
-------------------------------------------------------------------------------------------------------
VMWare, Using http://wiki.osdev.org/Getting_VBE_Mode_Info 's get best VBE mode function: (I wanted 800x600x16)
Get Controller Info:
Video Mode Pointer = 0xC00063BE
AX = 0x4F
Version = 2.0
Signature = VESA
Get Mode List:
List is empty, but it must be full of video modes.
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
In both other VMs And Real hardware: ( Excluding Bochs, Bochs has same result with VMWare [Results in top] )
Get Controller Info:
Video Mode Pointer = 0x202200
AX = 0x4F
Version = 3.0
Signature = VESA
-----------------------------------------------------------------------------------------
If using legacy standardized mode numbers ( Mode is 0x114 )
Get Mode Info:
(Correct values with / without LFB. Correct pointer, too)
AX = 0x4F
----------------------------------------------------------------------------------------------------
If using the http://wiki.osdev.org/Getting_VBE_Mode_Info 's get best VBE mode function:
List is full of video modes, also function gets the needed mode correctly.
AX = 0x4F
--------------------------------------------------------------------------------------------------------
Set Mode:
Screen resizes, sets the mode correct, and i can draw pixel.
AX = 0x4F
----------------------------------------------------------------------------------------------------------------------
The code i'm using:
Tried with / without LFB, still same, not sure what is the bug...
Tried with much different mode numbers and resolutions, same, nothing changes...
#Edit:
I simplified code to this and started to working, i started to think vbe get mode info is broken on VMWare...
Anyone knows a fix, or what can be the problem?
Thanks for helping
I was developing my VBE driver and i have a problem now...
My VESA driver works great in VirtualBox, QEMU and Real hardware.
But in Bochs and VMWare i have strange problems...
I tried mode switching and etc with my both int32 (turns the real mode back does the interrupt and reenters the protected mode again, then loads the system state) and v8086 monitor, but same results in int32 and v8086, no difference...
I'm sure both v8086 and int32 working, i tested different interrupts and different video modes (0x12h, 0x13h, and etc) and it worked in all virtual machines and real hardware.
The problem is:
If i try setting the mode with an old legacy standardized video mode number (Like 0x117) in get controller info and get mode info, bochs and vmware returns success (0x004F), too like other virtual machines and real hardware. But when setting the mode, in VMWare and Bochs, system crashes (accidentally freezes, no turn back or error [error and exception handling works great in my system, tested too much times], system magically freezes, display stays same, i can't get the value in ax, because system crashes like i said) but in other virtual machines and real hardware, it works great again.
If i use http://wiki.osdev.org/Getting_VBE_Mode_Info 's get best display mode function, in bochs and vmware can't get any video mode from Video Mode Pointer, the Modes list i get from Video Mode Pointer is empty. But if i try in real hardware or other virtual machines it gets the modes, also sets the mode without problem again...
The debug output from both VMWare and other working virtual machines:
VMWare (When i try first way) (Mode is 0x114) (With LFB):
Get Controller Info:
Video Mode Pointer = 0xC00063BE
AX = 0x4F
Version = 2.0
Signature = VESA
Get 0x114 (With LFB) Mode Info:
Width = 800
Height = 600
Depth = 16
AX = 0x4F
Base pointer = (A correct value but i forgot it now)
Set Mode:
Nothing, system crashes, display looks same and interrupts being disabled.
--------------------------------------------------------------------------------------------------------------------------
VMWare (When i try first way) (Mode is 0x114) (Without LFB):
Get Controller Info:
Video Mode Pointer = 0xC00063BE
AX = 0x4F
Version = 2.0
Signature = VESA
Get 0x114 (Without LFB) Mode Info:
Width = 65535
Height = 512
Depth = 4
AX = 0x14F
Base pointer = (An incorrect value but i forgot it, too)
-------------------------------------------------------------------------------------------------------
VMWare, Using http://wiki.osdev.org/Getting_VBE_Mode_Info 's get best VBE mode function: (I wanted 800x600x16)
Get Controller Info:
Video Mode Pointer = 0xC00063BE
AX = 0x4F
Version = 2.0
Signature = VESA
Get Mode List:
List is empty, but it must be full of video modes.
---------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------
In both other VMs And Real hardware: ( Excluding Bochs, Bochs has same result with VMWare [Results in top] )
Get Controller Info:
Video Mode Pointer = 0x202200
AX = 0x4F
Version = 3.0
Signature = VESA
-----------------------------------------------------------------------------------------
If using legacy standardized mode numbers ( Mode is 0x114 )
Get Mode Info:
(Correct values with / without LFB. Correct pointer, too)
AX = 0x4F
----------------------------------------------------------------------------------------------------
If using the http://wiki.osdev.org/Getting_VBE_Mode_Info 's get best VBE mode function:
List is full of video modes, also function gets the needed mode correctly.
AX = 0x4F
--------------------------------------------------------------------------------------------------------
Set Mode:
Screen resizes, sets the mode correct, and i can draw pixel.
AX = 0x4F
----------------------------------------------------------------------------------------------------------------------
The code i'm using:
Code: Select all
uint16_t findMode(int x, int y, int d)
{
struct VESA_INFO *ctrl = (VESA_INFO *)0x2000;
struct MODE_INFO *inf = (MODE_INFO *)0x3000;
uint16_t *modes;
int i;
uint16_t best = 0x13;
int pixdiff, bestpixdiff = DIFF(320 * 200, x * y);
int depthdiff, bestdepthdiff = 8 >= d ? 8 - d : (d - 8) * 2;
regs16_t regs;
memcpy(ctrl->VESASignature, "VBE2", 4);
regs.ax = 0x4F00;
regs.es = 0;
regs.di = ctrl;
int32(0x10, ®s); // Get Controller Info
if ( (uint16_t)regs.ax != 0x004F )
{
putstring("ERROR!");
}
modes = (uint16_t*)(ctrl->VideoModePtr);
putstring_hex(ctrl->VideoModePtr);
for ( i = 0 ; modes[i] != 0xFFFF ; ++i ) {
regs.ax = 0x4F01;
regs.cx = modes[i];
regs.es = 0;
regs.di = inf;
int32(0x10, ®s); // Get Mode Info
if ( (uint16_t)regs.ax != 0x004F ) continue;
// Check if this is a graphics mode with linear frame buffer support
if ( (inf->ModeAttributes & 0x90) != 0x90 ) continue;
// Check if this is a packed pixel or direct color mode
if ( inf->MemoryModel != 4 && inf->MemoryModel != 6 ) continue;
// Check if this is exactly the mode we're looking for
if ( x == inf->XResolution && y == inf->YResolution &&
d == inf->BitsPerPixel ) return modes[i];
// Otherwise, compare to the closest match so far, remember if best
pixdiff = DIFF(inf->XResolution * inf->YResolution, x * y);
depthdiff = (inf->BitsPerPixel >= d)? inf->BitsPerPixel - d : (d - inf->BitsPerPixel) * 2;
if ( bestpixdiff > pixdiff ||
(bestpixdiff == pixdiff && bestdepthdiff > depthdiff) ) {
best = modes[i];
bestpixdiff = pixdiff;
bestdepthdiff = depthdiff;
}
}
if ( x == 640 && y == 480 && d == 1 ) return 0x11;
return best;
}
void setVesa(unsigned int X, unsigned int Y, unsigned int BitsPerPixel)
{
regs16_t regs;
regs.ax = 0x4f02; //mode the sets up VESA graphics
regs.bx = (findMode(X, Y, BitsPerPixel));
int32(0x10, ®s);
}
Tried with much different mode numbers and resolutions, same, nothing changes...
#Edit:
Code: Select all
void setVesa(uint32_t mode)
{
regs16_t regs;
memset(®s, 0, sizeof(regs));
regs.ax = 0x4F02;
regs.bx = (mode | 0x4000);
int32(0x10, ®s);
}
Anyone knows a fix, or what can be the problem?
Thanks for helping