All of lore.kernel.org
 help / color / mirror / Atom feed
From: phcoder <phcoder@gmail.com>
To: The development of GRUB 2 <grub-devel@gnu.org>
Subject: multiboot on EFI
Date: Mon, 23 Mar 2009 13:29:55 +0100	[thread overview]
Message-ID: <49C780C3.4010403@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 183 bytes --]

Hello. Here is an initial version of patch for booting multiboot kernels 
on i386-efi. No Changelog yet because it's not for inclusion yet.
-- 

Regards
Vladimir 'phcoder' Serbinenko

[-- Attachment #2: efiboot.diff --]
[-- Type: text/x-diff, Size: 32540 bytes --]

diff --git a/conf/common.rmk b/conf/common.rmk
index 100fae7..e64a1a4 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -507,3 +507,10 @@ gzio_mod_LDFLAGS = $(COMMON_LDFLAGS)
 bufio_mod_SOURCES = io/bufio.c
 bufio_mod_CFLAGS = $(COMMON_CFLAGS)
 bufio_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += lsmmap.mod
+
+# For lsmmap.mod
+lsmmap_mod_SOURCES = commands/lsmmap.c
+lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
+lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index 6f4e8f3..1304eb3 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -102,8 +102,7 @@ pkglib_MODULES = _linux.mod linux.mod normal.mod	\
 	_multiboot.mod multiboot.mod aout.mod		\
 	play.mod serial.mod ata.mod			\
 	memdisk.mod pci.mod lspci.mod reboot.mod	\
-	halt.mod datetime.mod date.mod datehook.mod	\
-	lsmmap.mod
+	halt.mod datetime.mod date.mod datehook.mod	
 
 # For _linux.mod.
 _linux_mod_SOURCES = loader/i386/linux.c
@@ -211,10 +210,5 @@ datehook_mod_SOURCES = hook/datehook.c
 datehook_mod_CFLAGS = $(COMMON_CFLAGS)
 datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-# For lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 include $(srcdir)/conf/i386.mk
 include $(srcdir)/conf/common.mk
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index a2454d9..4303b1c 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -80,7 +80,20 @@ grub_install_SOURCES = util/i386/efi/grub-install.in
 # Modules.
 pkglib_MODULES = kernel.mod normal.mod _chain.mod chain.mod appleldr.mod \
 	_linux.mod linux.mod halt.mod reboot.mod pci.mod lspci.mod \
-	datetime.mod date.mod datehook.mod
+	datetime.mod date.mod datehook.mod _multiboot.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 multiboot.mod.
+multiboot_mod_SOURCES = loader/multiboot_loader_normal.c 
+multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For kernel.mod.
 kernel_mod_EXPORTS = no
@@ -90,14 +103,14 @@ kernel_mod_SOURCES = kern/i386/efi/startup.S kern/main.c kern/device.c \
 	kern/i386/dl.c kern/i386/efi/init.c kern/parser.c kern/partition.c \
 	kern/env.c symlist.c kern/efi/efi.c kern/efi/init.c kern/efi/mm.c \
 	term/efi/console.c disk/efi/efidisk.c \
-	kern/time.c kern/list.c kern/handler.c \
+	kern/efi/mmap.c kern/time.c kern/list.c kern/handler.c \
 	kern/i386/tsc.c kern/i386/pit.c \
 	kern/generic/rtc_get_time_ms.c \
 	kern/generic/millisleep.c
 kernel_mod_HEADERS = arg.h boot.h cache.h device.h disk.h dl.h elf.h elfload.h \
 	env.h err.h file.h fs.h kernel.h loader.h misc.h mm.h net.h parser.h \
 	partition.h pc_partition.h rescue.h symbol.h term.h time.h types.h \
-	efi/efi.h efi/time.h efi/disk.h list.h handler.h
+	efi/efi.h efi/time.h efi/disk.h efi/memory.h list.h handler.h
 kernel_mod_CFLAGS = $(COMMON_CFLAGS)
 kernel_mod_ASFLAGS = $(COMMON_ASFLAGS)
 kernel_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/i386-ieee1275.rmk b/conf/i386-ieee1275.rmk
index 305b31d..460dfdd 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -102,7 +102,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in
 pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod		\
 	multiboot.mod _multiboot.mod aout.mod serial.mod linux.mod	\
 	_linux.mod nand.mod memdisk.mod pci.mod lspci.mod datetime.mod	\
-	date.mod datehook.mod lsmmap.mod
+	date.mod datehook.mod
 
 #
 # Only arch dependant part of normal.mod will be here. Common part for
@@ -209,10 +209,5 @@ datehook_mod_SOURCES = hook/datehook.c
 datehook_mod_CFLAGS = $(COMMON_CFLAGS)
 datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-# For lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 include $(srcdir)/conf/i386.mk
 include $(srcdir)/conf/common.mk
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index e1ed9aa..0be2729 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -178,8 +178,8 @@ pkglib_MODULES = biosdisk.mod _chain.mod _linux.mod linux.mod normal.mod \
 	_multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod	\
 	vbe.mod vbetest.mod vbeinfo.mod play.mod serial.mod	\
 	ata.mod vga.mod memdisk.mod pci.mod lspci.mod \
-	aout.mod _bsd.mod bsd.mod pxe.mod pxecmd.mod datetime.mod date.mod \
-	datehook.mod lsmmap.mod ata_pthru.mod hdparm.mod \
+	pxe.mod pxecmd.mod datetime.mod date.mod \
+	datehook.mod ata_pthru.mod hdparm.mod \
 	usb.mod uhci.mod ohci.mod usbtest.mod usbms.mod usb_keyboard.mod \
 	efiemu.mod efiemu_acpi.mod efiemu_pnvram.mod
 
@@ -318,21 +318,6 @@ lspci_mod_SOURCES = commands/lspci.c
 lspci_mod_CFLAGS = $(COMMON_CFLAGS)
 lspci_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-# For aout.mod
-aout_mod_SOURCES = loader/aout.c
-aout_mod_CFLAGS = $(COMMON_CFLAGS)
-aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For _bsd.mod
-_bsd_mod_SOURCES = loader/i386/bsd.c
-_bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-# For bsd.mod
-bsd_mod_SOURCES = loader/i386/bsd_normal.c
-bsd_mod_CFLAGS = $(COMMON_CFLAGS)
-bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For usb.mod
 usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
 usb_mod_CFLAGS = $(COMMON_CFLAGS)
@@ -388,11 +373,6 @@ datehook_mod_SOURCES = hook/datehook.c
 datehook_mod_CFLAGS = $(COMMON_CFLAGS)
 datehook_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-# For lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 # For ata_pthru.mod.
 ata_pthru_mod_SOURCES = disk/ata_pthru.c
 ata_pthru_mod_CFLAGS = $(COMMON_CFLAGS)
diff --git a/conf/i386.rmk b/conf/i386.rmk
index 4e86ed8..5338457 100644
--- a/conf/i386.rmk
+++ b/conf/i386.rmk
@@ -19,3 +19,21 @@ pkglib_MODULES += uppermem.mod
 uppermem_mod_SOURCES = lib/i386/uppermem.c
 uppermem_mod_CFLAGS = $(COMMON_CFLAGS)
 uppermem_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += aout.mod _bsd.mod bsd.mod 
+# For aout.mod
+aout_mod_SOURCES = loader/aout.c
+aout_mod_CFLAGS = $(COMMON_CFLAGS)
+aout_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For _bsd.mod
+_bsd_mod_SOURCES = loader/i386/bsd.c loader/i386/bsd_helper.S
+_bsd_mod_CFLAGS = $(COMMON_CFLAGS) -Werror
+_bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+_bsd_mod_ASFLAGS = $(COMMON_ASFLAGS)
+
+# For bsd.mod
+bsd_mod_SOURCES = loader/i386/bsd_normal.c
+bsd_mod_CFLAGS = $(COMMON_CFLAGS)
+bsd_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index 66d1d58..c9e185a 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -112,8 +112,7 @@ pkglib_MODULES = halt.mod \
 	suspend.mod \
         _multiboot.mod \
         multiboot.mod \
-	memdisk.mod \
-	lsmmap.mod
+	memdisk.mod 
 
 # For _linux.mod.
 _linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
@@ -178,10 +177,5 @@ memdisk_mod_SOURCES = disk/memdisk.c
 memdisk_mod_CFLAGS = $(COMMON_CFLAGS)
 memdisk_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
-# For lsmmap.mod
-lsmmap_mod_SOURCES = commands/lsmmap.c
-lsmmap_mod_CFLAGS = $(COMMON_CFLAGS)
-lsmmap_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
 include $(srcdir)/conf/common.mk
 
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index 8c277c0..137a437 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -54,6 +54,8 @@ char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
 grub_efi_device_path_t *
 EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
 int EXPORT_FUNC(grub_efi_exit_boot_services) (grub_efi_uintn_t map_key);
+int EXPORT_FUNC(grub_efi_finish_boot_services) (void);
+
 void EXPORT_FUNC (grub_reboot) (void);
 void EXPORT_FUNC (grub_halt) (void);
 
diff --git a/include/grub/efi/memory.h b/include/grub/efi/memory.h
new file mode 100644
index 0000000..9000642
--- /dev/null
+++ b/include/grub/efi/memory.h
@@ -0,0 +1,15 @@
+#ifndef GRUB_MEMORY_MACHINE_HEADER
+#define GRUB_MEMORY_MACHINE_HEADER	1
+
+#include <grub/err.h>
+#include <grub/types.h>
+
+#define GRUB_MACHINE_MEMORY_AVAILABLE	1
+#define GRUB_MACHINE_MEMORY_RESERVED	2
+#define GRUB_MACHINE_MEMORY_ACPI	3
+#define GRUB_MACHINE_MEMORY_NVS         4
+#define GRUB_MACHINE_MEMORY_CODE         5
+
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate) 
+(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+#endif /* ! GRUB_MEMORY_MACHINE_HEADER */
diff --git a/include/grub/i386/bsd.h b/include/grub/i386/bsd.h
index 00296c9..e8bed00 100644
--- a/include/grub/i386/bsd.h
+++ b/include/grub/i386/bsd.h
@@ -148,6 +148,8 @@ struct grub_openbsd_bios_mmap
 {
   grub_uint64_t addr;
   grub_uint64_t len;
+#define	OPENBSD_MMAP_AVAILABLE	1
+#define	OPENBSD_MMAP_RESERVED 2
   grub_uint32_t type;
 };
 
@@ -229,4 +231,7 @@ void grub_rescue_cmd_netbsd (int argc, char *argv[]);
 void grub_rescue_cmd_freebsd_loadenv (int argc, char *argv[]);
 void grub_rescue_cmd_freebsd_module (int argc, char *argv[]);
 
+void grub_unix_real_boot (grub_addr_t entry, ...)
+  __attribute__ ((cdecl,noreturn));
+
 #endif /* ! GRUB_BSD_CPU_HEADER */
diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h
new file mode 100644
index 0000000..c9a61bb
--- /dev/null
+++ b/include/grub/i386/efi/memory.h
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/include/grub/i386/loader.h b/include/grub/i386/loader.h
index f858c0a..cb2f918 100644
--- a/include/grub/i386/loader.h
+++ b/include/grub/i386/loader.h
@@ -32,9 +32,6 @@ extern grub_size_t EXPORT_VAR(grub_os_area_size);
 
 grub_err_t EXPORT_FUNC(grub_linux_boot) (void);
 
-void EXPORT_FUNC(grub_unix_real_boot) (grub_addr_t entry, ...)
-     __attribute__ ((cdecl,noreturn));
-
 /* It is necessary to export these functions, because normal mode commands
    reuse rescue mode commands.  */
 void grub_rescue_cmd_linux (int argc, char *argv[]);
diff --git a/include/grub/i386/multiboot.h b/include/grub/i386/multiboot.h
index ea68640..85405dc 100644
--- a/include/grub/i386/multiboot.h
+++ b/include/grub/i386/multiboot.h
@@ -22,7 +22,7 @@
 /* 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));
diff --git a/include/grub/i386/pc/memory.h b/include/grub/i386/pc/memory.h
index 08e92a9..e69ff77 100644
--- a/include/grub/i386/pc/memory.h
+++ b/include/grub/i386/pc/memory.h
@@ -92,6 +92,8 @@ struct grub_machine_mmap_entry
   grub_uint64_t len;
 #define GRUB_MACHINE_MEMORY_AVAILABLE	1
 #define GRUB_MACHINE_MEMORY_RESERVED	2
+#define GRUB_MACHINE_MEMORY_ACPI	3
+#define GRUB_MACHINE_MEMORY_NVS 	4
   grub_uint32_t type;
 } __attribute__((packed));
 
diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h
new file mode 100644
index 0000000..c9a61bb
--- /dev/null
+++ b/include/grub/x86_64/efi/memory.h
@@ -0,0 +1 @@
+#include <grub/efi/memory.h>
diff --git a/kern/efi/efi.c b/kern/efi/efi.c
index 9c9a400..754f82c 100644
--- a/kern/efi/efi.c
+++ b/kern/efi/efi.c
@@ -187,6 +187,28 @@ grub_efi_exit_boot_services (grub_efi_uintn_t map_key)
   return status == GRUB_EFI_SUCCESS;
 }
 
+int
+grub_efi_finish_boot_services (void)
+{
+  grub_efi_uintn_t mmap_size = 0;
+  grub_efi_uintn_t map_key;
+  grub_efi_uintn_t desc_size;
+  grub_efi_uint32_t desc_version;
+  void *mmap_buf;
+
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+			       &desc_size, &desc_version) < 0)
+    return 0;
+
+  mmap_buf = grub_malloc (mmap_size);
+  
+  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
+			       &desc_size, &desc_version) <= 0)
+    return 0;
+
+  return  grub_efi_exit_boot_services (map_key);
+}
+
 grub_uint32_t
 grub_get_rtc (void)
 {
diff --git a/kern/efi/mm.c b/kern/efi/mm.c
index 35b12ab..4635776 100644
--- a/kern/efi/mm.c
+++ b/kern/efi/mm.c
@@ -47,7 +47,7 @@ static struct allocated_page *allocated_pages = 0;
 
 /* The minimum and maximum heap size for GRUB itself.  */
 #define MIN_HEAP_SIZE	0x100000
-#define MAX_HEAP_SIZE	(16 * 0x100000)
+#define MAX_HEAP_SIZE	(1600 * 0x100000)
 
 
 /* Allocate pages. Return the pointer to the first of allocated pages.  */
diff --git a/kern/efi/mmap.c b/kern/efi/mmap.c
new file mode 100644
index 0000000..11fbc72
--- /dev/null
+++ b/kern/efi/mmap.c
@@ -0,0 +1,158 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/machine/memory.h>
+#include <grub/err.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+#define NEXT_MEMORY_DESCRIPTOR(desc, size)      \
+  ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
+
+struct region
+{
+  grub_uint64_t start;
+  grub_uint64_t len;
+  grub_uint32_t type;
+};
+
+grub_err_t
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  grub_efi_uintn_t mmap_size = 0;
+  grub_efi_memory_descriptor_t *map_buf;
+  grub_efi_uintn_t map_key = 0;
+  grub_efi_uintn_t desc_size = 0;
+  grub_efi_uint32_t desc_version = 0;
+  grub_uint64_t curstart, curend;
+  grub_uint32_t curtype;
+  grub_efi_memory_descriptor_t *desc;
+  struct region *regions;
+  struct region t;
+  int i, count, done = 1;
+
+  if (grub_efi_get_memory_map (&mmap_size, map_buf,
+			       &map_key, &desc_size,
+			       &desc_version) < 0)
+    return grub_errno;
+
+  map_buf = grub_malloc (mmap_size);
+  if (!map_buf)
+    return grub_errno;
+
+  if (grub_efi_get_memory_map (&mmap_size, map_buf,
+			       &map_key, &desc_size,
+			       &desc_version) <= 0)
+    {
+      grub_free (map_buf);
+      return grub_errno;
+    }
+
+  count = mmap_size / desc_size;
+  if (! count)
+    {
+      grub_free (map_buf);
+      return grub_error (GRUB_ERR_IO, "couldn't get EFI memory map");
+    }
+  regions = (struct region *) grub_malloc (count * sizeof (struct region));
+
+  for (desc = map_buf, i = 0;
+       desc < NEXT_MEMORY_DESCRIPTOR (map_buf, mmap_size);
+       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++)
+    {
+      grub_dprintf ("efi_mmap", "EFI memory region 0x%llx-0x%llx: %d\n",
+		    desc->physical_start, desc->physical_start
+		    + desc->num_pages * 4096, desc->type);
+      switch (desc->type)
+	{
+	case GRUB_EFI_RUNTIME_SERVICES_CODE:
+	  regions[i].start = desc->physical_start;
+	  regions[i].len = desc->num_pages * 4096;
+	  regions[i].type = GRUB_MACHINE_MEMORY_CODE;
+	  break;
+
+	case GRUB_EFI_RESERVED_MEMORY_TYPE:
+	case GRUB_EFI_RUNTIME_SERVICES_DATA:
+	case GRUB_EFI_UNUSABLE_MEMORY:
+	case GRUB_EFI_MEMORY_MAPPED_IO:
+	case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+	case GRUB_EFI_PAL_CODE:
+	case GRUB_EFI_MAX_MEMORY_TYPE:
+	  regions[i].start = desc->physical_start;
+	  regions[i].len = desc->num_pages * 4096;
+	  regions[i].type = GRUB_MACHINE_MEMORY_RESERVED;
+	  break;
+
+	case GRUB_EFI_LOADER_CODE:
+	case GRUB_EFI_LOADER_DATA:
+	case GRUB_EFI_BOOT_SERVICES_CODE:
+	case GRUB_EFI_BOOT_SERVICES_DATA:
+	case GRUB_EFI_CONVENTIONAL_MEMORY:
+	  regions[i].start = desc->physical_start;
+	  regions[i].len = desc->num_pages * 4096;
+	  regions[i].type = GRUB_MACHINE_MEMORY_AVAILABLE;
+	  break;
+
+	case GRUB_EFI_ACPI_RECLAIM_MEMORY:
+	  regions[i].start = desc->physical_start;
+	  regions[i].len = desc->num_pages * 4096;
+	  regions[i].type = GRUB_MACHINE_MEMORY_ACPI;
+	  break;
+
+	case GRUB_EFI_ACPI_MEMORY_NVS:
+	  regions[i].start = desc->physical_start;
+	  regions[i].len = desc->num_pages * 4096;
+	  regions[i].type = GRUB_MACHINE_MEMORY_NVS;
+	  break;
+	}
+    }
+
+  /* Bubble-sort the memory map */
+  while (done)
+    {
+      done = 0;
+      for (i = 0; i < count - 1; i++)
+	if (regions[i].start > regions[i + 1].start)
+	  {
+	    done = 1;
+	    t = regions[i];
+	    regions[i] = regions[i + 1];
+	    regions[i + 1] = t;
+	  }
+    }
+  
+  curstart = regions[0].start;
+  curend = regions[0].start + regions[0].len;
+  curtype = regions[0].type;
+  for (i = 1; i < count; i++)
+    {
+      if (curend != regions[i].start || curtype != regions[i].type)
+	{
+	  hook (curstart, curend - curstart, curtype);
+	  curstart = regions[i].start;
+	  curtype = regions[i].type;	  
+	}
+      curend = regions[i].start + regions[i].len;	
+    }
+
+  hook (curstart, curend - curstart, curtype);  
+
+  return GRUB_ERR_NONE;
+}
diff --git a/kern/i386/loader.S b/kern/i386/loader.S
index fc27b86..f1b6c18 100644
--- a/kern/i386/loader.S
+++ b/kern/i386/loader.S
@@ -117,27 +117,3 @@ bzimage:
 linux_setup_seg:
 	.word	0
 	.code32
