Was successfully tested with qemu-tianocore with example multiboot
kernel from multiboot specification. Since real EFI has no VGA video
fields play a crucial feature and need to be supported. Patch is
coming but it will surely rely on gfxsplit patch. I also have plans to
extend it to x86-64 too

-- 
Regards
Vladimir 'phcoder' Serbinenko

Personal git repository: http://repo.or.cz/w/grub2/phcoder.git
diff --git a/ChangeLog b/ChangeLog
index d7f219b..95ca160 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2009-08-02  Vladimir Serbinenko  <phco...@gmail.com>
+
+       Multiboot support on i386-efi.
+
+       * conf/i386-efi.rmk (pkglib_MODULES): Add multiboot.mod.
+       (multiboot_mod_SOURCES): New variable.
+       (multiboot_mod_CFLAGS): Likewise.
+       (multiboot_mod_LDFLAGS): Likewise.
+       (multiboot_mod_ASFLAGS): Likewise.
+       * include/grub/i386/multiboot.h (grub_multiboot_real_boot): Explicitly
+       declare as regparm (3).
+       (grub_multiboot2_real_boot): Likewise.
+       (grub_multiboot_boot): Finish boot services.
+       (grub_fill_multiboot_mmap): Explicitly parse memory map types.
+       (grub_multiboot): Declare as noreturn to avoid finishing console.
+       * loader/multiboot_loader.c (grub_cmd_multiboot_loader): Enable
+       multiboot1 on i386-efi and disable multiboot2 on this platform.
+       (grub_cmd_module_loader): Likewise.
+
 2009-08-01  Vladimir Serbinenko  <phco...@gmail.com>
 
        * util/hostfs.c (grub_hostfs_dir): Don't use DT_DIR: It doesn't work
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index 9177b9d..248ad87 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -83,7 +83,15 @@ grub_install_SOURCES = util/i386/efi/grub-install.in
 pkglib_MODULES = kernel.mod chain.mod appleldr.mod \
        linux.mod halt.mod reboot.mod pci.mod lspci.mod \
        datetime.mod date.mod datehook.mod loadbios.mod \
-       fixvideo.mod mmap.mod acpi.mod
+       fixvideo.mod mmap.mod acpi.mod multiboot.mod
+
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/i386/multiboot.c \
+                       loader/i386/multiboot_helper.S \
+                        loader/multiboot_loader.c
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_ASFLAGS = $(COMMON_ASFLAGS)
 
 # For kernel.mod.
 kernel_mod_EXPORTS = no
diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h
index 2dd7ec0..a6da360 100644
--- a/include/grub/i386/multiboot.h
+++ b/include/grub/i386/multiboot.h
@@ -22,10 +22,10 @@
 /* The asm part of the multiboot loader.  */
 void grub_multiboot_real_boot (grub_addr_t entry,
                               struct grub_multiboot_info *mbi)
-     __attribute__ ((noreturn));
+  __attribute__ ((noreturn,regparm (3)));
 void grub_multiboot2_real_boot (grub_addr_t entry,
                                struct grub_multiboot_info *mbi)
-     __attribute__ ((noreturn));
+     __attribute__ ((noreturn,regparm (3)));
 
 extern grub_addr_t grub_multiboot_payload_orig;
 extern grub_addr_t grub_multiboot_payload_dest;
diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c
index 87ffcae..f51a38d 100644
--- a/loader/i386/multiboot.c
+++ b/loader/i386/multiboot.c
@@ -30,8 +30,10 @@
 #include <grub/loader.h>
 #include <grub/machine/loader.h>
 #include <grub/multiboot.h>
+#include <grub/machine/machine.h>
 #include <grub/machine/init.h>
 #include <grub/machine/memory.h>
+#include <grub/memory.h>
 #include <grub/cpu/multiboot.h>
 #include <grub/elf.h>
 #include <grub/aout.h>
@@ -49,6 +51,13 @@
 #include <grub/partition.h>
 #endif
 
+#include <grub/cpu/loader.h>
+#include <grub/cpu/multiboot.h>
+
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#endif
+
 extern grub_dl_t my_mod;
 static struct grub_multiboot_info *mbi, *mbi_dest;
 static grub_addr_t entry;
@@ -59,6 +68,11 @@ static grub_size_t code_size;
 static grub_err_t
 grub_multiboot_boot (void)
 {
+#ifdef GRUB_MACHINE_EFI
+  if (! grub_efi_finish_boot_services ())
+     grub_fatal ("cannot exit boot services");
+#endif
+
   grub_multiboot_real_boot (entry, mbi_dest);
 
   /* Not reached.  */
@@ -114,14 +128,24 @@ grub_get_multiboot_mmap_len (void)
 static void
 grub_fill_multiboot_mmap (struct grub_multiboot_mmap_entry *first_entry)
 {
-  struct grub_multiboot_mmap_entry *mmap_entry = (struct 
grub_multiboot_mmap_entry *) first_entry;
+  struct grub_multiboot_mmap_entry *mmap_entry
+    = (struct grub_multiboot_mmap_entry *) first_entry;
 
   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)
     {
       mmap_entry->addr = addr;
       mmap_entry->len = size;
-      mmap_entry->type = type;
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
+         mmap_entry->type = GRUB_MULTIBOOT_MEMORY_AVAILABLE;
+         break;
+
+       default:
+         mmap_entry->type = GRUB_MULTIBOOT_MEMORY_RESERVED;
+         break;
+       }
       mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof 
(mmap_entry->size);
       mmap_entry++;
 
@@ -371,7 +395,7 @@ grub_multiboot (int argc, char *argv[])
   if (grub_multiboot_get_bootdev (&mbi->boot_device))
     mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
 
-  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 1);
+  grub_loader_set (grub_multiboot_boot, grub_multiboot_unload, 0);
 
  fail:
   if (file)
diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c
index 986ee0b..7701ce0 100644
--- a/loader/multiboot_loader.c
+++ b/loader/multiboot_loader.c
@@ -140,7 +140,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ 
((unused)),
   /* XXX Find a better way to identify this.
      This is for i386-pc */
 #if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \
-    defined(GRUB_MACHINE_QEMU)
+  defined(GRUB_MACHINE_QEMU) || (defined(GRUB_MACHINE_EFI) && !defined 
(__x86_64__))
   if (header_multi_ver_found == 1)
     {
       grub_dprintf ("multiboot_loader",
@@ -149,6 +149,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ 
((unused)),
       module_version_status = 1;
     }
 #endif
+#if !defined(GRUB_MACHINE_EFI)
   if (header_multi_ver_found == 0 || header_multi_ver_found == 2)
     {
       grub_dprintf ("multiboot_loader",
@@ -156,6 +157,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ 
((unused)),
       grub_multiboot2 (argc, argv);
       module_version_status = 2;
     }
+#endif
 
   return grub_errno;
 
@@ -174,7 +176,7 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ 
((unused)),
 {
 
 #if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_COREBOOT) || \
-    defined(GRUB_MACHINE_QEMU)
+    defined(GRUB_MACHINE_QEMU) || (defined(GRUB_MACHINE_EFI) && !defined 
(__x86_64__))
   if (module_version_status == 1)
     {
       grub_dprintf("multiboot_loader",
@@ -182,13 +184,14 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ 
((unused)),
       grub_module (argc, argv);
     }
 #endif
+#if !defined(GRUB_MACHINE_EFI)
   if (module_version_status == 2)
     {
       grub_dprintf("multiboot_loader",
           "Launching multiboot 2 grub_module2() function\n");
       grub_module2 (argc, argv);
     }
-
+#endif
   return grub_errno;
 }
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to