VESA Linear frame buffer implementation in PM

Programming, for all ages and all languages.
Post Reply
maheshstms
Posts: 5
Joined: Mon Jan 22, 2007 3:44 am
Location: Chennai, India
Contact:

VESA Linear frame buffer implementation in PM

Post 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
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: VESA Linear frame buffer implementation in PM

Post 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
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.
Post Reply