-
-/*
- * Use cdecl calling convention for *BSD kernels.
- */
-
-FUNCTION(grub_unix_real_boot)
-
-        call    EXT_C(grub_dl_unload_all)
-        call    EXT_C(grub_stop_floppy)
-
-	/* Interrupts should be disabled.  */
-        cli
-
-	/* Discard `grub_unix_real_boot' return address.  */
-        popl    %eax
-
-        /* Fetch `entry' address ...  */
-        popl	%eax
-
-        /*
-         * ... and put our return address in its place. The kernel will
-         * ignore it, but it expects %esp to point to it.
-         */
-        call	*%eax
diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c
index 25d0f59..712b013 100644
--- a/loader/i386/bsd.c
+++ b/loader/i386/bsd.c
@@ -19,8 +19,8 @@
 #include <grub/loader.h>
 #include <grub/cpu/loader.h>
 #include <grub/cpu/bsd.h>
-#include <grub/machine/init.h>
 #include <grub/machine/memory.h>
+#include <grub/machine/machine.h>
 #include <grub/file.h>
 #include <grub/err.h>
 #include <grub/rescue.h>
@@ -31,6 +31,11 @@
 #include <grub/misc.h>
 #include <grub/gzio.h>
 #include <grub/aout.h>
+#include <grub/i386/uppermem.h>
+
+#ifdef GRUB_MACHINE_EFI
+#include <grub/efi/efi.h>
+#endif
 
 #define ALIGN_DWORD(a)	ALIGN_UP (a, 4)
 #define ALIGN_PAGE(a)	ALIGN_UP (a, 4096)
