Page 1 of 1

VESA Linear frame buffer implementation in PM

Posted: Thu Mar 01, 2007 5:57 am
by maheshstms
Hello all

I am making my OS, I like to implement graphics for it using VESA.
I use GRUB to boot my OS from disk, I use GRUB to initialize graphics for me 800x600 256 colors.

I use VMWare for my work, it has VBE 2.0 and I get the Phyical address to be 0xF0000000. When I write some thing to the location after the mode is set I see nothing displayed.

I found the link
http://www.osdev.org/phpBB2/viewtopic.php?p=84864#84864

where 'granularity' bit is spoken. where to set this bit. Is this the problem???

Code: Select all

for(x = 0; x < 600; x++)
{
	for(y = 0; y < 800; y++)
	{
		/*Is this ok.*/
		*((unsigned char *) (0xf0000000 + (y*800 + x))) = 0xff;
	}
}
please help

Thanks

Mahesh

Re: VESA Linear frame buffer implementation in PM

Posted: Thu Mar 01, 2007 6:58 am
by Brendan
Hi,
maheshstms wrote:I found the link
http://www.osdev.org/phpBB2/viewtopic.php?p=84864#84864

where 'granularity' bit is spoken. where to set this bit. Is this the problem???
I very much doubt it's the same problem - the granularity bit in that topic is for a GDT entry (or for the limit on data segments). If you're using GRUB then I'm guessing you (currently) let GRUB set this up for you, so it's not likely to be the problem here.
maheshstms wrote:

Code: Select all

for(x = 0; x < 600; x++)
{
	for(y = 0; y < 800; y++)
	{
		/*Is this ok.*/
		*((unsigned char *) (0xf0000000 + (y*800 + x))) = 0xff;
	}
}
There's only 3 problems I can see here (assuming the video mode is 800 * 600 * 256). The first one is that you're using a fixed address (0xF0000000) rather than detecting the correct address.

The second problem is that you've got X and Y mixed up - the code is for 600*800 rather than 800*600...

The other problem is that there may be more than 800 bytes per screen line. For example, often you might have 1024 bytes per screen line where the first 800 bytes are displayed and the remaining bytes aren't displayed. To fix this you need to get the "bytes_per_line" from VESA and use something like "*((unsigned char *) (VID_ADDRESS + (y*BYTES_PER_LINE + x))) = 0xff;".

Although I'd recommend something more like this:

Code: Select all

for(y = 0; y < 600; y++)
{
	currentLine = VID_ADDRESS + y * BYTES_PER_LINE;
	for(x = 0; x < 800/4; x++)
	{
		(dword *)currentLine[x] = 0xFFFFFFFF;
	}
}
This is similar to your code, except it recalculates the address much less often, it's doing 32-bits at a time, and it's much better for caching (write-combining) because it does sequential accesses (i.e. it does one line at a time rather than one colum at a time).

BTW are you sure your code is actually run? Is it possible that the OS locks up after setting the video mode but before filling the screen?

I would expect that if the video is at 0xF0000000 (and if you're using segment registers setup by GRUB and not using paging) then you would've seen white horizontal strips in some sort of pattern.


Cheers,

Brendan