]> git.proxmox.com Git - grub2.git/commitdiff
implement multiboot2 vbe specification
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 15 Sep 2010 22:54:21 +0000 (00:54 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Wed, 15 Sep 2010 22:54:21 +0000 (00:54 +0200)
grub-core/loader/multiboot_mbi2.c

index f453dcc6a422c106f2f54c02ed7011c59b5fb30a..05faf15e92bb22fb459815a9171ede236a2bc5d8 100644 (file)
@@ -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;