@@ -302,6 +307,15 @@ grub_freebsd_boot (void)
 
   bi.bi_kernend = kern_end;
 
+#ifdef GRUB_MACHINE_PCBIOS
+  grub_stop_floppy ();
+#endif
+
+#ifdef GRUB_MACHINE_EFI
+  if (! grub_efi_finish_boot_services ())
+     grub_fatal ("cannot exit boot services");
+#endif
+
   grub_unix_real_boot (entry, bootflags | FREEBSD_RB_BOOTINFO, bootdev,
 		       0, 0, 0, &bi, bi.bi_modulep, kern_end);
 
@@ -313,30 +327,39 @@ static grub_err_t
 grub_openbsd_boot (void)
 {
   char *buf = (char *) GRUB_BSD_TEMP_BUFFER;
-  struct grub_machine_mmap_entry mmap;
   struct grub_openbsd_bios_mmap *pm;
   struct grub_openbsd_bootargs *pa;
-  grub_uint32_t bootdev, biosdev, unit, slice, part, cont;
+  grub_uint32_t bootdev, biosdev, unit, slice, part;
+  grub_uint64_t lower, upper;
+  grub_err_t err;
+
+  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)
+    {
+      pm->addr = addr;
+      pm->len = size;
+
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
+	  pm->type = OPENBSD_MMAP_AVAILABLE;
+	  break;
+	  
+	default:
+	  pm->type = OPENBSD_MMAP_RESERVED;
+	  break;
+	}
+      pm++;
+
+      return 0;
+    }
 
   pa = (struct grub_openbsd_bootargs *) buf;
 
   pa->ba_type = OPENBSD_BOOTARG_MMAP;
   pm = (struct grub_openbsd_bios_mmap *) (pa + 1);
