2009-03-06 Robert Millan * 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_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 #include #include +#include #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; }