]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Update with newest mbtag spec
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 7 Mar 2010 13:59:15 +0000 (14:59 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 7 Mar 2010 13:59:15 +0000 (14:59 +0100)
include/grub/multiboot.h
include/multiboot2.h
loader/i386/multiboot.c
loader/i386/multiboot_mbi.c
loader/i386/multiboot_mbi2.c

index 27d4d816d7c05137da43f87fda6f72a86102b249..c108e5eef87ed09485a19d90ba4032a5c6358554 100644 (file)
@@ -44,7 +44,7 @@ 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);
 
-grub_uint32_t grub_get_multiboot_mmap_len (void);
+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_QEMU)
index 20c5c5696ac5676266c8e24a7e0130b4cfc97a34..36710ddf6710334f37bfec9376622a049cf46a84 100644 (file)
@@ -51,6 +51,7 @@
 /* This flag indicates the use of the address fields in the header.  */
 #define MULTIBOOT_AOUT_KLUDGE                  0x00010000
 
+#define MULTIBOOT_TAG_ALIGN                  8
 #define MULTIBOOT_TAG_TYPE_END               0
 #define MULTIBOOT_TAG_TYPE_CMDLINE           1
 #define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME  2
@@ -102,7 +103,6 @@ struct multiboot_color
 
 struct multiboot_mmap_entry
 {
-  multiboot_uint32_t size;
   multiboot_uint64_t addr;
   multiboot_uint64_t len;
 #define MULTIBOOT_MEMORY_AVAILABLE             1
@@ -110,6 +110,7 @@ struct multiboot_mmap_entry
 #define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE       3
 #define MULTIBOOT_MEMORY_NVS                    4
   multiboot_uint32_t type;
+  multiboot_uint32_t zero;
 } __attribute__((packed));
 typedef struct multiboot_mmap_entry multiboot_memory_map_t;
 
@@ -123,6 +124,8 @@ struct multiboot_tag_string
 {
   multiboot_uint32_t type;
   multiboot_uint32_t size;
+  multiboot_uint32_t entry_size;
+  multiboot_uint32_t entry_version;
   char string[0];
 };
 
@@ -156,6 +159,8 @@ struct multiboot_tag_mmap
 {
   multiboot_uint32_t type;
   multiboot_uint32_t size;
+  multiboot_uint32_t entry_size;
+  multiboot_uint32_t entry_version;
   struct multiboot_mmap_entry entries[0];  
 };
 
@@ -197,6 +202,7 @@ struct multiboot_tag_framebuffer_common
 #define MULTIBOOT_FRAMEBUFFER_TYPE_RGB     1
 #define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT    2
   multiboot_uint8_t framebuffer_type;
+  multiboot_uint16_t reserved;
 };
 
 struct multiboot_tag_framebuffer
@@ -222,6 +228,31 @@ struct multiboot_tag_framebuffer
   };
 };
 
+struct multiboot_tag_elf_sections
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  multiboot_uint32_t num;
+  multiboot_uint32_t entsize;
+  multiboot_uint32_t shndx;
+  char sections[0];
+};
+
+struct multiboot_tag_apm
+{
+  multiboot_uint32_t type;
+  multiboot_uint32_t size;
+  multiboot_uint16_t version;
+  multiboot_uint16_t cseg;
+  multiboot_uint32_t offset;
+  multiboot_uint16_t cseg_16;
+  multiboot_uint16_t dseg;
+  multiboot_uint16_t flags;
+  multiboot_uint16_t cseg_len;
+  multiboot_uint16_t cseg_16_len;
+  multiboot_uint16_t dseg_len;
+};
+
 #endif /* ! ASM_FILE */
 
 #endif /* ! MULTIBOOT_HEADER */
index 5f9751f332a1567abfedf6ad054d695717cb1c73..dab81dc8c37ab87e605ba0ad9674af75c9427028 100644 (file)
@@ -68,7 +68,7 @@ static int accepts_video;
 /* Return the length of the Multiboot mmap that will be needed to allocate
    our platform's map.  */
 grub_uint32_t
-grub_get_multiboot_mmap_len (void)
+grub_get_multiboot_mmap_count (void)
 {
   grub_size_t count = 0;
 
@@ -83,7 +83,7 @@ grub_get_multiboot_mmap_len (void)
 
   grub_mmap_iterate (hook);
 
-  return count * sizeof (struct multiboot_mmap_entry);
+  return count;
 }
 
 grub_err_t
index a8133a705e36f0cf57704b129db5178468fab586..0d5db3c1352a5261adb4b306692e717d7f51d0e3 100644 (file)
@@ -53,7 +53,8 @@ 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)
 #if GRUB_MACHINE_HAS_VBE
     + sizeof (struct grub_vbe_info_block)
     + sizeof (struct grub_vbe_mode_info_block)
@@ -233,7 +234,8 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
       mbi->mods_count = 0;
     }
 