-  cont = grub_get_mmap_entry (&mmap, 0);
-  if (mmap.size)
-    do
-      {
-	pm->addr = mmap.addr;
-	pm->len = mmap.len;
-	pm->type = mmap.type;
-	pm++;
-
-	if (!cont)
-	  break;
 
-	cont = grub_get_mmap_entry (&mmap, cont);
-      }
-    while (mmap.size);
+  grub_machine_mmap_iterate (hook);
 
   pa->ba_size = (char *) pm - (char *) pa;
   pa->ba_next = (struct grub_openbsd_bootargs *) pm;
@@ -348,8 +371,20 @@ grub_openbsd_boot (void)
   bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) +
 	     (part << OPENBSD_B_PARTSHIFT));
 
+  if ((err = grub_get_lower_upper_memory (&lower, &upper)))
+    return err;
+
+#ifdef GRUB_MACHINE_PCBIOS
+  grub_stop_floppy ();
+#endif
+
+#ifdef GRUB_MACHINE_EFI
+  if (! grub_efi_finish_boot_services ())
+     grub_fatal ("cannot exit boot services");
+#endif
+
   grub_unix_real_boot (entry, bootflags, bootdev, OPENBSD_BOOTARG_APIVER,
-		       0, grub_upper_mem >> 10, grub_lower_mem >> 10,
+		       0, upper >> 10, lower >> 10,
 		       (char *) pa - buf, buf);
 
   /* Not reached.  */
