Frame Buffer Mapping - Another thread

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Frame Buffer Mapping - Another thread

Post by piranha »

I am currently using patched grub to setup 800x600 video mode for me. I am trying to color the screen white. I know the code that actually does it works, as when I run it before paging, the screen becomes white.

I am using JamesM's tutorials for my memory management.
The code that I'm using to map is as follows:

Code: Select all

   int a;
   char *vga;
   a = (int)0xE0000000;
   vga=a;
   for (i = v->phys_base_ptr; i < (v->phys_base_ptr + (xr*yr*(bpp/8))); i += 0x1000,a += 0x1000)
   {
      page_t *p = get_page (a, 1, current_directory);
      p->frame = i;
      p->rw = 1;
      p->user = 0;
      p->present = 1;
   }
When I run the screen coloring code after paging is enabled, and after I run the above code, I only get about 1.75 lines colored at the top of the screen.

I've searched around already, but I still can't figure it out. Any ideas?

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Re: Frame Buffer Mapping - Another thread

Post by kmtdk »

well
my first guess is:
the mapping are to far away.
Meaning that when you are writing the screen, the address you are pointing at, is behind the "real" address.

example:
you have mapped, so that 0x1000 is 0x0000
and you are supossed to wrtie to the "REAL" address 0x2000
then writing at 0x2000 = 0x3000
so the currect address is 0x1000

IF you are sure about this, then more details are needed to find the problem

KMT dk
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Re: Frame Buffer Mapping - Another thread

Post by piranha »

Alright, I think I know what you mean, but can you put that in terms of my addresses if possible?

thanks, JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Frame Buffer Mapping - Another thread

Post by Brendan »

Hi,
piranha wrote:

Code: Select all

  for (i = v->phys_base_ptr; i < (v->phys_base_ptr + (xr*yr*(bpp/8))); i += 0x1000,a += 0x1000)
This looks dodgy to me - often there's unused bytes on the right hand side of video display memory for padding. For example, for 800 * 600 * 32 bpp each line can be 4096 bytes where the first 3200 bytes are visible pixels and the remaining 896 bytes are padding, so video memory looks like this:

Code: Select all

************......
************......
************......
************......
************......
There should be a "bytes_per_line" field somewhere, and you should map "y_resolution * bytes_per_line" bytes (as a minimum).
piranha wrote:When I run the screen coloring code after paging is enabled, and after I run the above code, I only get about 1.75 lines colored at the top of the screen.
You didn't say, but I'd assume this works out to 24 bpp mode and only the first page is mapped correctly (4096 / 3 / 800 = 1.706666 lines). It should be easy to find the problem with Bochs debugger, but I'd guess the "xr", "yr" or "bpp" variables don't contain what they should and the loop exits early.


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.
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Re: Frame Buffer Mapping - Another thread

Post by piranha »

Yeah, I just had it print the values, and yes, xr and yr are negative numbers, along with bpp.

I'll work on it...

Edit: I defined the variables as unsigned, and now the values are xr=61440, yr=65363, and bpp=255
Edit2:

Code: Select all

 kprintf("Mapping...\n");
 for (i = v->phys_base_ptr; i < (v->phys_base_ptr + (yr*v->bytes_per_scan_line)); i += 0x1000,a += 0x1000)
   {
	   kprintf("1 page\n");
only prints "Mapping...", but not "1 page", so v->phys_base_ptr + (yr*v->bytes_per_scan_line) must be less than v->phys_base_ptr...

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Frame Buffer Mapping - Another thread

Post by Brendan »

Hi,
piranha wrote:Edit: I defined the variables as unsigned, and now the values are xr=61440, yr=65363, and bpp=255
It's very unlikely those are sane values for any video mode...
piranha wrote:only prints "Mapping...", but not "1 page", so v->phys_base_ptr + (yr*v->bytes_per_scan_line) must be less than v->phys_base_ptr...
Are you sure "bytes_per_scan_line" is sane? Given that none of the other variables are sane, I'd assume "bytes_per_scan_line" is also wrong.

Also note that for C, multiplying 2 large numbers together can easily give you the wrong answer due to undetected overflow. If "v->phys_base_ptr + (yr*v->bytes_per_scan_line)" is less than or equal to "v->phys_base_ptr"; then "(yr*v->bytes_per_scan_line)" must be less than or equal to zero, which definitely isn't right. Further, if "yr=65363" then "bytes_per_scan_line" must be either negative, zero, or larger than "INT_MAX / 65363".

I'm guessing you've got code somewhere that gets details for the selected video mode from a VESA/VBE "mode info" structure. I'd assume this code is entirely borked, and that there's possibly nothing wrong with the code to map video display memory into the virtual address space...


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.
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Re: Frame Buffer Mapping - Another thread

Post by piranha »

Hmm...yeah, thats the conclusion I came up with.

I have
struct vbemodeinfo *v;
v = (struct vbemodeinfo *)mboot_ptr->vbe_mode_info;
mboot_ptr is the multiboot pointer struct, which I'm assuming is OK, because other values from it seem to be correct.

Here is the structure...vbemodeinfo. After writing one myself, I borrowed this one from a linux driver. So it should work, right?

Code: Select all

	u16 mode_attr;
	u8  winA_attr;
	u8  winB_attr;
	u16 win_granularity;
	u16 win_size;
	u16 winA_seg;
	u16 winB_seg;
	u32 win_func_ptr;
	u16 bytes_per_scan_line;

	u16 x_res;
	u16 y_res;
	u8  x_char_size;
	u8  y_char_size;
	u8  planes;
	u8  bits_per_pixel;
	u8  banks;
	u8  memory_model;
	u8  bank_size;
	u8  image_pages;
	u8  reserved1;
	u8  red_len;
	u8  red_off;
	u8  green_len;
	u8  green_off;
	u8  blue_len;
	u8  blue_off;
	u8  rsvd_len;
	u8  rsvd_off;
	u8  direct_color_info;

	unsigned int phys_base_ptr;
	u8  reserved2[6];
Edit: Is there a specific place that the framebuffer is physically mapped to in Qemu?

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
Post Reply