-  mmap_size = grub_get_multiboot_mmap_len (); 
+  mmap_size = grub_get_multiboot_mmap_count () 
+    * sizeof (struct multiboot_mmap_entry);
   grub_fill_multiboot_mmap ((struct multiboot_mmap_entry *) ptrorig);
   mbi->mmap_length = mmap_size;
   mbi->mmap_addr = ptrdest;
index a53bbe50ae8c6c921c64bbfe371ef645c0022777..ab803734f67979f097a761ba4d4e98c789168b6f 100644 (file)
@@ -62,15 +62,17 @@ static grub_uint32_t biosdev, slice, part;
 grub_size_t
 grub_multiboot_get_mbi_size (void)
 {
-  return sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
-    + (sizeof (struct multiboot_tag_string) + ALIGN_UP (cmdline_size, 4))
+  return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
     + (sizeof (struct multiboot_tag_string)
-       + ALIGN_UP (sizeof (PACKAGE_STRING), 4))
+       + ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
+    + (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)
-    + sizeof (struct multiboot_tag_bootdev)
-    + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_len ())
-    + sizeof (struct multiboot_tag_vbe);
+    + ALIGN_UP (sizeof (struct multiboot_tag_bootdev), MULTIBOOT_TAG_ALIGN)
+    + (sizeof (struct multiboot_tag_mmap) + grub_get_multiboot_mmap_count ()
+       * sizeof (struct multiboot_mmap_entry))
+    + sizeof (struct multiboot_tag_vbe) + MULTIBOOT_TAG_ALIGN - 1;
 }
 
 #ifdef GRUB_MACHINE_HAS_VBE
@@ -98,7 +100,7 @@ fill_vbe_info (struct grub_vbe_mode_info_block **vbe_mode_info_out,
     *vbe_mode_info_out = (struct grub_vbe_mode_info_block *) 
       &(tag->vbe_mode_info);
   tag->size = sizeof (struct multiboot_tag_vbe);
-  *ptrorig += tag->size;
+  *ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
   return GRUB_ERR_NONE;
 }
 
@@ -106,9 +108,9 @@ fill_vbe_info (struct grub_vbe_mode_info_block **vbe_mode_info_out,
 
 /* Fill previously allocated Multiboot mmap.  */
 static void
-grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
+grub_fill_multiboot_mmap (struct multiboot_tag_mmap *tag)
 {
-  struct multiboot_mmap_entry *mmap_entry = (struct multiboot_mmap_entry *) first_entry;
+  struct multiboot_mmap_entry *mmap_entry = tag->entries;
 
   auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
   int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
@@ -137,12 +139,17 @@ grub_fill_multiboot_mmap (struct multiboot_mmap_entry *first_entry)
          mmap_entry->type = MULTIBOOT_MEMORY_RESERVED;
          break;
        }
-      mmap_entry->size = sizeof (struct multiboot_mmap_entry) - sizeof (mmap_entry->size);
       mmap_entry++;
 
       return 0;
     }
 
+  tag->type = MULTIBOOT_TAG_TYPE_MMAP;
+  tag->size = sizeof (struct multiboot_tag_mmap)
+    + sizeof (struct multiboot_mmap_entry) * grub_get_multiboot_mmap_count (); 
+  tag->entry_size = sizeof (struct multiboot_mmap_entry);
+  tag->entry_version = 0;
+
   grub_mmap_iterate (hook);
 }
 
@@ -190,7 +197,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
          
          tag->common.framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT;
          tag->common.size = sizeof (tag->common);
-         *ptrorig += tag->common.size;
+         tag->common.reserved = 0;
+         *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
        }
       return GRUB_ERR_NONE;
     }
@@ -214,6 +222,8 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
   tag->common.framebuffer_height = mode_info.height;
 
   tag->common.framebuffer_bpp = mode_info.bpp;
+
+  tag->common.reserved = 0;
       
   if (mode_info.mode_type & GRUB_VIDEO_MODE_TYPE_INDEX_COLOR)
     {
@@ -231,7 +241,6 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
          tag->framebuffer_palette[i].green = palette[i].g;
          tag->framebuffer_palette[i].blue = palette[i].b;
        }
-      *ptrorig += tag->common.size;
     }
   else
     {
@@ -246,6 +255,7 @@ retrieve_video_parameters (grub_uint8_t **ptrorig)
 
       tag->common.size = sizeof (struct multiboot_tag_framebuffer_common) + 6;
     }
+  *ptrorig += ALIGN_UP (tag->common.size, MULTIBOOT_TAG_ALIGN);
 
 #if HAS_VBE
   if (driv_id == GRUB_VIDEO_DRIVER_VBE)