@@ -362,6 +397,8 @@ grub_netbsd_boot (void)
   struct grub_netbsd_btinfo_rootdevice *rootdev;
   struct grub_netbsd_bootinfo *bootinfo;
   grub_uint32_t biosdev, unit, slice, part;
+  grub_uint64_t lower, upper;
+  grub_err_t err;
 
   grub_bsd_get_device (&biosdev, &unit, &slice, &part);
 
@@ -376,8 +413,20 @@ grub_netbsd_boot (void)
   bootinfo->bi_count = 1;
   bootinfo->bi_data[0] = rootdev;
 
+  if ((err = grub_get_lower_upper_memory (&lower, &upper)))
+    return err;
+
+#ifdef GRUB_MACHINE_PCBIOS
+  grub_stop_floppy ();
+#endif
+
+#ifdef GRUB_MACHINE_EFI
+  if (! grub_efi_finish_boot_services ())
+     grub_fatal ("cannot exit boot services");
+#endif
+
   grub_unix_real_boot (entry, bootflags, 0, bootinfo,
-		       0, grub_upper_mem >> 10, grub_lower_mem >> 10);
+		       0, upper >> 10, lower >> 10);
 
   /* Not reached.  */
   return GRUB_ERR_NONE;
@@ -461,10 +510,10 @@ grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr)
   phdr->p_paddr &= 0xFFFFFF;
   paddr = phdr->p_paddr;
 
