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