@@ -264,30 +274,29 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
                         grub_size_t bufsize)
 {
   grub_uint8_t *ptrorig;
-  grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off;
+  grub_uint8_t *mbistart = (grub_uint8_t *) orig + buf_off 
+    + (ALIGN_UP (dest + buf_off, MULTIBOOT_TAG_ALIGN) - (dest + buf_off));
   grub_err_t err;
 
   if (bufsize < grub_multiboot_get_mbi_size ())
     return grub_error (GRUB_ERR_OUT_OF_MEMORY, "mbi buffer is too small");
 
-  ptrorig = (grub_uint8_t *) orig + buf_off + sizeof (grub_uint32_t);
+  ptrorig = mbistart + 2 * sizeof (grub_uint32_t);
 
   {
     struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
     tag->type = MULTIBOOT_TAG_TYPE_CMDLINE;
-    tag->size = sizeof (struct multiboot_tag_string)
-      + ALIGN_UP (cmdline_size, 4); 
+    tag->size = sizeof (struct multiboot_tag_string) + cmdline_size; 
     grub_memcpy (tag->string, cmdline, cmdline_size);
-    ptrorig += tag->size;
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
   }
 
   {
     struct multiboot_tag_string *tag = (struct multiboot_tag_string *) ptrorig;
     tag->type = MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME;
-    tag->size = sizeof (struct multiboot_tag_string)
-      + ALIGN_UP (sizeof (PACKAGE_STRING), 4); 
+    tag->size = sizeof (struct multiboot_tag_string) + sizeof (PACKAGE_STRING); 
     grub_memcpy (tag->string, PACKAGE_STRING, sizeof (PACKAGE_STRING));
-    ptrorig += tag->size;
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
   }
 
   {
@@ -299,23 +308,18 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
        struct multiboot_tag_module *tag
          = (struct multiboot_tag_module *) ptrorig;
        tag->type = MULTIBOOT_TAG_TYPE_MODULE;
-       tag->size = sizeof (struct multiboot_tag_module)
-         + ALIGN_UP (sizeof (cur->cmdline_size), 4); 
-
+       tag->size = sizeof (struct multiboot_tag_module) + cur->cmdline_size;
        tag->mod_start = dest + cur->start;
        tag->mod_end = tag->mod_start + cur->size;
        grub_memcpy (tag->cmdline, cur->cmdline, cur->cmdline_size);
-       ptrorig += tag->size;
+       ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
       }
   }
 
   {
     struct multiboot_tag_mmap *tag = (struct multiboot_tag_mmap *) ptrorig;
-    tag->type = MULTIBOOT_TAG_TYPE_MMAP;
-    tag->size = sizeof (struct multiboot_tag_mmap) 
-      + grub_get_multiboot_mmap_len (); 
-    grub_fill_multiboot_mmap (tag->entries);
-    ptrorig += tag->size;
+    grub_fill_multiboot_mmap (tag);
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
   }
 
   {
@@ -327,7 +331,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
     /* Convert from bytes to kilobytes.  */
     tag->mem_lower = grub_mmap_get_lower () / 1024;
     tag->mem_upper = grub_mmap_get_upper () / 1024;
-    ptrorig += tag->size;
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
   }
 
   if (bootdev_set)
@@ -340,7 +344,7 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
       tag->biosdev = biosdev;
       tag->slice = slice;
       tag->part = part;
-      ptrorig += tag->size;
+      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
     }
 
   {
@@ -356,10 +360,11 @@ grub_multiboot_make_mbi (void *orig, grub_uint32_t dest, grub_off_t buf_off,
     struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
     tag->type = MULTIBOOT_TAG_TYPE_END;
     tag->size = sizeof (struct multiboot_tag);
-    ptrorig += tag->size;
+    ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN);
   }
 
-  *(grub_uint32_t *) mbistart = ptrorig - mbistart;
+  ((grub_uint32_t *) mbistart)[0] = ptrorig - mbistart;
+  ((grub_uint32_t *) mbistart)[1] = 0;
 
   return GRUB_ERR_NONE;
 }
@@ -447,7 +452,7 @@ grub_multiboot_add_module (grub_addr_t start, grub_size_t size,
       return grub_errno;
     }
   newmod->cmdline_size = len;
-  total_modcmd += ALIGN_UP (len, 4);
+  total_modcmd += ALIGN_UP (len, MULTIBOOT_TAG_ALIGN);
 
   for (i = 0; i < argc; i++)
     {
@@ -495,8 +500,8 @@ grub_multiboot_set_bootdev (void)
   dev = grub_device_open (0);
   if (dev && dev->disk && dev->disk->partition)
     {
-
-      p = dev->disk->partition->partmap->get_name (dev->disk->partition);
+      char *p0;
+      p = p0 = dev->disk->partition->partmap->get_name (dev->disk->partition);
       if (p)
        {
          if ((p[0] >= '0') && (p[0] <= '9'))
@@ -510,6 +515,7 @@ grub_multiboot_set_bootdev (void)
          if ((p[0] >= 'a') && (p[0] <= 'z'))
            part = p[0] - 'a';
        }
+      grub_free (p0);
     }
   if (dev)
     grub_device_close (dev);