-  if ((paddr < grub_os_area_addr)
+  /*  if ((paddr < grub_os_area_addr)
       || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
     return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range",
-		       paddr);
+    paddr);*/
 
   if ((!kern_start) || (paddr < kern_start))
     kern_start = paddr;
@@ -577,7 +626,7 @@ grub_rescue_cmd_freebsd (int argc, char *argv[])
 	  (grub_freebsd_add_meta_module (1, argc, argv, kern_start,
 					 kern_end - kern_start)))
 	return;
-      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1);
+      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0);
     }
 }
 
@@ -589,7 +638,7 @@ grub_rescue_cmd_openbsd (int argc, char *argv[])
 	       grub_bsd_parse_flags (argv[1], openbsd_opts, openbsd_flags));
 
   if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
-    grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 1);
+    grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 0);
 }
 
 void
@@ -600,7 +649,7 @@ grub_rescue_cmd_netbsd (int argc, char *argv[])
 	       grub_bsd_parse_flags (argv[1], netbsd_opts, netbsd_flags));
 
   if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
-    grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 1);
+    grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 0);
 }
 
 void
@@ -718,11 +767,11 @@ grub_rescue_cmd_freebsd_module (int argc, char *argv[])
   if ((!file) || (!file->size))
     goto fail;
 
