From: Vladimir 'phcoder' Serbinenko Date: Wed, 15 Sep 2010 22:22:49 +0000 (+0200) Subject: Merge mainline into mbivid X-Git-Tag: 1.99~460^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ba27423f56d0c80383a352720fb215cb5bb4e8c;p=thirdparty%2Fgrub.git Merge mainline into mbivid --- 9ba27423f56d0c80383a352720fb215cb5bb4e8c diff --cc grub-core/commands/handler.c index f9270972b,000000000..f9270972b mode 100644,000000..100644 --- a/grub-core/commands/handler.c +++ b/grub-core/commands/handler.c diff --cc grub-core/commands/i386/pc/vbeinfo.c index c266bbfcb,000000000..c266bbfcb mode 100644,000000..100644 --- a/grub-core/commands/i386/pc/vbeinfo.c +++ b/grub-core/commands/i386/pc/vbeinfo.c diff --cc grub-core/commands/i386/pc/vbetest.c index d97323087,000000000..d97323087 mode 100644,000000..100644 --- a/grub-core/commands/i386/pc/vbetest.c +++ b/grub-core/commands/i386/pc/vbetest.c diff --cc grub-core/efiemu/runtime/efiemu.sh index 5a492dc2f,000000000..5a492dc2f mode 100644,000000..100644 --- a/grub-core/efiemu/runtime/efiemu.sh +++ b/grub-core/efiemu/runtime/efiemu.sh diff --cc grub-core/kern/handler.c index 2bf85313c,000000000..2bf85313c mode 100644,000000..100644 --- a/grub-core/kern/handler.c +++ b/grub-core/kern/handler.c diff --cc grub-core/kern/i386/ieee1275/init.c index 7658ee1a7,000000000..7658ee1a7 mode 100644,000000..100644 --- a/grub-core/kern/i386/ieee1275/init.c +++ b/grub-core/kern/i386/ieee1275/init.c diff --cc grub-core/kern/i386/loader.S index ed57c43ca,000000000..ed57c43ca mode 100644,000000..100644 --- a/grub-core/kern/i386/loader.S +++ b/grub-core/kern/i386/loader.S diff --cc grub-core/kern/i386/misc.S index 7d57df9b9,000000000..7d57df9b9 mode 100644,000000..100644 --- a/grub-core/kern/i386/misc.S +++ b/grub-core/kern/i386/misc.S diff --cc grub-core/loader/i386/bsd_helper.S index 25aee3a80,000000000..25aee3a80 mode 100644,000000..100644 --- a/grub-core/loader/i386/bsd_helper.S +++ b/grub-core/loader/i386/bsd_helper.S diff --cc grub-core/loader/i386/bsd_trampoline.S index a568fff4d,000000000..a568fff4d mode 100644,000000..100644 --- a/grub-core/loader/i386/bsd_trampoline.S +++ b/grub-core/loader/i386/bsd_trampoline.S diff --cc grub-core/loader/i386/efi/linux.c index 1abcc06db,000000000..1abcc06db mode 100644,000000..100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c diff --cc grub-core/loader/i386/efi/xnu.c index a7ede1960,000000000..a7ede1960 mode 100644,000000..100644 --- a/grub-core/loader/i386/efi/xnu.c +++ b/grub-core/loader/i386/efi/xnu.c diff --cc grub-core/loader/i386/ieee1275/linux.c index 8780804fd,000000000..8780804fd mode 100644,000000..100644 --- a/grub-core/loader/i386/ieee1275/linux.c +++ b/grub-core/loader/i386/ieee1275/linux.c diff --cc grub-core/loader/i386/linux_trampoline.S index 4acea7b11,000000000..4acea7b11 mode 100644,000000..100644 --- a/grub-core/loader/i386/linux_trampoline.S +++ b/grub-core/loader/i386/linux_trampoline.S diff --cc grub-core/loader/i386/multiboot_mbi.c index ddbbf3cfd,bf17863cf..4e6eca2e6 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@@ -92,11 -191,9 +191,13 @@@ grub_multiboot_get_mbi_size (void { return sizeof (struct multiboot_info) + ALIGN_UP (cmdline_size, 4) + modcnt * sizeof (struct multiboot_mod_list) + total_modcmd - + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + grub_get_multiboot_mmap_len () + + ALIGN_UP (sizeof(PACKAGE_STRING), 4) + + grub_get_multiboot_mmap_count () * sizeof (struct multiboot_mmap_entry) + + elf_sec_entsize * elf_sec_num +#if HAS_VBE + + sizeof (struct grub_vbe_info_block) + + sizeof (struct grub_vbe_mode_info_block) +#endif + 256 * sizeof (struct multiboot_color); } @@@ -130,107 -239,6 +243,78 @@@ grub_fill_multiboot_mmap (struct multib grub_mmap_iterate (hook); } - static grub_err_t - set_video_mode (void) - { - grub_err_t err; - const char *modevar; - - if (accepts_video || !HAS_VGA_TEXT) - { - modevar = grub_env_get ("gfxpayload"); - if (! modevar || *modevar == 0) - err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0); - else - { - char *tmp; - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (DEFAULT_VIDEO_MODE) + 1); - if (! tmp) - return grub_errno; - grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); - err = grub_video_set_mode (tmp, 0); - grub_free (tmp); - } - } - else - err = grub_video_set_mode ("text", 0); - - return err; - } - +#if HAS_VBE +static grub_err_t +fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, + grub_uint32_t ptrdest, int fill_generic) +{ + grub_vbe_status_t status; + grub_uint32_t vbe_mode; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + struct grub_vbe_mode_info_block *mode_info; + + status = grub_vbe_bios_get_controller_info (scratch); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "Can't get controller info."); + + mbi->vbe_control_info = ptrdest; + grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_info_block)); + ptrorig += sizeof (struct grub_vbe_info_block); + ptrdest += sizeof (struct grub_vbe_info_block); + + status = grub_vbe_bios_get_mode (scratch); + vbe_mode = *(grub_uint32_t *) scratch; + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "can't get VBE mode"); + mbi->vbe_mode = vbe_mode; + + mode_info = (struct grub_vbe_mode_info_block *) ptrorig; + mbi->vbe_mode_info = ptrdest; + /* get_mode_info isn't available for mode 3. */ + if (vbe_mode == 3) + { + grub_memset (mode_info, 0, sizeof (struct grub_vbe_mode_info_block)); + mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; + mode_info->x_resolution = 80; + mode_info->y_resolution = 25; + } + else + { + status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); + if (status != GRUB_VBE_STATUS_OK) + return grub_error (GRUB_ERR_IO, "can't get mode info"); + grub_memcpy (mode_info, scratch, + sizeof (struct grub_vbe_mode_info_block)); + } + ptrorig += sizeof (struct grub_vbe_mode_info_block); + ptrdest += sizeof (struct grub_vbe_mode_info_block); + + /* FIXME: retrieve those. */ + mbi->vbe_interface_seg = 0; + mbi->vbe_interface_off = 0; + mbi->vbe_interface_len = 0; + + mbi->flags |= MULTIBOOT_INFO_VBE_INFO; + + if (fill_generic && mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) + { + mbi->framebuffer_addr = 0xb8000; + + mbi->framebuffer_pitch = 2 * mode_info->x_resolution; + mbi->framebuffer_width = mode_info->x_resolution; + mbi->framebuffer_height = mode_info->y_resolution; + + mbi->framebuffer_bpp = 16; + + mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; + + mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; + } + + return GRUB_ERR_NONE; +} +#endif + static grub_err_t retrieve_video_parameters (struct multiboot_info *mbi, grub_uint8_t *ptrorig, grub_uint32_t ptrdest) @@@ -251,13 -259,8 +335,13 @@@ grub_video_get_palette (0, ARRAY_SIZE (palette), palette); driv_id = grub_video_get_driver_id (); - #if HAS_VGA_TEXT ++#if GRUB_MACHINE_HAS_VGA_TEXT + if (driv_id == GRUB_VIDEO_DRIVER_NONE) + return fill_vbe_info (mbi, ptrorig, ptrdest, 1); +#else if (driv_id == GRUB_VIDEO_DRIVER_NONE) return GRUB_ERR_NONE; +#endif err = grub_video_get_info_and_fini (&mode_info, &framebuffer); if (err) @@@ -305,11 -308,6 +389,11 @@@ mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; - #if HAS_VBE ++#if GRUB_MACHINE_HAS_VBE + if (driv_id == GRUB_VIDEO_DRIVER_VBE) + return fill_vbe_info (mbi, ptrorig, ptrdest, 0); +#endif + return GRUB_ERR_NONE; } @@@ -396,12 -418,6 +504,12 @@@ grub_multiboot_make_mbi (grub_uint32_t grub_print_error (); grub_errno = GRUB_ERR_NONE; } - #if HAS_VBE ++#if GRUB_MACHINE_HAS_VBE + ptrorig += sizeof (struct grub_vbe_info_block); + ptrdest += sizeof (struct grub_vbe_info_block); + ptrorig += sizeof (struct grub_vbe_mode_info_block); + ptrdest += sizeof (struct grub_vbe_mode_info_block); +#endif return GRUB_ERR_NONE; } diff --cc grub-core/loader/i386/pc/xnu.c index ebb176bb4,000000000..ebb176bb4 mode 100644,000000..100644 --- a/grub-core/loader/i386/pc/xnu.c +++ b/grub-core/loader/i386/pc/xnu.c diff --cc grub-core/loader/multiboot.c index 000000000,8780ec061..a6fa4b79c mode 000000,100644..100644 --- a/grub-core/loader/multiboot.c +++ b/grub-core/loader/multiboot.c @@@ -1,0 -1,358 +1,356 @@@ + /* multiboot.c - boot a multiboot OS image. */ + /* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + + /* + * FIXME: The following features from the Multiboot specification still + * need to be implemented: - * - VBE support - * - symbol table + * - drives table + * - ROM configuration table + * - APM table + */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #ifdef GRUB_MACHINE_EFI + #include + #endif + + struct grub_relocator *grub_multiboot_relocator = NULL; + grub_uint32_t grub_multiboot_payload_eip; + #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) + #define DEFAULT_VIDEO_MODE "text" + #else + #define DEFAULT_VIDEO_MODE "auto" + #endif + + static int accepts_video; + static int accepts_ega_text; + static int console_required; + static grub_dl_t my_mod; + + + /* Return the length of the Multiboot mmap that will be needed to allocate + our platform's map. */ + grub_uint32_t + grub_get_multiboot_mmap_count (void) + { + grub_size_t count = 0; + + auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); + int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + grub_uint32_t type __attribute__ ((unused))) + { + count++; + return 0; + } + + grub_mmap_iterate (hook); + + return count; + } + + grub_err_t + grub_multiboot_set_video_mode (void) + { + grub_err_t err; + const char *modevar; + + if (accepts_video || !GRUB_MACHINE_HAS_VGA_TEXT) + { + modevar = grub_env_get ("gfxpayload"); + if (! modevar || *modevar == 0) + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); + else + { + char *tmp; + tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); + if (! tmp) + return grub_errno; + err = grub_video_set_mode (tmp, 0, 0); + grub_free (tmp); + } + } + else + err = grub_video_set_mode ("text", 0, 0); + + return err; + } + + static grub_err_t + grub_multiboot_boot (void) + { + grub_err_t err; + struct grub_relocator32_state state = MULTIBOOT_INITIAL_STATE; + + state.MULTIBOOT_ENTRY_REGISTER = grub_multiboot_payload_eip; + + err = grub_multiboot_make_mbi (&state.MULTIBOOT_MBI_REGISTER); + + if (err) + return err; + + #ifdef GRUB_MACHINE_EFI + err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL); + if (err) + return err; + #endif + + grub_relocator32_boot (grub_multiboot_relocator, state); + + /* Not reached. */ + return GRUB_ERR_NONE; + } + + static grub_err_t + grub_multiboot_unload (void) + { + grub_multiboot_free_mbi (); + + grub_relocator_unload (grub_multiboot_relocator); + grub_multiboot_relocator = NULL; + + grub_dl_unref (my_mod); + + return GRUB_ERR_NONE; + } + + #define MULTIBOOT_LOAD_ELF64 + #include "multiboot_elfxx.c" + #undef MULTIBOOT_LOAD_ELF64 + + #define MULTIBOOT_LOAD_ELF32 + #include "multiboot_elfxx.c" + #undef MULTIBOOT_LOAD_ELF32 + + /* Load ELF32 or ELF64. */ + grub_err_t + grub_multiboot_load_elf (grub_file_t file, void *buffer) + { + if (grub_multiboot_is_elf32 (buffer)) + return grub_multiboot_load_elf32 (file, buffer); + else if (grub_multiboot_is_elf64 (buffer)) + return grub_multiboot_load_elf64 (file, buffer); + + return grub_error (GRUB_ERR_UNKNOWN_OS, "unknown ELF class"); + } + + grub_err_t + grub_multiboot_set_console (int console_type, int accepted_consoles, + int width, int height, int depth, + int console_req) + { + console_required = console_req; + if (!(accepted_consoles + & (GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER + | (GRUB_MACHINE_HAS_VGA_TEXT ? GRUB_MULTIBOOT_CONSOLE_EGA_TEXT : 0)))) + { + if (console_required) + return grub_error (GRUB_ERR_BAD_OS, + "OS requires a console but none is available"); + grub_printf ("WARNING: no console will be available to OS"); + accepts_video = 0; + accepts_ega_text = 0; + return GRUB_ERR_NONE; + } + + if (console_type == GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER) + { + char *buf; + if (depth && width && height) + buf = grub_xasprintf ("%dx%dx%d,%dx%d,auto", width, + height, depth, width, height); + else if (width && height) + buf = grub_xasprintf ("%dx%d,auto", width, height); + else + buf = grub_strdup ("auto"); + + if (!buf) + return grub_errno; + grub_env_set ("gfxpayload", buf); + grub_free (buf); + } + else + grub_env_set ("gfxpayload", "text"); + + accepts_video = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER); + accepts_ega_text = !!(accepted_consoles & GRUB_MULTIBOOT_CONSOLE_EGA_TEXT); + return GRUB_ERR_NONE; + } + + static grub_err_t + grub_cmd_multiboot (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { + grub_file_t file = 0; + grub_err_t err; + + grub_loader_unset (); + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); + + file = grub_file_open (argv[0]); + if (! file) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file"); + + grub_dl_ref (my_mod); + + /* Skip filename. */ + grub_multiboot_init_mbi (argc - 1, argv + 1); + + grub_relocator_unload (grub_multiboot_relocator); + grub_multiboot_relocator = grub_relocator_new (); + + if (!grub_multiboot_relocator) + goto fail; + + err = grub_multiboot_load (file); + if (err) + goto fail; + + grub_multiboot_set_bootdev (); + + grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0); + + fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_relocator_unload (grub_multiboot_relocator); + grub_multiboot_relocator = NULL; + grub_dl_unref (my_mod); + } + + return grub_errno; + } + + static grub_err_t + grub_cmd_module (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { + grub_file_t file = 0; + grub_ssize_t size; + void *module = NULL; + grub_addr_t target; + grub_err_t err; + int nounzip = 0; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); + + if (grub_strcmp (argv[0], "--nounzip") == 0) + { + argv++; + argc--; + nounzip = 1; + } + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); + + if (!grub_multiboot_relocator) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "you need to load the multiboot kernel first"); + + if (nounzip) + grub_file_filter_disable_compression (); + + file = grub_file_open (argv[0]); + if (! file) + return grub_errno; + + size = grub_file_size (file); + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch, + 0, (0xffffffff - size) + 1, + size, MULTIBOOT_MOD_ALIGN, + GRUB_RELOCATOR_PREFERENCE_NONE); + if (err) + { + grub_file_close (file); + return err; + } + module = get_virtual_current_address (ch); + target = (grub_addr_t) get_virtual_current_address (ch); + } + + err = grub_multiboot_add_module (target, size, argc - 1, argv + 1); + if (err) + { + grub_file_close (file); + return err; + } + + if (grub_file_read (file, module, size) != size) + { + grub_file_close (file); + return grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); + } + + grub_file_close (file); + return GRUB_ERR_NONE;; + } + + static grub_command_t cmd_multiboot, cmd_module; + + GRUB_MOD_INIT(multiboot) + { + cmd_multiboot = + #ifdef GRUB_USE_MULTIBOOT2 + grub_register_command ("multiboot2", grub_cmd_multiboot, + 0, N_("Load a multiboot 2 kernel.")); + cmd_module = + grub_register_command ("module2", grub_cmd_module, + 0, N_("Load a multiboot 2 module.")); + #else + grub_register_command ("multiboot", grub_cmd_multiboot, + 0, N_("Load a multiboot kernel.")); + cmd_module = + grub_register_command ("module", grub_cmd_module, + 0, N_("Load a multiboot module.")); + #endif + + my_mod = mod; + } + + GRUB_MOD_FINI(multiboot) + { + grub_unregister_command (cmd_multiboot); + grub_unregister_command (cmd_module); + } diff --cc grub-core/loader/multiboot_loader.c index 6d042fa81,000000000..6d042fa81 mode 100644,000000..100644 --- a/grub-core/loader/multiboot_loader.c +++ b/grub-core/loader/multiboot_loader.c diff --cc grub-core/normal/handler.c index b44dc7a68,000000000..b44dc7a68 mode 100644,000000..100644 --- a/grub-core/normal/handler.c +++ b/grub-core/normal/handler.c diff --cc grub-core/term/i386/pc/vesafb.c index 52694ed10,000000000..52694ed10 mode 100644,000000..100644 --- a/grub-core/term/i386/pc/vesafb.c +++ b/grub-core/term/i386/pc/vesafb.c diff --cc include/grub/multiboot.h index 665292e33,cbc58b2ee..92837d7d2 --- a/include/grub/multiboot.h +++ b/include/grub/multiboot.h @@@ -45,6 -46,35 +46,37 @@@ grub_err_t grub_multiboot_init_mbi (in grub_err_t grub_multiboot_add_module (grub_addr_t start, grub_size_t size, int argc, char *argv[]); void grub_multiboot_set_bootdev (void); + void + grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize, + unsigned shndx, void *data); + + grub_uint32_t grub_get_multiboot_mmap_count (void); + grub_err_t grub_multiboot_set_video_mode (void); + + #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_QEMU) + #include + #define GRUB_MACHINE_HAS_VGA_TEXT 1 ++#define GRUB_MACHINE_HAS_VBE 1 + #else + #define GRUB_MACHINE_HAS_VGA_TEXT 0 ++#define GRUB_MACHINE_HAS_VBE 0 + #endif + + #define GRUB_MULTIBOOT_CONSOLE_EGA_TEXT 1 + #define GRUB_MULTIBOOT_CONSOLE_FRAMEBUFFER 2 + + grub_err_t + grub_multiboot_set_console (int console_type, int accepted_consoles, + int width, int height, int depth, + int console_required); + grub_err_t + grub_multiboot_load (grub_file_t file); + /* Load ELF32 or ELF64. */ + grub_err_t + grub_multiboot_load_elf (grub_file_t file, void *buffer); + extern grub_size_t grub_multiboot_pure_size; + extern grub_size_t grub_multiboot_alloc_mbi; + extern grub_uint32_t grub_multiboot_payload_eip; #endif /* ! GRUB_MULTIBOOT_HEADER */