From b09cf083a05470d39b9be891f359aa25d2f64f39 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 16 Sep 2010 00:30:47 +0200 Subject: [PATCH 1/3] Fix compilation issue --- grub-core/loader/i386/multiboot_mbi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index 4e6eca2e6..aa2c4a202 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -194,7 +194,7 @@ grub_multiboot_get_mbi_size (void) + 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 +#if GRUB_MACHINE_HAS_VBE + sizeof (struct grub_vbe_info_block) + sizeof (struct grub_vbe_mode_info_block) #endif @@ -243,7 +243,7 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry) grub_mmap_iterate (hook); } -#if HAS_VBE +#if GRUB_MACHINE_HAS_VBE static grub_err_t fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, grub_uint32_t ptrdest, int fill_generic) From 0b37526a5ab7dba0de1201af57bb174f9afe9348 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 16 Sep 2010 00:37:30 +0200 Subject: [PATCH 2/3] Add VBE PM interface --- grub-core/loader/i386/multiboot_mbi.c | 7 +++---- grub-core/video/i386/pc/vbe.c | 26 ++++++++++++++++++++++++++ include/grub/i386/pc/vbe.h | 3 +++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/grub-core/loader/i386/multiboot_mbi.c b/grub-core/loader/i386/multiboot_mbi.c index aa2c4a202..8411c7ec6 100644 --- a/grub-core/loader/i386/multiboot_mbi.c +++ b/grub-core/loader/i386/multiboot_mbi.c @@ -289,10 +289,9 @@ fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, 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; + grub_vbe_bios_get_pm_interface (&mbi->vbe_interface_seg, + &mbi->vbe_interface_off, + &mbi->vbe_interface_len); mbi->flags |= MULTIBOOT_INFO_VBE_INFO; diff --git a/grub-core/video/i386/pc/vbe.c b/grub-core/video/i386/pc/vbe.c index 4bb46e4cd..2ddb4ca80 100644 --- a/grub-core/video/i386/pc/vbe.c +++ b/grub-core/video/i386/pc/vbe.c @@ -248,6 +248,32 @@ grub_vbe_bios_get_display_start (grub_uint32_t *x, return regs.eax & 0xffff; } +/* Call VESA BIOS 0x4f0a. */ +grub_vbe_status_t +grub_vbe_bios_get_pm_interface (grub_uint16_t *segment, grub_uint16_t *offset, + grub_uint16_t *length) +{ + struct grub_bios_int_registers regs; + + regs.eax = 0x4f0a; + regs.ebx = 0x0000; + regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT; + grub_bios_interrupt (0x10, ®s); + + if ((regs.eax & 0xffff) != GRUB_VBE_STATUS_OK) + { + *segment = 0; + *offset = 0; + *length = 0; + } + + *segment = regs.es & 0xffff; + *offset = regs.edi & 0xffff; + *length = regs.ecx & 0xffff; + return regs.eax & 0xffff; +} + + grub_err_t grub_vbe_probe (struct grub_vbe_info_block *info_block) { diff --git a/include/grub/i386/pc/vbe.h b/include/grub/i386/pc/vbe.h index 9b05c2299..fba3ee642 100644 --- a/include/grub/i386/pc/vbe.h +++ b/include/grub/i386/pc/vbe.h @@ -209,6 +209,9 @@ grub_err_t grub_vbe_set_video_mode (grub_uint32_t mode, grub_err_t grub_vbe_get_video_mode (grub_uint32_t *mode); grub_err_t grub_vbe_get_video_mode_info (grub_uint32_t mode, struct grub_vbe_mode_info_block *mode_info); +grub_vbe_status_t +grub_vbe_bios_get_pm_interface (grub_uint16_t *seg, grub_uint16_t *offset, + grub_uint16_t *length); #endif /* ! GRUB_VBE_MACHINE_HEADER */ From f0eee6b26a2a34f0bbe3c8feaa8a0bd230df3039 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 16 Sep 2010 00:54:21 +0200 Subject: [PATCH 3/3] implement multiboot2 vbe specification --- grub-core/loader/multiboot_mbi2.c | 73 ++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 7 deletions(-) diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index f453dcc6a..05faf15e9 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -138,10 +138,10 @@ grub_multiboot_load (grub_file_t file) case MULTIBOOT_TAG_TYPE_BOOTDEV: case MULTIBOOT_TAG_TYPE_MMAP: case MULTIBOOT_TAG_TYPE_FRAMEBUFFER: - break; - case MULTIBOOT_TAG_TYPE_VBE: case MULTIBOOT_TAG_TYPE_ELF_SECTIONS: + break; + case MULTIBOOT_TAG_TYPE_APM: default: grub_free (buffer); @@ -273,12 +273,13 @@ grub_multiboot_get_mbi_size (void) + (sizeof (struct multiboot_tag_string) + ALIGN_UP (sizeof (PACKAGE_STRING), MULTIBOOT_TAG_ALIGN)) + (modcnt * sizeof (struct multiboot_tag_module) + total_modcmd) - + sizeof (struct multiboot_tag_basic_meminfo) + + ALIGN_UP (sizeof (struct multiboot_tag_basic_meminfo), MULTIBOOT_TAG_ALIGN) + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN) - + sizeof (struct multiboot_tag_elf_sections) - + elf_sec_entsize * elf_sec_num - + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count () - * sizeof (struct multiboot_mmap_entry)) + + ALIGN_UP (sizeof (struct multiboot_tag_elf_sections), MULTIBOOT_TAG_ALIGN) + + ALIGN_UP (elf_sec_entsize * elf_sec_num, MULTIBOOT_TAG_ALIGN) + + ALIGN_UP ((sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count () + * sizeof (struct multiboot_mmap_entry)), MULTIBOOT_TAG_ALIGN) + + ALIGN_UP (sizeof (struct multiboot_tag_framebuffer), MULTIBOOT_TAG_ALIGN) + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1; } @@ -329,6 +330,54 @@ grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag) grub_mmap_iterate (hook); } +#if defined (GRUB_MACHINE_PCBIOS) +static void +fill_vbe_tag (struct multiboot_tag_vbe *tag) +{ + grub_vbe_status_t status; + void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; + + tag->type = MULTIBOOT_TAG_TYPE_VBE; + tag->size = 0; + + status = grub_vbe_bios_get_controller_info (scratch); + if (status != GRUB_VBE_STATUS_OK) + return; + + grub_memcpy (&tag->vbe_control_info, scratch, + sizeof (struct grub_vbe_info_block)); + + status = grub_vbe_bios_get_mode (scratch); + tag->vbe_mode = *(grub_uint32_t *) scratch; + if (status != GRUB_VBE_STATUS_OK) + return; + + /* get_mode_info isn't available for mode 3. */ + if (tag->vbe_mode == 3) + { + struct grub_vbe_mode_info_block *mode_info = (void *) &tag->vbe_mode_info; + 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 (tag->vbe_mode, scratch); + if (status != GRUB_VBE_STATUS_OK) + return; + grub_memcpy (&tag->vbe_mode_info, scratch, + sizeof (struct grub_vbe_mode_info_block)); + } + grub_vbe_bios_get_pm_interface (&tag->vbe_interface_seg, + &tag->vbe_interface_off, + &tag->vbe_interface_len); + + tag->size = sizeof (*tag); +} +#endif + static grub_err_t retrieve_video_parameters (grub_uint8_t **ptrorig) { @@ -417,6 +466,16 @@ retrieve_video_parameters (grub_uint8_t **ptrorig) return GRUB_ERR_NONE; #endif +#if GRUB_MACHINE_HAS_VBE + { + struct multiboot_tag_vbe *tag_vbe = (struct multiboot_tag_vbe *) *ptrorig; + + fill_vbe_tag (tag_vbe); + + *ptrorig += ALIGN_UP (tag_vbe->size, MULTIBOOT_TAG_ALIGN); + } +#endif + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); if (err) return err;