-  if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
+  /*  if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
     {
       grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the module");
       goto fail;
-    }
+      }*/
 
   grub_file_read (file, (char *) kern_end, file->size);
   if ((!grub_errno) &&
diff --git a/loader/i386/bsd_helper.S b/loader/i386/bsd_helper.S
new file mode 100644
index 0000000..9cdea0c
--- /dev/null
+++ b/loader/i386/bsd_helper.S
@@ -0,0 +1,65 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ *       Be careful of that you must not modify some registers. Quote
+ *       from gcc-2.95.2/gcc/config/i386/i386.h:
+
+   1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.
+
+  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+ */
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+#include <grub/symbol.h>
+  
+/*
+ * Use cdecl calling convention for *BSD kernels.
+ */
+
+FUNCTION(grub_unix_real_boot)
+
+	/* Interrupts should be disabled.  */
+        cli
+
+	/* Discard `grub_unix_real_boot' return address.  */
+        popl    %eax
+
+        /* Fetch `entry' address ...  */
+        popl	%eax
+
+        /*
+         * ... and put our return address in its place. The kernel will
+         * ignore it, but it expects %esp to point to it.
+         */
+        call	*%eax
diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c
index ff758d1..055b1cf 100644
--- a/loader/i386/multiboot.c
+++ b/loader/i386/multiboot.c
@@ -30,7 +30,7 @@
 #include <grub/loader.h>
 #include <grub/machine/loader.h>
 #include <grub/multiboot.h>
-#include <grub/machine/init.h>
+#include <grub/machine/machine.h>
 #include <grub/machine/memory.h>
 #include <grub/cpu/multiboot.h>
 #include <grub/elf.h>
@@ -43,6 +43,13 @@
 #include <grub/misc.h>
 #include <grub/gzio.h>
 #include <grub/env.h>
+#include <grub/cpu/loader.h>
+#include <grub/cpu/multiboot.h>
+#include <grub/i386/uppermem.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;
@@ -54,7 +61,12 @@ static grub_size_t code_size;
 static grub_err_t
 grub_multiboot_boot (void)
 {
-  grub_stop_floppy ();
+  grub_printf ("Boot\n");
+
+#ifdef GRUB_MACHINE_EFI
+  if (! grub_efi_finish_boot_services ())
+     grub_fatal ("cannot exit boot services");
+#endif
 
   grub_multiboot_real_boot (entry, mbi_dest);
 
@@ -111,14 +123,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++;
 
@@ -201,6 +223,7 @@ grub_multiboot (int argc, char *argv[])
   struct grub_multiboot_header *header;
   grub_ssize_t len, cmdline_length, boot_loader_name_length;
   grub_uint32_t mmap_length;
+  grub_uint64_t lower, upper;
   int i;
 
   grub_loader_unset ();
@@ -288,7 +311,9 @@ grub_multiboot (int argc, char *argv[])
       grub_multiboot_payload_dest = header->load_addr;
 
       grub_multiboot_payload_size += code_size;
-      playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
+      playground = grub_malloc (RELOCATOR_SIZEOF(forward) 
+				+ grub_multiboot_payload_size 
+				+ RELOCATOR_SIZEOF(backward));
       if (! playground)
 	goto fail;
 
@@ -343,9 +368,12 @@ grub_multiboot (int argc, char *argv[])
 		grub_multiboot_payload_size,
 		grub_multiboot_payload_entry_offset);
 
+  if (grub_get_lower_upper_memory (&lower, &upper))
+    goto fail;
+
   /* Convert from bytes to kilobytes.  */
-  mbi->mem_lower = grub_lower_mem / 1024;
-  mbi->mem_upper = grub_upper_mem / 1024;
+  mbi->mem_lower = lower / 1024;
+  mbi->mem_upper = upper / 1024;
   mbi->flags |= MULTIBOOT_INFO_MEMORY;
 
   cmdline = p = cmdline_addr (grub_multiboot_payload_orig);
@@ -372,7 +400,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/i386/multiboot_helper.S b/loader/i386/multiboot_helper.S
index 1e71120..cd07246 100644
--- a/loader/i386/multiboot_helper.S
+++ b/loader/i386/multiboot_helper.S
@@ -52,7 +52,7 @@ VARIABLE(grub_multiboot_forward_relocator)
 	cld
 	rep
 	movsb
-
+	
 	jmp	*%edx
 VARIABLE(grub_multiboot_forward_relocator_end)
 
@@ -91,7 +91,7 @@ FUNCTION(grub_multiboot_real_boot)
 
 	/* Move the magic value into eax.  */
 	movl	$MULTIBOOT_MAGIC2, %eax
-				
+
 	/* Jump to the relocator.  */
 	popl	%ebp
 	jmp 	*%ebp
diff --git a/loader/i386/xnu_helper.S b/loader/i386/xnu_helper.S
index 901be68..a83bd9a 100644
--- a/loader/i386/xnu_helper.S
+++ b/loader/i386/xnu_helper.S
@@ -15,6 +15,9 @@ FUNCTION(grub_xnu_launch)
 	jmp cont1
 cont1:
 	lgdt gdtdesc
+
+	jmp cont2
+cont2:
 	
 	.code32
 	
@@ -28,8 +31,8 @@ cont1:
 	and $0xffffffef, %eax
 	wrmsr
 
-	jmp cont2
-cont2:	
+	jmp cont3
+cont3:	
 #endif
 
 	.code32
diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c
index abcad9b..8abce88 100644
--- a/loader/multiboot_loader.c
+++ b/loader/multiboot_loader.c
@@ -140,7 +140,7 @@ grub_rescue_cmd_multiboot_loader (int argc, char *argv[])
 
    /* XXX Find a better way to identify this. 
       This is for i386-pc */
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
+#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) || defined (GRUB_MACHINE_EFI)
   if (header_multi_ver_found == 1)
     {
       grub_dprintf ("multiboot_loader",
@@ -153,7 +153,9 @@ grub_rescue_cmd_multiboot_loader (int argc, char *argv[])
     {
       grub_dprintf ("multiboot_loader",
            "Launching multiboot 2 grub_multiboot2() function\n");
+#ifndef GRUB_MACHINE_EFI
       grub_multiboot2 (argc, argv);
+#endif
       module_version_status = 2;
     }
 
@@ -170,7 +172,7 @@ void
 grub_rescue_cmd_module_loader (int argc, char *argv[])
 {
 
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
+#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS) || defined(GRUB_MACHINE_EFI)
   if (module_version_status == 1)
     {
       grub_dprintf("multiboot_loader",
@@ -182,7 +184,9 @@ grub_rescue_cmd_module_loader (int argc, char *argv[])
     {
       grub_dprintf("multiboot_loader",
           "Launching multiboot 2 grub_module2() function\n");
+#ifndef GRUB_MACHINE_EFI
       grub_module2 (argc, argv);
+#endif
     }
 }
 

[-- Attachment #3: uppermem.diff --]
[-- Type: text/x-diff, Size: 3753 bytes --]

diff --git a/conf/i386.rmk b/conf/i386.rmk
index 93f84ce..5338457 100644
--- a/conf/i386.rmk
+++ b/conf/i386.rmk
@@ -14,3 +14,8 @@ pkglib_MODULES += vga_text.mod
 vga_text_mod_SOURCES = term/i386/pc/vga_text.c term/i386/vga_common.c
 vga_text_mod_CFLAGS = $(COMMON_CFLAGS)
 vga_text_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+pkglib_MODULES += uppermem.mod
+uppermem_mod_SOURCES = lib/i386/uppermem.c
+uppermem_mod_CFLAGS = $(COMMON_CFLAGS)
+uppermem_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/lib/i386/uppermem.c b/lib/i386/uppermem.c
new file mode 100644
index 0000000..623535f
--- /dev/null
+++ b/lib/i386/uppermem.c
@@ -0,0 +1,127 @@
+/* Compute amount of lower and upper memory till the first hole */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2009  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef EFIEMU
+#include <grub/machine/memory.h>
+#include <grub/i386/uppermem.h>
+#endif
+
+#include <grub/mm.h>
+#include <grub/misc.h>
+
+struct region
+{
+  grub_uint64_t start;
+  grub_uint64_t end;
+};
+
+#ifdef EFIEMU
+grub_err_t
+grub_efiemu_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper)
+#else
+grub_err_t
+grub_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper)
+#endif
+{
+  grub_size_t count = 0;
+  struct region *regions = 0;
+  int done = 1;
+  unsigned i;
+  struct region t;
+  grub_uint64_t last_addr;
+
+  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)
+    {
+#ifdef EFIEMU  
+      if (type != GRUB_EFIEMU_MEMORY_AVAILABLE)
+#else
+      if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
+#endif
+	return 0;
+      regions = (struct region *) 
+	grub_realloc (regions, (count + 1) * sizeof (struct region));
+      regions[count].start = addr;
+      regions[count].end = addr + size;
+      count++;
+      return 0;
+    }
+
+#ifdef EFIEMU  
+  grub_efiemu_mmap_iterate (hook);
+#else
+  grub_machine_mmap_iterate (hook);
+#endif
+
+  /* Bubble-sort the memory map */
+  while (done)
+    {
+      done = 0;
+      for (i = 0; i < count - 1; i++)
+	if (regions[i].start > regions[i + 1].start)
+	  {
+	    done = 1;
+	    t = regions[i];
+	    regions[i] = regions[i + 1];
+	    regions[i + 1] = t;
+	  }
+    }
+
+  /* Set mem_upper and mem_lower */
+  last_addr = 0;
+  for (i = 0; i < count; i++)
+    {
+      grub_uint64_t end = regions[i].end;
+      /* Don't use memory after 0xa0000*/
+      if (end > 0xa0000)
+	end = 0xa0000;
+
+      /* low memory is finished */
+      if (regions[i].start > end)
+	break;
+
+      /* A hole */
+      if (regions[i].start > last_addr)
+	break;
+
+      last_addr = end;
+    }
+
+  *lower = last_addr;
+
+  /* Skip low memory */
+  for (i = 0; i < count && regions[i].end <= 0x100000; 
+       i++);
+
+  last_addr = 0x100000;
+  for (; i < count; i++)
+    {
+      /* A hole */
+      if (regions[i].start > last_addr)
+	break;
+
+      last_addr = regions[i].end;
+    }
+
+  *upper = (last_addr - 0x100000);
+  grub_free (regions);
+
+  return GRUB_ERR_NONE;
+}

             reply	other threads:[~2009-03-23 12:30 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-23 12:29 phcoder [this message]
2009-03-23 21:16 ` multiboot on EFI uzer cheg
2009-03-23 22:14   ` phcoder
2009-03-23 22:33     ` phcoder
2009-03-24 10:31     ` uzer cheg
2009-03-24 10:54       ` phcoder
2009-03-24 10:58         ` uzer cheg
2009-03-26 19:25           ` Vladimir Serbinenko
2009-03-28 13:13 ` Robert Millan
2009-03-28 14:31   ` Yoshinori K. Okuji
2009-04-01 12:57     ` Robert Millan
2009-04-01 13:58       ` Yoshinori K. Okuji
2009-03-28 22:33   ` phcoder
2009-04-04 16:28     ` phcoder
2009-04-04 16:51       ` phcoder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49C780C3.4010403@gmail.com \
    --to=phcoder@gmail.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.