]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Implement multiboot2 EFI BS specification.
authorVladimir Serbinenko <phcoder@gmail.com>
Fri, 13 Dec 2013 11:56:14 +0000 (12:56 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Fri, 13 Dec 2013 11:56:14 +0000 (12:56 +0100)
ChangeLog
grub-core/loader/multiboot.c
grub-core/loader/multiboot_mbi2.c
include/multiboot2.h

index 9cec63f5ce4a9a1f7499edefd3385d4e738464fd..9c5073c101a7d79e4758dd51b112614e19b2227e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-12-13  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Implement multiboot2 EFI BS specification.
+
 2013-12-11  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/normal/charset.c: Fix premature line wrap and crash.
index 54e4d240858d27bdb270e8df94026c777c6b63da..4b71f33635349eb8dec7181d05f698539ec8f00f 100644 (file)
@@ -344,7 +344,7 @@ grub_cmd_module (grub_command_t cmd __attribute__ ((unused)),
     err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
                                            lowest_addr, (0xffffffff - size) + 1,
                                            size, MULTIBOOT_MOD_ALIGN,
-                                           GRUB_RELOCATOR_PREFERENCE_NONE, 0);
+                                           GRUB_RELOCATOR_PREFERENCE_NONE, 1);
     if (err)
       {
        grub_file_close (file);
index 951988fb95575a47b3136909c61a454f97767ee2..2f5aa6294d2a3e95888f04566fa063fd53c24268 100644 (file)
@@ -67,6 +67,7 @@ static grub_uint32_t biosdev, slice, part;
 static grub_size_t elf_sec_num, elf_sec_entsize;
 static unsigned elf_sec_shstrndx;
 static void *elf_sections;
+static int keep_bs = 0;
 
 void
 grub_multiboot_add_elfsyms (grub_size_t num, grub_size_t entsize,
@@ -127,6 +128,8 @@ grub_multiboot_load (grub_file_t file, const char *filename)
 
   COMPILE_TIME_ASSERT (MULTIBOOT_TAG_ALIGN % 4 == 0);
 
+  keep_bs = 0;
+
   for (tag = (struct multiboot_header_tag *) (header + 1);
        tag->type != MULTIBOOT_TAG_TYPE_END;
        tag = (struct multiboot_header_tag *) ((grub_uint32_t *) tag + ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN) / 4))
@@ -160,6 +163,7 @@ grub_multiboot_load (grub_file_t file, const char *filename)
              case MULTIBOOT_TAG_TYPE_ACPI_NEW:
              case MULTIBOOT_TAG_TYPE_NETWORK:
              case MULTIBOOT_TAG_TYPE_EFI_MMAP:
+             case MULTIBOOT_TAG_TYPE_EFI_BS:
                break;
 
              default:
@@ -198,6 +202,10 @@ grub_multiboot_load (grub_file_t file, const char *filename)
       case MULTIBOOT_HEADER_TAG_MODULE_ALIGN:
        break;
 
+      case MULTIBOOT_HEADER_TAG_EFI_BS:
+       keep_bs = 1;
+       break;
+
       default:
        if (! (tag->flags & MULTIBOOT_HEADER_TAG_OPTIONAL))
          {
@@ -362,6 +370,7 @@ grub_multiboot_get_mbi_size (void)
     find_efi_mmap_size ();    
 #endif
   return 2 * sizeof (grub_uint32_t) + sizeof (struct multiboot_tag)
+    + sizeof (struct multiboot_tag)
     + (sizeof (struct multiboot_tag_string)
        + ALIGN_UP (cmdline_size, MULTIBOOT_TAG_ALIGN))
     + (sizeof (struct multiboot_tag_string)
@@ -637,7 +646,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
   err = grub_relocator_alloc_chunk_align (grub_multiboot_relocator, &ch,
                                          0, 0xffffffff - bufsize,
                                          bufsize, MULTIBOOT_TAG_ALIGN,
-                                         GRUB_RELOCATOR_PREFERENCE_NONE, 0);
+                                         GRUB_RELOCATOR_PREFERENCE_NONE, 1);
   if (err)
     return err;
 
@@ -853,8 +862,16 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
     tag->type = MULTIBOOT_TAG_TYPE_EFI_MMAP;
     tag->size = sizeof (*tag) + efi_mmap_size;
 
-    err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
-                                        &efi_desc_size, &efi_desc_version);
+    if (!keep_bs)
+      err = grub_efi_finish_boot_services (&efi_mmap_size, tag->efi_mmap, NULL,
+                                          &efi_desc_size, &efi_desc_version);
+    else
+      {
+       if (grub_efi_get_memory_map (&efi_mmap_size, (void *) tag->efi_mmap,
+                                    NULL,
+                                    &efi_desc_size, &efi_desc_version) <= 0)
+         err = grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
+      }
     if (err)
       return err;
     tag->descr_size = efi_desc_size;
@@ -864,6 +881,15 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
     ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
       / sizeof (grub_properly_aligned_t);
   }
+
+  if (keep_bs)
+    {
+      struct multiboot_tag *tag = (struct multiboot_tag *) ptrorig;
+      tag->type = MULTIBOOT_TAG_TYPE_EFI_BS;
+      tag->size = sizeof (struct multiboot_tag);
+      ptrorig += ALIGN_UP (tag->size, MULTIBOOT_TAG_ALIGN)
+       / sizeof (grub_properly_aligned_t);
+    }
 #endif
 
   {
index 58f2f684554d108056b6e34229d23d6a4a908cbd..2e33cbf8d20902fe55a2a2dea868808fb65c380b 100644 (file)
@@ -59,6 +59,7 @@
 #define MULTIBOOT_TAG_TYPE_ACPI_NEW          15
 #define MULTIBOOT_TAG_TYPE_NETWORK           16
 #define MULTIBOOT_TAG_TYPE_EFI_MMAP          17
+#define MULTIBOOT_TAG_TYPE_EFI_BS            18
 
 #define MULTIBOOT_HEADER_TAG_END  0
 #define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST  1
@@ -67,6 +68,7 @@
 #define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS  4
 #define MULTIBOOT_HEADER_TAG_FRAMEBUFFER  5
 #define MULTIBOOT_HEADER_TAG_MODULE_ALIGN  6
+#define MULTIBOOT_HEADER_TAG_EFI_BS  7
 
 #define MULTIBOOT_ARCHITECTURE_I386  0
 #define MULTIBOOT_ARCHITECTURE_MIPS32  4