This patch integrates the generic Linux loader with gfxterm.  The result is
that graphical mode becomes usable with this loader.  Our loader gets the
screen settings from the video subsystem (as per gfxterm setup), and passes
them to Linux.

This way GRUB/gfxterm can transition to Linux/fb with no further mode
setting.  Perhaps this can be exploited to make the transition seamless
by using the same background image in both places, but I haven't explored
this possibility yet :-)

Note: As the comment in grub/video.h says, struct grub_video_render_target
didn't really want to be moved.  My code only needs to access it to find
the framebuffer address.  Perhaps it'd be better to move this information
elsewhere?  Or split it in a separate structure / getter?

-- 
Robert Millan

  The DRM opt-in fallacy: "Your data belongs to us. We will decide when (and
  how) you may access your data; but nobody's threatening your freedom: we
  still allow you to remove your data and not access it at all."
2009-03-06  Robert Millan  <r...@aybabtu.com>

	* include/grub/i386/pc/vbe.h (struct grub_video_render_target): Move
	from here ...
	* include/grub/video.h (struct grub_video_render_target): ... to here.

	* loader/i386/linux.c: Inclue `<grub/video.h>'.
	(grub_linux_setup_video): New function.  Loosely based on the EFI one.
	(grub_rescue_cmd_linux): Attempt to configure video settings with
	grub_linux_setup_video().
	Set noreturn=0 in grub_loader_set, in order to avoid grub_console_fini()
	which would step out of graphical mode unconditionally.

Index: include/grub/i386/pc/vbe.h
===================================================================
--- include/grub/i386/pc/vbe.h	(revision 2019)
+++ include/grub/i386/pc/vbe.h	(working copy)
@@ -227,29 +227,6 @@ grub_err_t grub_vbe_get_video_mode_info 
 /* VBE module internal prototypes (should not be used from elsewhere).  */
 struct grub_video_i386_vbeblit_info;
 
-struct grub_video_render_target
-{
-  /* Copy of the screen's mode info structure, except that width, height and
-     mode_type has been re-adjusted to requested render target settings.  */
-  struct grub_video_mode_info mode_info;
-
-  struct
-  {
-    unsigned int x;
-    unsigned int y;
-    unsigned int width;
-    unsigned int height;
-  } viewport;
-
-  /* Indicates whether the data has been allocated by us and must be freed
-     when render target is destroyed.  */
-  int is_allocated;
-
-  /* Pointer to data.  Can either be in video card memory or in local host's
-     memory.  */
-  void *data;
-};
-
 grub_uint8_t * grub_video_vbe_get_video_ptr (struct grub_video_i386_vbeblit_info *source,
                                              grub_uint32_t x, grub_uint32_t y);
 
Index: include/grub/video.h
===================================================================
--- include/grub/video.h	(revision 2019)
+++ include/grub/video.h	(working copy)
@@ -26,10 +26,6 @@
    specific coding format.  */
 typedef grub_uint32_t grub_video_color_t;
 
-/* This structure is driver specific and should not be accessed directly by
-   outside code.  */
-struct grub_video_render_target;
-
 /* Forward declarations for used data structures.  */
 struct grub_video_bitmap;
 
@@ -152,6 +148,29 @@ struct grub_video_mode_info
   grub_uint8_t fg_alpha;
 };
 
+struct grub_video_render_target
+{
+  /* Copy of the screen's mode info structure, except that width, height and
+     mode_type has been re-adjusted to requested render target settings.  */
+  struct grub_video_mode_info mode_info;
+
+  struct
+  {
+    unsigned int x;
+    unsigned int y;
+    unsigned int width;
+    unsigned int height;
+  } viewport;
+
+  /* Indicates whether the data has been allocated by us and must be freed
+     when render target is destroyed.  */
+  int is_allocated;
+
+  /* Pointer to data.  Can either be in video card memory or in local host's
+     memory.  */
+  void *data;
+};
+
 struct grub_video_palette_data
 {
   grub_uint8_t r; /* Red color value (0-255).  */
Index: loader/i386/linux.c
===================================================================
--- loader/i386/linux.c	(revision 2019)
+++ loader/i386/linux.c	(working copy)
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008  Free Software Foundation, Inc.
+ *  Copyright (C) 2006,2007,2008,2009  Free Software Foundation, Inc.
  *
  *  GRUB is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
 #include <grub/mm.h>
 #include <grub/term.h>
 #include <grub/cpu/linux.h>
+#include <grub/video.h>
 
 #define GRUB_LINUX_CL_OFFSET		0x1000
 #define GRUB_LINUX_CL_END_OFFSET	0x2000
@@ -304,6 +304,41 @@ grub_linux_unload (void)
   return GRUB_ERR_NONE;
 }
 
+static int
+grub_linux_setup_video (struct linux_kernel_params *params)
+{
+  struct grub_video_mode_info mode_info;
+  struct grub_video_render_target *render_target;
+  int ret;
+
+  ret = grub_video_get_info (&mode_info);
+  if (ret)
+    return 1;
+
+  ret = grub_video_get_active_render_target (&render_target);
+  if (ret)
+    return 1;
+
+  params->lfb_width = mode_info.width;
+  params->lfb_height = mode_info.height;
+  params->lfb_depth = mode_info.bpp;
+  params->lfb_line_len = mode_info.pitch;
+
+  params->lfb_base = (void *) render_target->data;
+  params->lfb_size = (params->lfb_line_len * params->lfb_height + 65535) >> 16;
+
+  params->red_mask_size = 8;
+  params->red_field_pos = 16;
+  params->green_mask_size = 8;
+  params->green_field_pos = 8;
+  params->blue_mask_size = 8;
+  params->blue_field_pos = 0;
+  params->reserved_mask_size = 8;
+  params->reserved_field_pos = 24;
+
+  return 0;
+}
+
 void
 grub_rescue_cmd_linux (int argc, char *argv[])
 {
@@ -315,7 +350,6 @@ grub_rescue_cmd_linux (int argc, char *a
   grub_ssize_t len;
   int i;
   char *dest;
-  int video_type;
 
   grub_dl_ref (my_mod);
   
@@ -423,7 +457,6 @@ grub_rescue_cmd_linux (int argc, char *a
 
   /* Detect explicitly specified memory size, if any.  */
   linux_mem_size = 0;
-  video_type = 0;
   for (i = 1; i < argc; i++)
     if (grub_memcmp (argv[i], "mem=", 4) == 0)
       {
@@ -459,6 +492,9 @@ grub_rescue_cmd_linux (int argc, char *a
 	      linux_mem_size <<= shift;
 	  }
       }
+
+  if (! grub_linux_setup_video (params))
+    params->have_vga = GRUB_VIDEO_TYPE_VLFB;
   
   /* Specify the boot file.  */
   dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
@@ -482,7 +518,8 @@ grub_rescue_cmd_linux (int argc, char *a
 
   if (grub_errno == GRUB_ERR_NONE)
     {
-      grub_loader_set (grub_linux32_boot, grub_linux_unload, 1);
+      grub_loader_set (grub_linux32_boot, grub_linux_unload,
+		       0 /* set noreturn=0 in order to avoid grub_console_fini() */);
       loaded = 1;
     }
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to