grub vbeset : put pixel bad result

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
SamyPesse
Posts: 17
Joined: Mon Apr 13, 2009 2:56 pm
Location: France

grub vbeset : put pixel bad result

Post by SamyPesse »

Hello everybody ;)
when i want to use vesa video mode, i let grub set the mode for me with stage2_eltorino and vbeset :

Code: Select all

default=0
timeout=30
	title=MyOS : free and Open Source OS
	kernel /kernel.bin -disk 0 -part 0 -init C:/sys/bin/shell -b
	vbeset 771
	boot
i get :
http://myos.redby.fr/image/vbe.png

normally with vga12h mode, i get :
http://myos.redby.fr/image/novbe.png

this my code for vesa and grub, :
I dont know where is the probleme !!

Code: Select all


static int lfb_px = 0;

static int lfb_py = 0;



static ULONG lfb_width  = 0;

static ULONG lfb_height = 0;

static ULONG lfb_depth  = 0;

static ULONG lfb_type 	= 0;



void lfb_clear()

{

	memset((char*)lfb,15,lfb_width*lfb_height*lfb_depth);

}




void init_lfb(struct multiboot_info *multiboot )

{

	struct vbe_mode *mode_info;

	void *lfb_ptr;



	lfb_px = 0;

	lfb_py = 0;



	if ( (multiboot->flags & (1<<11)) == 0 )

	{

	    lfb_width  = 0;

	    lfb_height = 0;

	    lfb_depth = 0;

	    lfb_type = 0;

	    lfb_ptr = 0;

		printk("\n Video mode : VGA 12h\n");

	}

	else

	{

		setVideoMode(MODEVBE);

	    mode_info = (struct vbe_mode*) multiboot->vbe_mode_info;

	    lfb_width  = mode_info->x_resolution;

	    lfb_height = mode_info->y_resolution;

	    lfb_depth = mode_info->bits_per_pixel;

	    lfb_type = 0;

	    lfb_ptr = (void*)mode_info->phys_base;

		lfb = (unsigned char*)lfb_ptr;

		printk("\n Video mode : VESA grub\n");

	}

	

//	set_lfb( lfb_width, lfb_height, lfb_depth, lfb_type, lfb_ptr );

}



#define PIXEL_POINTEUR(x,y) ((char*)(lfb+x \

 +((unsigned short int)y*(unsigned short int)lfb_width)))



void putpixel_vbe(ULONG x, ULONG y, ULONG col) {

	*PIXEL_POINTEUR(x,y)=(char)col;

}
and the vbe mode struct :

Code: Select all


/* VBE mode information.  */

struct vbe_mode

{

  unsigned short mode_attributes;

  unsigned char win_a_attributes;

  unsigned char win_b_attributes;

  unsigned short win_granularity;

  unsigned short win_size;

  unsigned short win_a_segment;

  unsigned short win_b_segment;

  unsigned long win_func;

  unsigned short bytes_per_scanline;



  /* >=1.2 */

  unsigned short x_resolution;

  unsigned short y_resolution;

  unsigned char x_char_size;

  unsigned char y_char_size;

  unsigned char number_of_planes;

  unsigned char bits_per_pixel;

  unsigned char number_of_banks;

  unsigned char memory_model;

  unsigned char bank_size;

  unsigned char number_of_image_pages;

  unsigned char reserved0;



  /* direct color */

  unsigned char red_mask_size;

  unsigned char red_field_position;

  unsigned char green_mask_size;

  unsigned char green_field_position;

  unsigned char blue_mask_size;

  unsigned char blue_field_position;

  unsigned char reserved_mask_size;

  unsigned char reserved_field_position;

  unsigned char direct_color_mode_info;



  /* >=2.0 */

  unsigned long phys_base;

  unsigned long reserved1;

  unsigned short reversed2;



  /* >=3.0 */

  unsigned short linear_bytes_per_scanline;

  unsigned char banked_number_of_image_pages;

  unsigned char linear_number_of_image_pages;

  unsigned char linear_red_mask_size;

  unsigned char linear_red_field_position;

  unsigned char linear_green_mask_size;

  unsigned char linear_green_field_position;

  unsigned char linear_blue_mask_size;

  unsigned char linear_blue_field_position;

  unsigned char linear_reserved_mask_size;

  unsigned char linear_reserved_field_position;

