Page 1 of 1
Problem with VESA LFB on VMWare
Posted: Mon Feb 18, 2013 3:29 pm
by BlackIce
Hello All,
I'm playing with my small investigation OS and got stuck with vesa lfb on VMWare. When I run my OS in the Bosch or VirtualPC it looks ok, but the same code doesn't not produce the same results on VMWare workstation. Please see the screens attached. I've spent a week reading docs/specs from different informational resources from inet, but still have no idea how to fix this. I would be very glad if someone give me some advise or at last show the general research direction. On the sreenshots is the same kernel running in different emulators.
The attachment VirtualPC_gfx.png is no longer available
Thanks.
Re: Problem with VESA LFB on VMWare
Posted: Mon Feb 18, 2013 3:32 pm
by BlackIce
Re: Problem with VESA LFB on VMWare
Posted: Mon Feb 18, 2013 8:44 pm
by Brendan
Hi,
That last picture looks like the second MiB of pixel data has overwritten the first MiB of pixel data, and the third MiB of pixel data is fine. It's almost as if something is causing the 21st address line (A20) to be ignored...
Cheers,
Brendan
Re: Problem with VESA LFB on VMWare
Posted: Tue Feb 19, 2013 3:18 am
by Shaun
could you show us some pieces of the vesa drawing code?
Re: Problem with VESA LFB on VMWare
Posted: Tue Feb 19, 2013 6:26 am
by BlackIce
Brendan wrote:
That last picture looks like the second MiB of pixel data has overwritten the first MiB of pixel data, and the third MiB of pixel data is fine. It's almost as if something is causing the 21st address line (A20) to be ignored...
Thanks Brendan! I've added code that enables gate A20 and now it works fine on VMWare as well! Accordingly to intel manuals, first far jump or call after switching to the protected mode should open this gate automatically. That is why I did not add the code to specially enable this gate before.
virusest wrote:could you show us some pieces of the vesa drawing code?
Yes, please:
Code: Select all
void gfx_drawRainbow()
{
const DWORD dwWidth = g_pMode->XResolution;
const DWORD dwHeight = g_pMode->YResolution;
const DWORD dwColors = 4;
DWORD dwSize = dwWidth * dwHeight * dwColors;
DWORD dwSteps = 256 * 5;
float fStepSize = (float)dwHeight / (float)dwSteps;
BYTE bRed = 255;
BYTE bGreen = 0;
BYTE bBlue = 0;
for( DWORD i = 0; i < dwSteps; i++ )
{
if( bRed == 255 && bBlue == 0 && bGreen < 255 )
bGreen++;
else if( bRed > 0 && bGreen == 255 && bBlue == 0 )
bRed--;
else if( bRed == 0 && bGreen == 255 && bBlue < 255 )
bBlue++;
else if( bRed == 0 && bGreen > 0 && bBlue == 255 )
bGreen--;
else if( bRed < 255 && bGreen == 0 && bBlue == 255 )
bRed++;
else if( bRed == 255 && bGreen == 0 && bBlue > 0 )
bBlue--;
for( DWORD y = i * fStepSize; y < fStepSize * (i+1); y++ )
{
for( DWORD x = 0; x < dwWidth; x++ )
{
gfx_putPixel( x, y, RGB( bRed, bGreen, bBlue ) );
}
}
}
}
void gfx_putPixel( DWORD x, DWORD y, DWORD color )
{
DWORD dwOffset = y * g_pMode->XResolution + x; //y * g_pMode->BytesPerScanLine + x * g_pMode->BitsPerPixel / 4;
g_pLFB[dwOffset] = color;
}
Re: Problem with VESA LFB on VMWare
Posted: Tue Feb 19, 2013 7:12 am
by Combuster
BlackIce wrote:first far jump or call after switching to the protected mode should open this gate automatically. That is why I did not add the code to specially enable this gate before.
And most processors I've seen don't do that. So either that's a new feature or a misinterpretation.
Re: Problem with VESA LFB on VMWare
Posted: Tue Feb 19, 2013 3:10 pm
by dozniak
BlackIce wrote:Code: Select all
for( DWORD y = i * fStepSize; y < fStepSize * (i+1); y++ )
{
for( DWORD x = 0; x < dwWidth; x++ )
{
gfx_putPixel( x, y, RGB( bRed, bGreen, bBlue ) );
}
}
}
}
How long does it usually take to draw this rainbow, pixel by pixel?
Re: Problem with VESA LFB on VMWare
Posted: Tue Feb 19, 2013 4:44 pm
by BlackIce
I haven't measured this
, but I think it takes a while... however on real h/w rainbow appears immediately. I just use this code to test that everything is OK with my LFB. Performance is not critical at this moment.
Re: Problem with VESA LFB on VMWare
Posted: Tue Feb 19, 2013 11:52 pm
by Shaun
BlackIce wrote:Brendan wrote:
That last picture looks like the second MiB of pixel data has overwritten the first MiB of pixel data, and the third MiB of pixel data is fine. It's almost as if something is causing the 21st address line (A20) to be ignored...
Thanks Brendan! I've added code that enables gate A20 and now it works fine on VMWare as well! Accordingly to intel manuals, first far jump or call after switching to the protected mode should open this gate automatically. That is why I did not add the code to specially enable this gate before.
virusest wrote:could you show us some pieces of the vesa drawing code?
Yes, please:
Code: Select all
void gfx_drawRainbow()
{
const DWORD dwWidth = g_pMode->XResolution;
const DWORD dwHeight = g_pMode->YResolution;
const DWORD dwColors = 4;
DWORD dwSize = dwWidth * dwHeight * dwColors;
DWORD dwSteps = 256 * 5;
float fStepSize = (float)dwHeight / (float)dwSteps;
BYTE bRed = 255;
BYTE bGreen = 0;
BYTE bBlue = 0;
for( DWORD i = 0; i < dwSteps; i++ )
{
if( bRed == 255 && bBlue == 0 && bGreen < 255 )
bGreen++;
else if( bRed > 0 && bGreen == 255 && bBlue == 0 )
bRed--;
else if( bRed == 0 && bGreen == 255 && bBlue < 255 )
bBlue++;
else if( bRed == 0 && bGreen > 0 && bBlue == 255 )
bGreen--;
else if( bRed < 255 && bGreen == 0 && bBlue == 255 )
bRed++;
else if( bRed == 255 && bGreen == 0 && bBlue > 0 )
bBlue--;
for( DWORD y = i * fStepSize; y < fStepSize * (i+1); y++ )
{
for( DWORD x = 0; x < dwWidth; x++ )
{
gfx_putPixel( x, y, RGB( bRed, bGreen, bBlue ) );
}
}
}
}
void gfx_putPixel( DWORD x, DWORD y, DWORD color )
{
DWORD dwOffset = y * g_pMode->XResolution + x; //y * g_pMode->BytesPerScanLine + x * g_pMode->BitsPerPixel / 4;
g_pLFB[dwOffset] = color;
}
thanks a lot for your sharing.
i have a question, where does your g_pLFB point to?
0xA0000 in protected mode if you use banked mode, or
0xd0000000(VMware),0xe0000000(bochs) if you enable bit 14 in mode number when you move to graphic mode ?
if the later case, did you map 0xe0000000 to a valid place?
Re: Problem with VESA LFB on VMWare
Posted: Wed Feb 20, 2013 10:16 am
by BlackIce
g_pLFB is a pointer to linear frame buffer, it points directly to the video memory and initialized by 0xD0000000 for VMWare, etc... I do not use banked mode. Bit 14 was enabled upon initialization - that's indicates linear frame buffer mode.
I do not use any special mapping. My small kernel doesn't use paging at all. I've just created flat data segment with base 0 and limit 4Gb.
Re: Problem with VESA LFB on VMWare
Posted: Wed Feb 20, 2013 8:02 pm
by Shaun
BlackIce wrote:g_pLFB is a pointer to linear frame buffer, it points directly to the video memory and initialized by 0xD0000000 for VMWare, etc... I do not use banked mode. Bit 14 was enabled upon initialization - that's indicates linear frame buffer mode.
I do not use any special mapping. My small kernel doesn't use paging at all. I've just created flat data segment with base 0 and limit 4Gb.
thanks again, i got it. your posts really do me a big favor and settle a puzzle which stuck me for a long time up.
sorry for my poor English, by the way, do you have any ideas about displaying picture in grapic mode?
Re: Problem with VESA LFB on VMWare
Posted: Thu Feb 21, 2013 8:57 am
by BlackIce
Well, it depends on your needs. At first it looks so trivial: you should copy array of color data into screen memory. Digging into details you've probably heard about stuff like creating off-screen surfaces, clipping, scaling/stretching, texture filtering, bit blitting. That's all you need to consider to have your picture correctly displayed in some frame.
...I see that RGB macro stolen from wingdi.h doesn't work well for vesa. All my rainbows are inverted. The actual position of each color component should be taken from mode info structure...
Re: Problem with VESA LFB on VMWare
Posted: Thu Feb 21, 2013 10:01 am
by Griwes
BlackIce wrote:The actual position of each color component should be taken from mode info structure...
Remember: not only position, but also size. I've made a mistake of forgetting about using size fields, and I kept getting light purple text instead of grey one in 16bit mode