  unsigned long max_pixel_clock;



  unsigned char reserved3[189];

} __attribute__ ((packed));

User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: grub vbeset : put pixel bad result

Post by Combuster »

For starters, your code is not taking care of various bit depths.

Also, what is the exact mode you are setting?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
SamyPesse
Posts: 17
Joined: Mon Apr 13, 2009 2:56 pm
Location: France

Re: grub vbeset : put pixel bad result

Post by SamyPesse »

i want to use the mode : 792 (1024x728 and 24 bits per pixel)
xyzzy
Member
Member
Posts: 391
Joined: Wed Jul 25, 2007 8:45 am
Libera.chat IRC: aejsmith
Location: London, UK
Contact:

Re: grub vbeset : put pixel bad result

Post by xyzzy »

The VBE mode number for that mode is 280 (0x118), not 792. I'd guess you got that number from Linux - IIRC its mode numbers are <VESA mode number> + 0x200, which would give what you're using.
SamyPesse
Posts: 17
Joined: Mon Apr 13, 2009 2:56 pm
Location: France

Re: grub vbeset : put pixel bad result

Post by SamyPesse »

euh the mode 792 give me the correct result with qemu : a windows of 1024x728
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: grub vbeset : put pixel bad result

Post by Brendan »

Hi,
SamyPesse wrote:i want to use the mode : 792 (1024x728 and 24 bits per pixel)
Some video cards don't support 24 bits per pixel at all, some video cards don't support 1024*768 at all, and some do support "1024*768 * 24-bpp" but don't support VBE. AFAIK in all of these cases, GRUB will fail to set "1024*768 * 24-bpp" and will leave you in text mode.

If the video card does support "1024*768 * 24-bpp", there's no guarantee that the monitor will support it. In this case GRUB will set the video mode but the user won't be able to see anything on the screen after that (and some ancient "VGA only" video cards will blow up).

IMHO there's only 3 sane choices:
  • Use a video mode that every video card and monitor supports (e.g. 640 * 480 * 4 bits per pixel, or text mode)
  • Force the end-user to tell GRUB which video mode to use, so that they can use a video mode that their hardware actually does support. IMHO this idea isn't very user-friendly. For example, if you're using the "mode_type", "width", "height" and "depth" fields in the multi-boot header, then the end user needs to create a customized version of your kernel before using it (which is a pain in the neck for end-users). It also doesn't work in some situations (e.g. a live CD where the person who makes the CD doesn't know which computers it'll be booted on). It also means that the OS has to support every possible video mode (including strange/rare video modes), because it has no control over which video mode the user might select.
  • Switch back to real mode, then create a list of video modes that the video card and OS (and monitor?) do support, then choose a video mode from this list during boot. In this case GRUB's video support isn't used at all (and your OS doesn't require a special patched GRUB, which means people who are already using an unpatched GRUB to boot an existing OS can continue using the version of GRUB they've already installed to dual boot their existing OS and your OS). In this case, the OS could automatically choose any video mode, and could let the user set preferences (e.g. with a pretty menu system or with kernel parameters) where the OS searches the list of usable video modes and finds the video mode that most closely matches the requested resolution and colour depth (and refresh rate?). Unfortunately this is complex and GRUB just makes things worse. For example, you'd need to copy some code below 0x00100000 (as you can't run real mode code above 0x00100000), and you'd need to make sure you don't trash anything that could be the area below 0x00100000 (e.g. the multiboot information data structure).
Mostly, the video support in GRUB (or more correctly, the multi-boot specification) isn't adequate...

It does make me wonder how GRUB 2 will handle video though. Ideally, the multi-boot header should contain a complete description of which video modes the OS does/doesn't support (possibly including ranges - e.g. "this OS supports all video modes from 640 * 480 to 1600 * 1200, but not resolutions that are outside this range, and not any 4-bit per pixel video modes"); so that GRUB 2 can create a list of video modes that the video card and OS (and monitor?) do support and choose a video mode for the OS intelligently (including taking user preferences into account). In addition, the boot loader should display an error message if no suitable video mode is found, rather than using text mode as a fallback (so that an OS that requires graphics mode doesn't have to support text mode). Unfortunately, as far as I can tell GRUB 2 is intending to use the original multi-boot specification, so it won't be any better at mis-handling video... :)


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