All of lore.kernel.org
 help / color / mirror / Atom feed
* multiboot module in grub2 --with-platform=efi --target=i386
       [not found] <fd8d61830903180608l2ad4b32ag8122fbc748c64515@mail.gmail.com>
@ 2009-03-18 13:22 ` uzer cheg
  2009-03-18 13:38   ` phcoder
  2009-04-14  8:22   ` Drew Rosen
  0 siblings, 2 replies; 13+ messages in thread
From: uzer cheg @ 2009-03-18 13:22 UTC (permalink / raw)
  To: grub-devel

Dear all,

I'm trying to run Xen Dom0 kernel on my Xserve.
As I see I need Grub's entry like this:

menuentry "Xen 3.3 unstable -i386
{
  search --set /boot/xen-3.3.gz
  multiboot /boot/xen-3.3.gz
  module /boot/vmlinuz-2.6.29-rc8-tip root=LABEL=/ ro console=tty0
  module /boot/initrd-2.6.29-rc8-tip.img
}

I just downloaded from svn latest grub2 (revision 2032) and tried to build it.
# cd grub2
# ./configure --with-platform=efi --target=i386
# make
# ./grub-mkimage -d . -o grub.efi apple appleldr boot cat chain
configfile cpio date ext2 echo fat gpt help hexdump hfs hfsplus
iso9660 linux ls normal pc reboot reiserfs scsi search sleep xfs
multiboot module

I got error message
# grub-mkimage: error: cannot stat ./multiboot.mod

I think that make did not build multiboot.mod for efi.
Help me please.
Tell me please how to enable multiboot and module support in efi grub2?

Thank you in advance.



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-03-18 13:22 ` multiboot module in grub2 --with-platform=efi --target=i386 uzer cheg
@ 2009-03-18 13:38   ` phcoder
  2009-03-18 13:54     ` uzer cheg
  2009-04-14  8:22   ` Drew Rosen
  1 sibling, 1 reply; 13+ messages in thread
From: phcoder @ 2009-03-18 13:38 UTC (permalink / raw)
  To: The development of GRUB 2

It isn't done yet but I'm working on it. You can be tester if you're 
interested
uzer cheg wrote:
> Dear all,
> 
> I'm trying to run Xen Dom0 kernel on my Xserve.
> As I see I need Grub's entry like this:
> 
> menuentry "Xen 3.3 unstable -i386
> {
>   search --set /boot/xen-3.3.gz
>   multiboot /boot/xen-3.3.gz
>   module /boot/vmlinuz-2.6.29-rc8-tip root=LABEL=/ ro console=tty0
>   module /boot/initrd-2.6.29-rc8-tip.img
> }
> 
> I just downloaded from svn latest grub2 (revision 2032) and tried to build it.
> # cd grub2
> # ./configure --with-platform=efi --target=i386
> # make
> # ./grub-mkimage -d . -o grub.efi apple appleldr boot cat chain
> configfile cpio date ext2 echo fat gpt help hexdump hfs hfsplus
> iso9660 linux ls normal pc reboot reiserfs scsi search sleep xfs
> multiboot module
> 
> I got error message
> # grub-mkimage: error: cannot stat ./multiboot.mod
> 
> I think that make did not build multiboot.mod for efi.
> Help me please.
> Tell me please how to enable multiboot and module support in efi grub2?
> 
> Thank you in advance.
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel


-- 

Regards
Vladimir 'phcoder' Serbinenko



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-03-18 13:38   ` phcoder
@ 2009-03-18 13:54     ` uzer cheg
  2009-03-18 14:09       ` phcoder
  0 siblings, 1 reply; 13+ messages in thread
From: uzer cheg @ 2009-03-18 13:54 UTC (permalink / raw)
  To: The development of GRUB 2

Thank you Vladimir.

I'm really interested in it.
I'd like to be a tester.

Is it hard to commit into SVN?

Thank you in advance,
Sergey


It's very interesting for me.
I'd like to be a tester.

On Wed, Mar 18, 2009 at 3:38 PM, phcoder <phcoder@gmail.com> wrote:
> It isn't done yet but I'm working on it. You can be tester if you're
> interested



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-03-18 13:54     ` uzer cheg
@ 2009-03-18 14:09       ` phcoder
  2009-03-18 14:15         ` uzer cheg
  0 siblings, 1 reply; 13+ messages in thread
From: phcoder @ 2009-03-18 14:09 UTC (permalink / raw)
  To: The development of GRUB 2

You don't need to. commit=upload. download=checkout. See instructions on 
grub.enbug.org
uzer cheg wrote:
> Thank you Vladimir.
> 
> I'm really interested in it.
> I'd like to be a tester.
> 
> Is it hard to commit into SVN?
> 
> Thank you in advance,
> Sergey
> 
> 
> It's very interesting for me.
> I'd like to be a tester.
> 
> On Wed, Mar 18, 2009 at 3:38 PM, phcoder <phcoder@gmail.com> wrote:
>> It isn't done yet but I'm working on it. You can be tester if you're
>> interested
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel


-- 

Regards
Vladimir 'phcoder' Serbinenko



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-03-18 14:09       ` phcoder
@ 2009-03-18 14:15         ` uzer cheg
  2009-03-18 14:58           ` phcoder
  0 siblings, 1 reply; 13+ messages in thread
From: uzer cheg @ 2009-03-18 14:15 UTC (permalink / raw)
  To: The development of GRUB 2

Ok.

I mean is hard for you to commit you code into SVN?
Anyway I hope that you inform me when it will be possible to test.
Isn't it?

Thank you.


> You don't need to. commit=upload. download=checkout. See instructions on
> grub.enbug.org
> uzer cheg wrote:



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-03-18 14:15         ` uzer cheg
@ 2009-03-18 14:58           ` phcoder
  0 siblings, 0 replies; 13+ messages in thread
From: phcoder @ 2009-03-18 14:58 UTC (permalink / raw)
  To: The development of GRUB 2

No code will be commited before correct testing
uzer cheg wrote:
> Ok.
> 
> I mean is hard for you to commit you code into SVN?
> Anyway I hope that you inform me when it will be possible to test.
> Isn't it?
> 
> Thank you.
> 
> 
>> You don't need to. commit=upload. download=checkout. See instructions on
>> grub.enbug.org
>> uzer cheg wrote:
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel


-- 

Regards
Vladimir 'phcoder' Serbinenko



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-03-18 13:22 ` multiboot module in grub2 --with-platform=efi --target=i386 uzer cheg
  2009-03-18 13:38   ` phcoder
@ 2009-04-14  8:22   ` Drew Rosen
  2009-04-14  9:12     ` phcoder
  2009-04-14 20:31     ` multiboot module in grub2 --with-platform=efi --target=i386 uzer cheg
  1 sibling, 2 replies; 13+ messages in thread
From: Drew Rosen @ 2009-04-14  8:22 UTC (permalink / raw)
  To: The development of GRUB 2

Hi Uzer Cheg.

Any progress on the Xserve?


On Mar 18, 2009, at 6:22 AM, uzer cheg wrote:

> Dear all,
>
> I'm trying to run Xen Dom0 kernel on my Xserve.
> As I see I need Grub's entry like this:
>
> menuentry "Xen 3.3 unstable -i386
> {
>   search --set /boot/xen-3.3.gz
>   multiboot /boot/xen-3.3.gz
>   module /boot/vmlinuz-2.6.29-rc8-tip root=LABEL=/ ro console=tty0
>   module /boot/initrd-2.6.29-rc8-tip.img
> }
>
> I just downloaded from svn latest grub2 (revision 2032) and tried to  
> build it.
> # cd grub2
> # ./configure --with-platform=efi --target=i386
> # make
> # ./grub-mkimage -d . -o grub.efi apple appleldr boot cat chain
> configfile cpio date ext2 echo fat gpt help hexdump hfs hfsplus
> iso9660 linux ls normal pc reboot reiserfs scsi search sleep xfs
> multiboot module
>
> I got error message
> # grub-mkimage: error: cannot stat ./multiboot.mod
>
> I think that make did not build multiboot.mod for efi.
> Help me please.
> Tell me please how to enable multiboot and module support in efi  
> grub2?
>
> Thank you in advance.
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-04-14  8:22   ` Drew Rosen
@ 2009-04-14  9:12     ` phcoder
  2009-04-15 13:58       ` Drew Rosen
  2009-04-14 20:31     ` multiboot module in grub2 --with-platform=efi --target=i386 uzer cheg
  1 sibling, 1 reply; 13+ messages in thread
From: phcoder @ 2009-04-14  9:12 UTC (permalink / raw)
  To: The development of GRUB 2

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

I did the patch for it, however it seems nobody is interested to test 
it. With it I'm able to boot grub invaders on qemu-tianocore. And I have 
no xserve. For convenience I resend the patch. If it works I'll split it 
into components as required for review. Also have a look at 
http://grub.enbug.org/TestingOnMacbook for some relevant fixes (in linux 
section).
Drew Rosen wrote:
> Hi Uzer Cheg.
> 
> Any progress on the Xserve?
> 
> 
> On Mar 18, 2009, at 6:22 AM, uzer cheg wrote:
> 
>> Dear all,
>>
>> I'm trying to run Xen Dom0 kernel on my Xserve.
>> As I see I need Grub's entry like this:
>>
>> menuentry "Xen 3.3 unstable -i386
>> {
>>   search --set /boot/xen-3.3.gz
>>   multiboot /boot/xen-3.3.gz
>>   module /boot/vmlinuz-2.6.29-rc8-tip root=LABEL=/ ro console=tty0
>>   module /boot/initrd-2.6.29-rc8-tip.img
>> }
>>
>> I just downloaded from svn latest grub2 (revision 2032) and tried to 
>> build it.
>> # cd grub2
>> # ./configure --with-platform=efi --target=i386
>> # make
>> # ./grub-mkimage -d . -o grub.efi apple appleldr boot cat chain
>> configfile cpio date ext2 echo fat gpt help hexdump hfs hfsplus
>> iso9660 linux ls normal pc reboot reiserfs scsi search sleep xfs
>> multiboot module
>>
>> I got error message
>> # grub-mkimage: error: cannot stat ./multiboot.mod
>>
>> I think that make did not build multiboot.mod for efi.
>> Help me please.
>> Tell me please how to enable multiboot and module support in efi grub2?
>>
>> Thank you in advance.
>>
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
> 
> 
> 
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel


-- 

Regards
Vladimir 'phcoder' Serbinenko

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

diff --git a/conf/common.rmk b/conf/common.rmk
index b0a78b0..fb36edb 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -525,3 +525,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 41c45db..1cd7484 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -101,8 +101,7 @@ grub_install_SOURCES = util/i386/pc/grub-install.in
 pkglib_MODULES = linux.mod normal.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
@@ -200,10 +199,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 399376f..e185337 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -81,7 +81,17 @@ grub_install_SOURCES = util/i386/efi/grub-install.in
 # Modules.
 pkglib_MODULES = kernel.mod normal.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
+	datetime.mod date.mod datehook.mod loadbios.mod \
+	fixvideo.mod multiboot.mod
+# For multiboot.mod.
+multiboot_mod_SOURCES = loader/i386/multiboot.c \
+			 loader/i386/multiboot_helper.S \
+                         loader/multiboot2.c \
+                         loader/efi/multiboot2.c \
+                         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
@@ -91,14 +101,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/command.c kern/corecmd.c \
+	kern/efi/mmap.c kern/time.c kern/list.c kern/handler.c kern/command.c kern/corecmd.c \
 	kern/i386/tsc.c kern/i386/pit.c \
 	kern/generic/rtc_get_time_ms.c \
 	kern/generic/millisleep.c
 kernel_mod_HEADERS = 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 command.h
+	efi/efi.h efi/time.h efi/disk.h efi/memory.h list.h handler.h command.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 96d9c10..df8c062 100644
--- a/conf/i386-ieee1275.rmk
+++ b/conf/i386-ieee1275.rmk
@@ -103,7 +103,7 @@ grub_install_SOURCES = util/ieee1275/grub-install.in
 pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod		\
 	multiboot.mod aout.mod serial.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
@@ -128,6 +128,7 @@ normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
 # For multiboot.mod.
 multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
+			loader/i386/multiboot.c \
 			loader/i386/multiboot_helper.S \
 			 loader/multiboot2.c \
 			 loader/multiboot_loader.c
@@ -200,10 +201,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 7dfb854..82ede6e 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -289,16 +289,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 usb.mod
 usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
 usb_mod_CFLAGS = $(COMMON_CFLAGS)
@@ -354,11 +344,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 93f84ce..ddf7118 100644
--- a/conf/i386.rmk
+++ b/conf/i386.rmk
@@ -14,3 +14,21 @@ 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)
+
+pkglib_MODULES += aout.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)
+
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index 361fb85..c084370 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -111,8 +111,7 @@ pkglib_MODULES = halt.mod \
 	reboot.mod \
 	suspend.mod \
         multiboot.mod \
-	memdisk.mod \
-	lsmmap.mod
+	memdisk.mod 
 
 # For linux.mod.
 linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
@@ -167,10 +166,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 f50f18e..723dff5 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;
 };
 
@@ -222,4 +224,7 @@ struct grub_netbsd_btinfo_bootdisk
   int partition;
 };
 
+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 afd3eb9..685c2e0 100644
--- a/include/grub/i386/loader.h
+++ b/include/grub/i386/loader.h
@@ -27,12 +27,14 @@ extern grub_uint32_t EXPORT_VAR(grub_linux_prot_size);
 extern char *EXPORT_VAR(grub_linux_tmp_addr);
 extern char *EXPORT_VAR(grub_linux_real_addr);
 extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage);
-extern grub_addr_t EXPORT_VAR(grub_os_area_addr);
-extern grub_size_t EXPORT_VAR(grub_os_area_size);
 
 grub_err_t EXPORT_FUNC(grub_linux16_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[]);
+void grub_rescue_cmd_initrd (int argc, char *argv[]);
+
+void EXPORT_FUNC(grub_stop_floppy) (void);
 
 #endif /* ! GRUB_LOADER_CPU_HEADER */
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/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/i386/uppermem.h b/include/grub/i386/uppermem.h
new file mode 100644
index 0000000..bceed3e
--- /dev/null
+++ b/include/grub/i386/uppermem.h
@@ -0,0 +1,7 @@
+#ifndef GRUB_UPPERMEM_HEADER
+#define GRUB_UPPERMEM_HEADER
+
+grub_err_t
+grub_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t *upper);
+
+#endif
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
index 3b5139e..48bc3f2 100644
--- a/include/grub/ieee1275/ieee1275.h
+++ b/include/grub/ieee1275/ieee1275.h
@@ -169,7 +169,6 @@ grub_err_t EXPORT_FUNC(grub_children_iterate) (char *devpath,
      int (*hook) (struct grub_ieee1275_devalias *alias));
 grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
      (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
 
 char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path);
 char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path);
diff --git a/include/grub/loader.h b/include/grub/loader.h
index 1ae5fdd..544b2f5 100644
--- a/include/grub/loader.h
+++ b/include/grub/loader.h
@@ -41,4 +41,8 @@ void EXPORT_FUNC(grub_loader_unset) (void);
    depending on the setting by grub_loader_set.  */
 grub_err_t EXPORT_FUNC(grub_loader_boot) (void);
 
+int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
+
+void EXPORT_FUNC(grub_declaimmap) (grub_addr_t addr, grub_size_t size);
+
 #endif /* ! GRUB_LOADER_HEADER */
diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h
index bfbffcc..1e6701e 100644
--- a/include/grub/multiboot2.h
+++ b/include/grub/multiboot2.h
@@ -39,12 +39,6 @@ void
 grub_mb2_arch_unload (struct multiboot_tag_header *tags);
 
 grub_err_t
-grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr);
-
-grub_err_t 
-grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr);
-
-grub_err_t
 grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr);
 
 grub_err_t
diff --git a/include/grub/types.h b/include/grub/types.h
index 8d51b66..faf2257 100644
--- a/include/grub/types.h
+++ b/include/grub/types.h
@@ -100,6 +100,16 @@ typedef grub_int32_t	grub_ssize_t;
 # define LONG_MAX 2147483647UL
 #endif
 
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
+#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
+#define PTR_TO_UINT32(x) ((grub_uint32_t)(x))
+#else
+#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x))
+#define PTR_TO_UINT64(x) ((grub_uint64_t)(x))
+#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x))
+#endif
+
 /* The type for representing a file offset.  */
 typedef grub_uint64_t	grub_off_t;
 
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..3f795cb
--- /dev/null
+++ b/kern/efi/mmap.c
@@ -0,0 +1,177 @@
+/*
+ *  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>
+#include <grub/loader.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;
+}
+
+/* XXX: Manage subpage allocations */
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+  void *ret;
+  ret = grub_efi_allocate_pages (addr  & (~0xfff), 
+				 (size + (addr & 0xfff) + 0xfff) >> 12);
+  return (! ret) ? -1 : 0;
+}
+
+/* XXX: Manage subpage allocations */
+void
+grub_declaimmap (grub_addr_t addr, grub_size_t size)
+{
+  grub_efi_free_pages (addr  & (~0xfff), 
+		       (size + (addr & 0xfff) + 0xfff) >> 12);
+}
diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c
index 1348488..9c1aee0 100644
--- a/kern/i386/coreboot/init.c
+++ b/kern/i386/coreboot/init.c
@@ -155,3 +155,18 @@ grub_arch_modules_addr (void)
 {
   return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
 }
+
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+  if ((addr < grub_os_area_addr)
+      || (addr + size > grub_os_area_addr + grub_os_area_size))
+    return -1;
+  return 0;
+}
+
+void
+grub_declaimmap (grub_addr_t addr __attribute__ ((unused)), 
+		 grub_size_t size  __attribute__ ((unused)))
+{
+}
diff --git a/kern/i386/loader.S b/kern/i386/loader.S
index bbd2187..d9b37bf 100644
--- a/kern/i386/loader.S
+++ b/kern/i386/loader.S
@@ -117,26 +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)
-
-	/* 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/kern/i386/pc/init.c b/kern/i386/pc/init.c
index 6191412..17d5343 100644
--- a/kern/i386/pc/init.c
+++ b/kern/i386/pc/init.c
@@ -43,8 +43,8 @@ struct mem_region
 static struct mem_region mem_regions[MAX_REGIONS];
 static int num_regions;
 
-grub_addr_t grub_os_area_addr;
-grub_size_t grub_os_area_size;
+static grub_addr_t grub_os_area_addr;
+static grub_size_t grub_os_area_size;
 grub_size_t grub_lower_mem, grub_upper_mem;
 
 void 
@@ -233,3 +233,18 @@ grub_arch_modules_addr (void)
   return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
     + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
 }
+
+int
+grub_claimmap (grub_addr_t addr, grub_size_t size)
+{
+  if ((addr < grub_os_area_addr)
+      || (addr + size > grub_os_area_addr + grub_os_area_size))
+    return -1;
+  return 0;
+}
+
+void
+grub_declaimmap (grub_addr_t addr __attribute__ ((unused)), 
+		 grub_size_t size  __attribute__ ((unused)))
+{
+}
diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c
index d70c3ba..c713d4c 100644
--- a/kern/ieee1275/openfw.c
+++ b/kern/ieee1275/openfw.c
@@ -194,6 +194,13 @@ grub_claimmap (grub_addr_t addr, grub_size_t size)
   return 0;
 }
 
+/* XXX Could someone with better OFW knowledge that me fill this? */
+void
+grub_declaimmap (grub_addr_t addr __attribute__ ((unused)), 
+		 grub_size_t size  __attribute__ ((unused)))
+{
+}
+
 /* Get the device arguments of the Open Firmware node name `path'.  */
 static char *
 grub_ieee1275_get_devargs (const char *path)
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;
+}
diff --git a/loader/efi/multiboot2.c b/loader/efi/multiboot2.c
new file mode 100644
index 0000000..44bb542
--- /dev/null
+++ b/loader/efi/multiboot2.c
@@ -0,0 +1,75 @@
+/* multiboot2.c - boot a multiboot 2 OS image. */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  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 <multiboot2.h>
+#include <grub/multiboot2.h>
+#include <grub/elf.h>
+#include <grub/err.h>
+#include <grub/machine/loader.h>
+#include <grub/mm.h>
+
+grub_err_t
+grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
+{
+  grub_addr_t modaddr;
+
+  modaddr = (grub_addr_t) grub_memalign (MULTIBOOT2_MOD_ALIGN, size);
+  if (! modaddr)
+    return grub_errno;
+
+  *addr = modaddr;
+  return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size)
+{
+  grub_free((void *) addr);
+  return GRUB_ERR_NONE;
+}
+
+void
+grub_mb2_arch_boot (grub_addr_t entry, void *tags)
+{
+  grub_multiboot2_real_boot (entry, tags);
+}
+
+void
+grub_mb2_arch_unload (struct multiboot_tag_header *tags)
+{
+   struct multiboot_tag_header *tag;
+   
+   /* Free all module memory in the tag list.  */
+   for_each_tag (tag, tags)
+     {
+       if (tag->key == MULTIBOOT2_TAG_MODULE)
+         {
+           struct multiboot_tag_module *module =
+              (struct multiboot_tag_module *) tag;
+           grub_free((void *) module->addr);
+         }
+     }
+}
+
+grub_err_t
+grub_mb2_tags_arch_create (void)
+{
+  /* XXX Create system table et al. */
+  return GRUB_ERR_NONE;
+}
diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c
index 355cb3f..4023566 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/dl.h>
@@ -30,8 +30,13 @@
 #include <grub/misc.h>
 #include <grub/gzio.h>
 #include <grub/aout.h>
+#include <grub/i386/uppermem.h>
 #include <grub/command.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,8 +510,7 @@ 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)
-      || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
+  if (grub_claimmap (paddr, phdr->p_memsz) < 0)
     return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range",
 		       paddr);
 
@@ -578,7 +626,7 @@ grub_cmd_freebsd (grub_command_t cmd __attribute__ ((unused)),
 	  (grub_freebsd_add_meta_module (1, argc, argv, kern_start,
 					 kern_end - kern_start)))
 	return grub_errno;
-      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1);
+      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0);
     }
 
   return grub_errno;
@@ -593,7 +641,7 @@ grub_cmd_openbsd (grub_command_t cmd __attribute__ ((unused)),
 	       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);
 
   return grub_errno;
 }
@@ -607,7 +655,7 @@ grub_cmd_netbsd (grub_command_t cmd __attribute__ ((unused)),
 	       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);
 
   return grub_errno;
 }
@@ -725,7 +773,7 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
   if ((!file) || (!file->size))
     goto fail;
 
-  if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
+  if (grub_claimmap (kern_end, file->size) < 0)
     {
       grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the module");
       goto fail;
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/efi/linux.c b/loader/i386/efi/linux.c
index 100b268..e729a8e 100644
--- a/loader/i386/efi/linux.c
+++ b/loader/i386/efi/linux.c
@@ -18,6 +18,7 @@
 
 #include <grub/loader.h>
 #include <grub/machine/loader.h>
+#include <grub/machine/memory.h>
 #include <grub/file.h>
 #include <grub/disk.h>
 #include <grub/err.h>
@@ -46,9 +47,10 @@ static int loaded;
 static void *real_mode_mem;
 static void *prot_mode_mem;
 static void *initrd_mem;
-static grub_efi_uintn_t real_mode_pages;
-static grub_efi_uintn_t prot_mode_pages;
-static grub_efi_uintn_t initrd_pages;
+static grub_size_t real_size;
+static grub_size_t mmap_size;
+static grub_size_t prot_size;
+static grub_size_t initrd_size;
 static void *mmap_buf;
 
 static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
@@ -95,26 +97,26 @@ page_align (grub_size_t size)
 
 /* Find the optimal number of pages for the memory map. Is it better to
    move this code to efi/mm.c?  */
-static grub_efi_uintn_t
+static grub_size_t
 find_mmap_size (void)
 {
-  static grub_efi_uintn_t mmap_size = 0;
+  static grub_efi_uintn_t cache_mmap_size = 0;
 
-  if (mmap_size != 0)
-    return mmap_size;
+  if (cache_mmap_size != 0)
+    return cache_mmap_size;
   
-  mmap_size = (1 << 12);
+  cache_mmap_size = (1 << 12);
   while (1)
     {
       int ret;
       grub_efi_memory_descriptor_t *mmap;
       grub_efi_uintn_t desc_size;
       
-      mmap = grub_malloc (mmap_size);
+      mmap = grub_malloc (cache_mmap_size);
       if (! mmap)
 	return 0;
 
-      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
+      ret = grub_efi_get_memory_map (&cache_mmap_size, mmap, 0, &desc_size, 0);
       grub_free (mmap);
       
       if (ret < 0)
@@ -122,14 +124,14 @@ find_mmap_size (void)
       else if (ret > 0)
 	break;
 
-      mmap_size += (1 << 12);
+      cache_mmap_size += (1 << 12);
     }
 
   /* Increase the size a bit for safety, because GRUB allocates more on
      later, and EFI itself may allocate more.  */
-  mmap_size += (1 << 12);
+  cache_mmap_size += (1 << 12);
 
-  return page_align (mmap_size);
+  return page_align (cache_mmap_size);
 }
 
 static void
@@ -137,19 +139,19 @@ free_pages (void)
 {
   if (real_mode_mem)
     {
-      grub_efi_free_pages ((grub_addr_t) real_mode_mem, real_mode_pages);
+      grub_declaimmap ((grub_addr_t) real_mode_mem, real_size + mmap_size);
       real_mode_mem = 0;
     }
 
   if (prot_mode_mem)
     {
-      grub_efi_free_pages ((grub_addr_t) prot_mode_mem, prot_mode_pages);
+      grub_declaimmap ((grub_addr_t) prot_mode_mem, prot_size);
       prot_mode_mem = 0;
     }
   
   if (initrd_mem)
     {
-      grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
+      grub_declaimmap ((grub_addr_t) initrd_mem, initrd_size);
       initrd_mem = 0;
     }
 }
@@ -161,9 +163,8 @@ allocate_pages (grub_size_t prot_size)
 {
   grub_efi_uintn_t desc_size;
   grub_efi_memory_descriptor_t *mmap, *mmap_end;
-  grub_efi_uintn_t mmap_size, tmp_mmap_size;
+  grub_efi_uintn_t tmp_mmap_size;
   grub_efi_memory_descriptor_t *desc;
-  grub_size_t real_size;
   
   /* Make sure that each size is aligned to a page boundary.  */
   real_size = GRUB_LINUX_CL_END_OFFSET;
@@ -173,11 +174,6 @@ allocate_pages (grub_size_t prot_size)
   grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
 		(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
   
-  /* Calculate the number of pages; Combine the real mode code with
-     the memory map buffer for simplicity.  */
-  real_mode_pages = ((real_size + mmap_size) >> 12);
-  prot_mode_pages = (prot_size >> 12);
-  
   /* Initialize the memory pointers with NULL for convenience.  */
   real_mode_mem = 0;
   prot_mode_mem = 0;
@@ -192,44 +188,40 @@ allocate_pages (grub_size_t prot_size)
     grub_fatal ("cannot get memory map");
 
   mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
-  
-  /* First, find free pages for the real mode code
-     and the memory map buffer.  */
-  for (desc = mmap;
-       desc < mmap_end;
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+
+  /* FIXME: Should request low memory from the heap when this feature is
+     implemented.  */
+
+  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)
     {
-      /* Probably it is better to put the real mode code in the traditional
-	 space for safety.  */
-      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
-	  && desc->physical_start <= 0x90000
-	  && desc->num_pages >= real_mode_pages)
+      /* We must put real mode code in the traditional space.  */
+
+      if (type == GRUB_MACHINE_MEMORY_AVAILABLE
+	  && addr <= 0x90000)
 	{
-	  grub_efi_physical_address_t physical_end;
-	  grub_efi_physical_address_t addr;
-	  
-	  physical_end = desc->physical_start + (desc->num_pages << 12);
-	  if (physical_end > 0x90000)
-	    physical_end = 0x90000;
-
-	  grub_dprintf ("linux", "physical_start = %x, physical_end = %x\n",
-			(unsigned) desc->physical_start,
-			(unsigned) physical_end);
-	  addr = physical_end - real_size - mmap_size;
 	  if (addr < 0x10000)
-	    continue;
+	    {
+	      size += addr - 0x10000;
+	      addr = 0x10000;
+	    }
 
-	  grub_dprintf ("linux", "trying to allocate %u pages at %lx\n",
-			(unsigned) real_mode_pages, (unsigned long) addr);
-	  real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages);
-	  if (! real_mode_mem)
-	    grub_fatal ("cannot allocate pages");
-	  
-	  desc->num_pages -= real_mode_pages;
-	  break;
+	  if (addr + size > 0x90000)
+	    size = 0x90000 - addr;
+
+	  if (real_size + mmap_size > size)
+	    return 0;
+
+	  real_mode_mem = (void *) ((addr + size) - (real_size + mmap_size));
+	  if (grub_claimmap ((grub_addr_t) real_mode_mem, 
+			     real_size + mmap_size) < 0)
+	    return 0;
+	  return 1;
 	}
-    }
 
+      return 0;
+    }
+  grub_machine_mmap_iterate (hook);
   if (! real_mode_mem)
     {
       grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
@@ -238,20 +230,20 @@ allocate_pages (grub_size_t prot_size)
 
   mmap_buf = (void *) ((char *) real_mode_mem + real_size);
 	      
+  prot_mode_mem = (void *) 0x100000;
   /* Next, find free pages for the protected mode code.  */
   /* XXX what happens if anything is using this address?  */
-  prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages);
-  if (! prot_mode_mem)
+  if (grub_claimmap (0x100000, prot_size) < 0)
     {
       grub_error (GRUB_ERR_OUT_OF_MEMORY,
 		  "cannot allocate protected mode pages");
       goto fail;
     }
 
-  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
-		"prot_mode_mem = %lx, prot_mode_pages = %x\n",
-		(unsigned long) real_mode_mem, (unsigned) real_mode_pages,
-		(unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
+  grub_dprintf ("linux", "real_mode_mem = %lx, real_size = %x, "
+                "prot_mode_mem = %lx, prot_size = %x\n",
+                (unsigned long) real_mode_mem, (unsigned) real_size,
+                (unsigned long) prot_mode_mem, (unsigned) prot_size);
 
   grub_free (mmap);
   return 1;
@@ -300,7 +292,6 @@ grub_linux_boot (void)
   grub_efi_uintn_t map_key;
   grub_efi_uintn_t desc_size;
   grub_efi_uint32_t desc_version;
-  grub_efi_memory_descriptor_t *desc;
   int e820_num;
   
   params = real_mode_mem;
@@ -318,77 +309,46 @@ grub_linux_boot (void)
 			       &desc_size, &desc_version) <= 0)
     grub_fatal ("cannot get memory map");
 
-  e820_num = 0;
-  for (desc = mmap_buf;
-       desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
+  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)
     {
-      switch (desc->type)
-	{
-	case GRUB_EFI_ACPI_RECLAIM_MEMORY:
+      switch (type)
+        {
+        case GRUB_MACHINE_MEMORY_AVAILABLE:
 	  grub_e820_add_region (params->e820_map, &e820_num,
-				desc->physical_start,
-				desc->num_pages << 12,
-				GRUB_E820_ACPI);
+				addr, size, GRUB_E820_RAM);
 	  break;
 
-	case GRUB_EFI_ACPI_MEMORY_NVS:
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+        case GRUB_MACHINE_MEMORY_ACPI:
 	  grub_e820_add_region (params->e820_map, &e820_num,
-				desc->physical_start,
-				desc->num_pages << 12,
-				GRUB_E820_NVS);
+				addr, size, GRUB_E820_ACPI);
 	  break;
+#endif
 
-	case GRUB_EFI_RUNTIME_SERVICES_CODE:
+#ifdef GRUB_MACHINE_MEMORY_NVS
+        case GRUB_MACHINE_MEMORY_NVS:
 	  grub_e820_add_region (params->e820_map, &e820_num,
-				desc->physical_start,
-				desc->num_pages << 12,
-				GRUB_E820_EXEC_CODE);
+				addr, size, GRUB_E820_NVS);
 	  break;
+#endif
 
-	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:
-	  {
-	    grub_uint64_t start, size, end;
-
-	    start = desc->physical_start;
-	    size = desc->num_pages << 12;
-	    end = start + size;
-
-	    /* Skip A0000 - 100000 region.  */
-	    if ((start < 0x100000ULL) && (end > 0xA0000ULL))
-	      {
-		if (start < 0xA0000ULL)
-		  {
-		    grub_e820_add_region (params->e820_map, &e820_num,
-					  start,
-					  0xA0000ULL - start,
-					  GRUB_E820_RAM);
-		  }
-
-		if (end <= 0x100000ULL)
-		  continue;
-
-		start = 0x100000ULL;
-		size = end - start;
-	      }
-
-	    grub_e820_add_region (params->e820_map, &e820_num,
-				  start, size, GRUB_E820_RAM);
-	    break;
-	  }
-
-	default:
+#ifdef GRUB_MACHINE_MEMORY_CODE
+        case GRUB_MACHINE_MEMORY_CODE:
 	  grub_e820_add_region (params->e820_map, &e820_num,
-				desc->physical_start,
-				desc->num_pages << 12,
-				GRUB_E820_RESERVED);
-	}
+				addr, size, GRUB_E820_EXEC_CODE);
+	  break;
+#endif
+
+        default:
+          grub_e820_add_region (params->e820_map, &e820_num,
+                                addr, size, GRUB_E820_RESERVED);
+        }
+      return 0;
     }
 
+  e820_num = 0;
+  grub_machine_mmap_iterate (hook);
   params->mmap_size = e820_num;
 
   if (! grub_efi_exit_boot_services (map_key))
@@ -633,7 +593,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   struct linux_kernel_header lh;
   struct linux_kernel_params *params;
   grub_uint8_t setup_sects;
-  grub_size_t real_size, prot_size;
   grub_ssize_t len;
   int i;
   char *dest;
@@ -916,9 +875,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
   grub_ssize_t size;
   grub_addr_t addr_min, addr_max;
   grub_addr_t addr;
-  grub_efi_uintn_t mmap_size;
-  grub_efi_memory_descriptor_t *desc;
-  grub_efi_uintn_t desc_size;
   struct linux_kernel_header *lh;
   
   if (argc == 0)
@@ -938,11 +894,24 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
     goto fail;
 
   size = grub_file_size (file);
-  initrd_pages = (page_align (size) >> 12);
+  initrd_size = page_align (size);
 
   lh = (struct linux_kernel_header *) real_mode_mem;
+
+  /* Get the highest address available for the initrd.  */
+  if (grub_le_to_cpu16 (lh->version) >= 0x0203)
+    {
+      addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
+
+      /* XXX in reality, Linux specifies a bogus value, so
+	 it is necessary to make sure that ADDR_MAX does not exceed
+	 0x3fffffff.  */
+      if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
+	addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
+    }
+  else
+    addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
   
-  addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
   if (linux_mem_size != 0 && linux_mem_size < addr_max)
     addr_max = linux_mem_size;
   
@@ -953,49 +922,21 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
   addr_max -= 0x10000;
 
   /* Usually, the compression ratio is about 50%.  */
-  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
-	     + page_align (size);
+  addr_min = (grub_addr_t) prot_mode_mem + prot_size * 3
+             + page_align (size);
   
-  /* Find the highest address to put the initrd.  */
-  mmap_size = find_mmap_size ();
-  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
-    grub_fatal ("cannot get memory map");
-
-  addr = 0;
-  for (desc = mmap_buf;
-       desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
-       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
-    {
-      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
-	  && desc->num_pages >= initrd_pages)
-	{
-	  grub_efi_physical_address_t physical_end;
-	  
-	  physical_end = desc->physical_start + (desc->num_pages << 12);
-	  if (physical_end > addr_max)
-	    physical_end = addr_max;
-
-	  if (physical_end < page_align (size))
-	    continue;
-
-	  physical_end -= page_align (size);
-
-	  if ((physical_end >= addr_min) &&
-	      (physical_end >= desc->physical_start) &&
-	      (physical_end > addr))
-	    addr = physical_end;
-	}
-    }
+  /* Put the initrd as high as possible, 4KiB aligned.  */
+  addr = (addr_max - size) & ~0xFFF;
+  while (addr >= addr_min && grub_claimmap (addr, initrd_size) < 0)
+    addr -= 0x1000;
 
-  if (addr == 0)
+  if (addr < addr_min)
     {
-      grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big");
       goto fail;
     }
   
-  initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);
-  if (! initrd_mem)
-    grub_fatal ("cannot allocate pages");
+  initrd_mem = (void *) addr;
   
   if (grub_file_read (file, initrd_mem, size) != size)
     {
diff --git a/loader/i386/linux.c b/loader/i386/linux.c
index 01d10d5..4811f1a 100644
--- a/loader/i386/linux.c
+++ b/loader/i386/linux.c
@@ -45,9 +45,10 @@ static int loaded;
 static void *real_mode_mem;
 static void *prot_mode_mem;
 static void *initrd_mem;
-static grub_uint32_t real_mode_pages;
-static grub_uint32_t prot_mode_pages;
-static grub_uint32_t initrd_pages;
+static grub_size_t real_size;
+static grub_size_t mmap_size;
+static grub_size_t prot_size;
+static grub_size_t initrd_size;
 
 static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
   {
@@ -182,7 +183,24 @@ find_mmap_size (void)
 static void
 free_pages (void)
 {
-  real_mode_mem = prot_mode_mem = initrd_mem = 0;
+  if (real_mode_mem)
+    {
+      grub_declaimmap ((grub_addr_t) real_mode_mem, real_size 
+			       + mmap_size);
+      real_mode_mem = 0;
+    }
+
+  if (prot_mode_mem)
+    {
+      grub_declaimmap ((grub_addr_t) prot_mode_mem, prot_size);
+      prot_mode_mem = 0;
+    }
+  
+  if (initrd_mem)
+    {
+      grub_declaimmap ((grub_addr_t) initrd_mem, initrd_size);
+      initrd_mem = 0;
+    }
 }
 
 /* Allocate pages for the real mode code and the protected mode code
@@ -190,8 +208,6 @@ free_pages (void)
 static int
 allocate_pages (grub_size_t prot_size)
 {
-  grub_size_t real_size, mmap_size;
-
   /* Make sure that each size is aligned to a page boundary.  */
   real_size = GRUB_LINUX_CL_END_OFFSET;
   prot_size = page_align (prot_size);
@@ -200,11 +216,6 @@ allocate_pages (grub_size_t prot_size)
   grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
 		(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
   
-  /* Calculate the number of pages; Combine the real mode code with
-     the memory map buffer for simplicity.  */
-  real_mode_pages = ((real_size + mmap_size) >> 12);
-  prot_mode_pages = (prot_size >> 12);
-  
   /* Initialize the memory pointers with NULL for convenience.  */
   free_pages ();
   
@@ -232,6 +243,8 @@ allocate_pages (grub_size_t prot_size)
 	    return 0;
 
 	  real_mode_mem = (void *) ((addr + size) - (real_size + mmap_size));
+	  if (grub_claimmap (real_mode_mem, real_size + mmap_size) < 0)
+	    return 0;
 	  return 1;
 	}
 
@@ -245,6 +258,14 @@ allocate_pages (grub_size_t prot_size)
     }
 
   prot_mode_mem = (void *) 0x100000;
+  /* Next, find free pages for the protected mode code.  */
+  /* XXX what happens if anything is using this address?  */
+  if (grub_claimmap (0x100000, prot_size) < 0)
+    {
+      grub_error (GRUB_ERR_OUT_OF_MEMORY,
+		  "cannot allocate protected mode pages");
+      goto fail;
+    }
 
   grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
                 "prot_mode_mem = %lx, prot_mode_pages = %x\n",
@@ -396,6 +417,27 @@ grub_linux_boot (void)
 				addr, size, GRUB_E820_RAM);
 	  break;
 
+#ifdef GRUB_MACHINE_MEMORY_ACPI
+        case GRUB_MACHINE_MEMORY_ACPI:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_ACPI);
+	  break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_NVS
+        case GRUB_MACHINE_MEMORY_NVS:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_NVS);
+	  break;
+#endif
+
+#ifdef GRUB_MACHINE_MEMORY_CODE
+        case GRUB_MACHINE_MEMORY_CODE:
+	  grub_e820_add_region (params->e820_map, &e820_num,
+				addr, size, GRUB_E820_EXEC_CODE);
+	  break;
+#endif
+
         default:
           grub_e820_add_region (params->e820_map, &e820_num,
                                 addr, size, GRUB_E820_RESERVED);
@@ -457,7 +499,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   struct linux_kernel_header lh;
   struct linux_kernel_params *params;
   grub_uint8_t setup_sects;
-  grub_size_t real_size, prot_size;
   grub_ssize_t len;
   int i;
   char *dest;
@@ -693,7 +734,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
     goto fail;
 
   size = grub_file_size (file);
-  initrd_pages = (page_align (size) >> 12);
+  initrd_size = page_align (size);
 
   lh = (struct linux_kernel_header *) real_mode_mem;
 
@@ -724,11 +765,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
   addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
              + page_align (size);
   
-  if (addr_max > grub_os_area_addr + grub_os_area_size)
-    addr_max = grub_os_area_addr + grub_os_area_size;
-
   /* Put the initrd as high as possible, 4KiB aligned.  */
   addr = (addr_max - size) & ~0xFFF;
+  while (addr >= addr_min && grub_claimmap (addr, initrd_size) < 0)
+    addr -= 0x1000;
 
   if (addr < addr_min)
     {
diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c
index 27042a5..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,6 +61,13 @@ static grub_size_t code_size;
 static grub_err_t
 grub_multiboot_boot (void)
 {
+  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);
 
   /* Not reached.  */
@@ -109,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++;
 
@@ -199,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 ();
@@ -286,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;
 
@@ -341,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);
@@ -370,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/pc/linux.c b/loader/i386/pc/linux.c
index 8ff97f4..4823ddc 100644
--- a/loader/i386/pc/linux.c
+++ b/loader/i386/pc/linux.c
@@ -71,11 +71,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
   if (! file)
     goto fail;
 
-  if ((grub_size_t) grub_file_size (file) > grub_os_area_size)
+  if (grub_claimmap (GRUB_LINUX_BZIMAGE_ADDR, grub_file_size (file)) < 0)
     {
-      grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x%x)",
-		  (grub_size_t) grub_file_size (file),
-		  grub_os_area_size);
+      grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x)",
+		  (grub_size_t) grub_file_size (file));
       goto fail;
     }
 
@@ -340,9 +339,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
      worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
   addr_max -= 0x10000;
 
-  if (addr_max > grub_os_area_addr + grub_os_area_size)
-    addr_max = grub_os_area_addr + grub_os_area_size;
-
   addr_min = (grub_addr_t) grub_linux_tmp_addr + GRUB_LINUX_CL_END_OFFSET;
 
   file = grub_file_open (argv[0]);
@@ -353,6 +349,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
 
   /* Put the initrd as high as possible, 4KiB aligned.  */
   addr = (addr_max - size) & ~0xFFF;
+  while (addr >= addr_min && grub_claimmap (addr, size) < 0)
+    addr -= 0x1000;
 
   if (addr < addr_min)
     {
diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c
index d5fe8e3..b065fa7 100644
--- a/loader/i386/pc/multiboot2.c
+++ b/loader/i386/pc/multiboot2.c
@@ -25,32 +25,6 @@
 #include <grub/mm.h>
 
 grub_err_t
-grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
-{
-  Elf32_Addr paddr = phdr->p_paddr;
-
-  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);
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
-grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
-{
-  Elf64_Addr paddr = phdr->p_paddr;
-
-  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);
-
-  return GRUB_ERR_NONE;
-}
-
-grub_err_t
 grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
 {
   grub_addr_t modaddr;
@@ -73,6 +47,7 @@ grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size)
 void
 grub_mb2_arch_boot (grub_addr_t entry, void *tags)
 {
+  grub_stop_floppy ();
   grub_multiboot2_real_boot (entry, tags);
 }
 
diff --git a/loader/ieee1275/multiboot2.c b/loader/ieee1275/multiboot2.c
index c253fc9..462135b 100644
--- a/loader/ieee1275/multiboot2.c
+++ b/loader/ieee1275/multiboot2.c
@@ -31,41 +31,6 @@
 typedef void (*kernel_entry_t) (unsigned long, void *, int (void *),
                                 unsigned long, unsigned long);
 
-/* Claim the memory occupied by the multiboot kernel.  */
-grub_err_t
-grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
-{
-  int rc;
-
-  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
-  if (rc)
-    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x - %x",
-		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
-
-  grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr,
-		phdr->p_paddr + phdr->p_memsz);
-
-  return GRUB_ERR_NONE;
-}
-
-/* Claim the memory occupied by the multiboot kernel.  */
-grub_err_t
-grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
-{
-  int rc;
-
-  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
-  if (rc)
-    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx - 0x%lx",
-		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
-
-  grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
-		(unsigned long) phdr->p_paddr,
-		(unsigned long) (phdr->p_paddr + phdr->p_memsz));
-
-  return GRUB_ERR_NONE;
-}
-
 grub_err_t
 grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
 {
diff --git a/loader/multiboot2.c b/loader/multiboot2.c
index 2fb56bf..a6cee06 100644
--- a/loader/multiboot2.c
+++ b/loader/multiboot2.c
@@ -38,6 +38,42 @@ static char *grub_mb2_tags_pos;
 static grub_size_t grub_mb2_tags_len;
 static int grub_mb2_tags_count;
 
+/* Claim the memory occupied by the multiboot kernel.  */
+static grub_err_t
+grub_mb2_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
+{
+  int rc;
+
+  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
+  if (rc)
+    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x - %x",
+		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
+
+  grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr,
+		phdr->p_paddr + phdr->p_memsz);
+
+  return GRUB_ERR_NONE;
+}
+
+/* Claim the memory occupied by the multiboot kernel.  */
+static grub_err_t
+grub_mb2_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
+{
+  int rc;
+
+  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
+  if (rc)
+    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx - 0x%lx",
+		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
+
+  grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
+		(unsigned long) phdr->p_paddr,
+		(unsigned long) (phdr->p_paddr + phdr->p_memsz));
+
+  return GRUB_ERR_NONE;
+}
+
+
 static void
 grub_mb2_tags_free (void)
 {
@@ -279,13 +315,13 @@ grub_mb2_load_elf (grub_elf_t elf, int argc, char *argv[])
   if (grub_elf_is_elf32 (elf))
     {
       entry = elf->ehdr.ehdr32.e_entry;
-      err = grub_elf32_load (elf, grub_mb2_arch_elf32_hook, &kern_base,
+      err = grub_elf32_load (elf, grub_mb2_elf32_hook, &kern_base,
 			     &kern_size);
     }
   else if (grub_elf_is_elf64 (elf))
     {
       entry = elf->ehdr.ehdr64.e_entry;
-      err = grub_elf64_load (elf, grub_mb2_arch_elf64_hook, &kern_base,
+      err = grub_elf64_load (elf, grub_mb2_elf64_hook, &kern_base,
 			     &kern_size);
     }
   else
diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c
index f4a3933..6c30d5a 100644
--- a/loader/multiboot_loader.c
+++ b/loader/multiboot_loader.c
@@ -137,9 +137,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
 
    /* Launch multi boot with header */
 
-   /* XXX Find a better way to identify this. 
-      This is for i386-pc */
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
+#if defined(__i386__)
   if (header_multi_ver_found == 1)
     {
       grub_dprintf ("multiboot_loader",
@@ -152,7 +150,9 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
     {
       grub_dprintf ("multiboot_loader",
            "Launching multiboot 2 grub_multiboot2() function\n");
+#ifndef GRUB_MACHINE_EFI
       grub_multiboot2 (argc, argv);
+#endif
       module_version_status = 2;
     }
 
@@ -172,7 +172,7 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)),
 			int argc, char *argv[])
 {
 
-#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
+#if defined(__i386__)
   if (module_version_status == 1)
     {
       grub_dprintf("multiboot_loader",
@@ -184,7 +184,9 @@ grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)),
     {
       grub_dprintf("multiboot_loader",
           "Launching multiboot 2 grub_module2() function\n");
+#ifndef GRUB_MACHINE_EFI
       grub_module2 (argc, argv);
+#endif
     }
 
   return grub_errno;

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-04-14  8:22   ` Drew Rosen
  2009-04-14  9:12     ` phcoder
@ 2009-04-14 20:31     ` uzer cheg
  1 sibling, 0 replies; 13+ messages in thread
From: uzer cheg @ 2009-04-14 20:31 UTC (permalink / raw)
  To: The development of GRUB 2

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

Hi,dear folks, unfortunately I have a tough working schedule last time.

It still not tested.
Hope to do it  in a few weeks.

phcoder, I will report results.

[-- Attachment #2: Type: text/html, Size: 618 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-04-14  9:12     ` phcoder
@ 2009-04-15 13:58       ` Drew Rosen
  2009-04-15 15:24         ` Bean
  0 siblings, 1 reply; 13+ messages in thread
From: Drew Rosen @ 2009-04-15 13:58 UTC (permalink / raw)
  To: The development of GRUB 2

We're interested, I've got 30 Xserves that will be paper weights  
pretty soon if we don't get a 64 bit linux OS on them... rendering for  
3d fx in movies.

I'll try to start a http://grub.enbug.org/TestingOnXserve page shortly  
to combine all the info we've gathered so far.

Thanks.


On Apr 14, 2009, at 2:12 AM, phcoder wrote:

> I did the patch for it, however it seems nobody is interested to  
> test it. With it I'm able to boot grub invaders on qemu-tianocore.  
> And I have no xserve. For convenience I resend the patch. If it  
> works I'll split it into components as required for review. Also  
> have a look at http://grub.enbug.org/TestingOnMacbook for some  
> relevant fixes (in linux section).
> Drew Rosen wrote:
>> Hi Uzer Cheg.
>> Any progress on the Xserve?
>> On Mar 18, 2009, at 6:22 AM, uzer cheg wrote:
>>> Dear all,
>>>
>>> I'm trying to run Xen Dom0 kernel on my Xserve.
>>> As I see I need Grub's entry like this:
>>>
>>> menuentry "Xen 3.3 unstable -i386
>>> {
>>>  search --set /boot/xen-3.3.gz
>>>  multiboot /boot/xen-3.3.gz
>>>  module /boot/vmlinuz-2.6.29-rc8-tip root=LABEL=/ ro console=tty0
>>>  module /boot/initrd-2.6.29-rc8-tip.img
>>> }
>>>
>>> I just downloaded from svn latest grub2 (revision 2032) and tried  
>>> to build it.
>>> # cd grub2
>>> # ./configure --with-platform=efi --target=i386
>>> # make
>>> # ./grub-mkimage -d . -o grub.efi apple appleldr boot cat chain
>>> configfile cpio date ext2 echo fat gpt help hexdump hfs hfsplus
>>> iso9660 linux ls normal pc reboot reiserfs scsi search sleep xfs
>>> multiboot module
>>>
>>> I got error message
>>> # grub-mkimage: error: cannot stat ./multiboot.mod
>>>
>>> I think that make did not build multiboot.mod for efi.
>>> Help me please.
>>> Tell me please how to enable multiboot and module support in efi  
>>> grub2?
>>>
>>> Thank you in advance.
>>>
>>>
>>> _______________________________________________
>>> Grub-devel mailing list
>>> Grub-devel@gnu.org
>>> http://lists.gnu.org/mailman/listinfo/grub-devel
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>
>
> -- 
>
> Regards
> Vladimir 'phcoder' Serbinenko
> diff --git a/conf/common.rmk b/conf/common.rmk
> index b0a78b0..fb36edb 100644
> --- a/conf/common.rmk
> +++ b/conf/common.rmk
> @@ -525,3 +525,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 41c45db..1cd7484 100644
> --- a/conf/i386-coreboot.rmk
> +++ b/conf/i386-coreboot.rmk
> @@ -101,8 +101,7 @@ grub_install_SOURCES = util/i386/pc/grub- 
> install.in
> pkglib_MODULES = linux.mod normal.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
> @@ -200,10 +199,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 399376f..e185337 100644
> --- a/conf/i386-efi.rmk
> +++ b/conf/i386-efi.rmk
> @@ -81,7 +81,17 @@ grub_install_SOURCES = util/i386/efi/grub- 
> install.in
> # Modules.
> pkglib_MODULES = kernel.mod normal.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
> +	datetime.mod date.mod datehook.mod loadbios.mod \
> +	fixvideo.mod multiboot.mod
> +# For multiboot.mod.
> +multiboot_mod_SOURCES = loader/i386/multiboot.c \
> +			 loader/i386/multiboot_helper.S \
> +                         loader/multiboot2.c \
> +                         loader/efi/multiboot2.c \
> +                         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
> @@ -91,14 +101,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/command.c kern/ 
> corecmd.c \
> +	kern/efi/mmap.c kern/time.c kern/list.c kern/handler.c kern/ 
> command.c kern/corecmd.c \
> 	kern/i386/tsc.c kern/i386/pit.c \
> 	kern/generic/rtc_get_time_ms.c \
> 	kern/generic/millisleep.c
> kernel_mod_HEADERS = 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 command.h
> +	efi/efi.h efi/time.h efi/disk.h efi/memory.h list.h handler.h  
> command.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 96d9c10..df8c062 100644
> --- a/conf/i386-ieee1275.rmk
> +++ b/conf/i386-ieee1275.rmk
> @@ -103,7 +103,7 @@ grub_install_SOURCES = util/ieee1275/grub- 
> install.in
> pkglib_MODULES = normal.mod halt.mod reboot.mod suspend.mod		\
> 	multiboot.mod aout.mod serial.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
> @@ -128,6 +128,7 @@ normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
>
> # For multiboot.mod.
> multiboot_mod_SOURCES = loader/ieee1275/multiboot2.c \
> +			loader/i386/multiboot.c \
> 			loader/i386/multiboot_helper.S \
> 			 loader/multiboot2.c \
> 			 loader/multiboot_loader.c
> @@ -200,10 +201,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 7dfb854..82ede6e 100644
> --- a/conf/i386-pc.rmk
> +++ b/conf/i386-pc.rmk
> @@ -289,16 +289,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 usb.mod
> usb_mod_SOURCES = bus/usb/usb.c bus/usb/usbtrans.c bus/usb/usbhub.c
> usb_mod_CFLAGS = $(COMMON_CFLAGS)
> @@ -354,11 +344,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 93f84ce..ddf7118 100644
> --- a/conf/i386.rmk
> +++ b/conf/i386.rmk
> @@ -14,3 +14,21 @@ 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)
> +
> +pkglib_MODULES += aout.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)
> +
> diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
> index 361fb85..c084370 100644
> --- a/conf/powerpc-ieee1275.rmk
> +++ b/conf/powerpc-ieee1275.rmk
> @@ -111,8 +111,7 @@ pkglib_MODULES = halt.mod \
> 	reboot.mod \
> 	suspend.mod \
>         multiboot.mod \
> -	memdisk.mod \
> -	lsmmap.mod
> +	memdisk.mod
>
> # For linux.mod.
> linux_mod_SOURCES = loader/powerpc/ieee1275/linux.c
> @@ -167,10 +166,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 f50f18e..723dff5 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;
> };
>
> @@ -222,4 +224,7 @@ struct grub_netbsd_btinfo_bootdisk
>   int partition;
> };
>
> +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 afd3eb9..685c2e0 100644
> --- a/include/grub/i386/loader.h
> +++ b/include/grub/i386/loader.h
> @@ -27,12 +27,14 @@ extern grub_uint32_t  
> EXPORT_VAR(grub_linux_prot_size);
> extern char *EXPORT_VAR(grub_linux_tmp_addr);
> extern char *EXPORT_VAR(grub_linux_real_addr);
> extern grub_int32_t EXPORT_VAR(grub_linux_is_bzimage);
> -extern grub_addr_t EXPORT_VAR(grub_os_area_addr);
> -extern grub_size_t EXPORT_VAR(grub_os_area_size);
>
> grub_err_t EXPORT_FUNC(grub_linux16_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[]);
> +void grub_rescue_cmd_initrd (int argc, char *argv[]);
> +
> +void EXPORT_FUNC(grub_stop_floppy) (void);
>
> #endif /* ! GRUB_LOADER_CPU_HEADER */
> 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/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/i386/uppermem.h b/include/grub/i386/ 
> uppermem.h
> new file mode 100644
> index 0000000..bceed3e
> --- /dev/null
> +++ b/include/grub/i386/uppermem.h
> @@ -0,0 +1,7 @@
> +#ifndef GRUB_UPPERMEM_HEADER
> +#define GRUB_UPPERMEM_HEADER
> +
> +grub_err_t
> +grub_get_lower_upper_memory (grub_uint64_t *lower, grub_uint64_t  
> *upper);
> +
> +#endif
> diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ 
> ieee1275/ieee1275.h
> index 3b5139e..48bc3f2 100644
> --- a/include/grub/ieee1275/ieee1275.h
> +++ b/include/grub/ieee1275/ieee1275.h
> @@ -169,7 +169,6 @@ grub_err_t EXPORT_FUNC(grub_children_iterate)  
> (char *devpath,
>      int (*hook) (struct grub_ieee1275_devalias *alias));
> grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
>      (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t,  
> grub_uint32_t));
> -int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
>
> char *EXPORT_FUNC(grub_ieee1275_encode_devname) (const char *path);
> char *EXPORT_FUNC(grub_ieee1275_get_filename) (const char *path);
> diff --git a/include/grub/loader.h b/include/grub/loader.h
> index 1ae5fdd..544b2f5 100644
> --- a/include/grub/loader.h
> +++ b/include/grub/loader.h
> @@ -41,4 +41,8 @@ void EXPORT_FUNC(grub_loader_unset) (void);
>    depending on the setting by grub_loader_set.  */
> grub_err_t EXPORT_FUNC(grub_loader_boot) (void);
>
> +int EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
> +
> +void EXPORT_FUNC(grub_declaimmap) (grub_addr_t addr, grub_size_t  
> size);
> +
> #endif /* ! GRUB_LOADER_HEADER */
> diff --git a/include/grub/multiboot2.h b/include/grub/multiboot2.h
> index bfbffcc..1e6701e 100644
> --- a/include/grub/multiboot2.h
> +++ b/include/grub/multiboot2.h
> @@ -39,12 +39,6 @@ void
> grub_mb2_arch_unload (struct multiboot_tag_header *tags);
>
> grub_err_t
> -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr);
> -
> -grub_err_t
> -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr);
> -
> -grub_err_t
> grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr);
>
> grub_err_t
> diff --git a/include/grub/types.h b/include/grub/types.h
> index 8d51b66..faf2257 100644
> --- a/include/grub/types.h
> +++ b/include/grub/types.h
> @@ -100,6 +100,16 @@ typedef grub_int32_t	grub_ssize_t;
> # define LONG_MAX 2147483647UL
> #endif
>
> +#if GRUB_CPU_SIZEOF_VOID_P == 4
> +#define UINT_TO_PTR(x) ((void*)(grub_uint32_t)(x))
> +#define PTR_TO_UINT64(x) ((grub_uint64_t)(grub_uint32_t)(x))
> +#define PTR_TO_UINT32(x) ((grub_uint32_t)(x))
> +#else
> +#define UINT_TO_PTR(x) ((void*)(grub_uint64_t)(x))
> +#define PTR_TO_UINT64(x) ((grub_uint64_t)(x))
> +#define PTR_TO_UINT32(x) ((grub_uint32_t)(grub_uint64_t)(x))
> +#endif
> +
> /* The type for representing a file offset.  */
> typedef grub_uint64_t	grub_off_t;
>
> 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..3f795cb
> --- /dev/null
> +++ b/kern/efi/mmap.c
> @@ -0,0 +1,177 @@
> +/*
> + *  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>
> +#include <grub/loader.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;
> +}
> +
> +/* XXX: Manage subpage allocations */
> +int
> +grub_claimmap (grub_addr_t addr, grub_size_t size)
> +{
> +  void *ret;
> +  ret = grub_efi_allocate_pages (addr  & (~0xfff),
> +				 (size + (addr & 0xfff) + 0xfff) >> 12);
> +  return (! ret) ? -1 : 0;
> +}
> +
> +/* XXX: Manage subpage allocations */
> +void
> +grub_declaimmap (grub_addr_t addr, grub_size_t size)
> +{
> +  grub_efi_free_pages (addr  & (~0xfff),
> +		       (size + (addr & 0xfff) + 0xfff) >> 12);
> +}
> diff --git a/kern/i386/coreboot/init.c b/kern/i386/coreboot/init.c
> index 1348488..9c1aee0 100644
> --- a/kern/i386/coreboot/init.c
> +++ b/kern/i386/coreboot/init.c
> @@ -155,3 +155,18 @@ grub_arch_modules_addr (void)
> {
>   return ALIGN_UP((grub_addr_t) _end, GRUB_MOD_ALIGN);
> }
> +
> +int
> +grub_claimmap (grub_addr_t addr, grub_size_t size)
> +{
> +  if ((addr < grub_os_area_addr)
> +      || (addr + size > grub_os_area_addr + grub_os_area_size))
> +    return -1;
> +  return 0;
> +}
> +
> +void
> +grub_declaimmap (grub_addr_t addr __attribute__ ((unused)),
> +		 grub_size_t size  __attribute__ ((unused)))
> +{
> +}
> diff --git a/kern/i386/loader.S b/kern/i386/loader.S
> index bbd2187..d9b37bf 100644
> --- a/kern/i386/loader.S
> +++ b/kern/i386/loader.S
> @@ -117,26 +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)
> -
> -	/* 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/kern/i386/pc/init.c b/kern/i386/pc/init.c
> index 6191412..17d5343 100644
> --- a/kern/i386/pc/init.c
> +++ b/kern/i386/pc/init.c
> @@ -43,8 +43,8 @@ struct mem_region
> static struct mem_region mem_regions[MAX_REGIONS];
> static int num_regions;
>
> -grub_addr_t grub_os_area_addr;
> -grub_size_t grub_os_area_size;
> +static grub_addr_t grub_os_area_addr;
> +static grub_size_t grub_os_area_size;
> grub_size_t grub_lower_mem, grub_upper_mem;
>
> void
> @@ -233,3 +233,18 @@ grub_arch_modules_addr (void)
>   return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR
>     + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE);
> }
> +
> +int
> +grub_claimmap (grub_addr_t addr, grub_size_t size)
> +{
> +  if ((addr < grub_os_area_addr)
> +      || (addr + size > grub_os_area_addr + grub_os_area_size))
> +    return -1;
> +  return 0;
> +}
> +
> +void
> +grub_declaimmap (grub_addr_t addr __attribute__ ((unused)),
> +		 grub_size_t size  __attribute__ ((unused)))
> +{
> +}
> diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c
> index d70c3ba..c713d4c 100644
> --- a/kern/ieee1275/openfw.c
> +++ b/kern/ieee1275/openfw.c
> @@ -194,6 +194,13 @@ grub_claimmap (grub_addr_t addr, grub_size_t  
> size)
>   return 0;
> }
>
> +/* XXX Could someone with better OFW knowledge that me fill this? */
> +void
> +grub_declaimmap (grub_addr_t addr __attribute__ ((unused)),
> +		 grub_size_t size  __attribute__ ((unused)))
> +{
> +}
> +
> /* Get the device arguments of the Open Firmware node name `path'.  */
> static char *
> grub_ieee1275_get_devargs (const char *path)
> 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;
> +}
> diff --git a/loader/efi/multiboot2.c b/loader/efi/multiboot2.c
> new file mode 100644
> index 0000000..44bb542
> --- /dev/null
> +++ b/loader/efi/multiboot2.c
> @@ -0,0 +1,75 @@
> +/* multiboot2.c - boot a multiboot 2 OS image. */
> +/*
> + *  GRUB  --  GRand Unified Bootloader
> + *  Copyright (C) 2007,2008  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 <multiboot2.h>
> +#include <grub/multiboot2.h>
> +#include <grub/elf.h>
> +#include <grub/err.h>
> +#include <grub/machine/loader.h>
> +#include <grub/mm.h>
> +
> +grub_err_t
> +grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
> +{
> +  grub_addr_t modaddr;
> +
> +  modaddr = (grub_addr_t) grub_memalign (MULTIBOOT2_MOD_ALIGN, size);
> +  if (! modaddr)
> +    return grub_errno;
> +
> +  *addr = modaddr;
> +  return GRUB_ERR_NONE;
> +}
> +
> +grub_err_t
> +grub_mb2_arch_module_free (grub_addr_t addr, UNUSED grub_size_t size)
> +{
> +  grub_free((void *) addr);
> +  return GRUB_ERR_NONE;
> +}
> +
> +void
> +grub_mb2_arch_boot (grub_addr_t entry, void *tags)
> +{
> +  grub_multiboot2_real_boot (entry, tags);
> +}
> +
> +void
> +grub_mb2_arch_unload (struct multiboot_tag_header *tags)
> +{
> +   struct multiboot_tag_header *tag;
> +
> +   /* Free all module memory in the tag list.  */
> +   for_each_tag (tag, tags)
> +     {
> +       if (tag->key == MULTIBOOT2_TAG_MODULE)
> +         {
> +           struct multiboot_tag_module *module =
> +              (struct multiboot_tag_module *) tag;
> +           grub_free((void *) module->addr);
> +         }
> +     }
> +}
> +
> +grub_err_t
> +grub_mb2_tags_arch_create (void)
> +{
> +  /* XXX Create system table et al. */
> +  return GRUB_ERR_NONE;
> +}
> diff --git a/loader/i386/bsd.c b/loader/i386/bsd.c
> index 355cb3f..4023566 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/dl.h>
> @@ -30,8 +30,13 @@
> #include <grub/misc.h>
> #include <grub/gzio.h>
> #include <grub/aout.h>
> +#include <grub/i386/uppermem.h>
> #include <grub/command.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,8 +510,7 @@ 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)
> -      || (paddr + phdr->p_memsz > grub_os_area_addr +  
> grub_os_area_size))
> +  if (grub_claimmap (paddr, phdr->p_memsz) < 0)
>     return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out  
> of range",
> 		       paddr);
>
> @@ -578,7 +626,7 @@ grub_cmd_freebsd (grub_command_t cmd  
> __attribute__ ((unused)),
> 	  (grub_freebsd_add_meta_module (1, argc, argv, kern_start,
> 					 kern_end - kern_start)))
> 	return grub_errno;
> -      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 1);
> +      grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0);
>     }
>
>   return grub_errno;
> @@ -593,7 +641,7 @@ grub_cmd_openbsd (grub_command_t cmd  
> __attribute__ ((unused)),
> 	       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);
>
>   return grub_errno;
> }
> @@ -607,7 +655,7 @@ grub_cmd_netbsd (grub_command_t cmd  
> __attribute__ ((unused)),
> 	       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);
>
>   return grub_errno;
> }
> @@ -725,7 +773,7 @@ grub_cmd_freebsd_module (grub_command_t cmd  
> __attribute__ ((unused)),
>   if ((!file) || (!file->size))
>     goto fail;
>
> -  if (kern_end + file->size > grub_os_area_addr + grub_os_area_size)
> +  if (grub_claimmap (kern_end, file->size) < 0)
>     {
>       grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the  
> module");
>       goto fail;
> 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/efi/linux.c b/loader/i386/efi/linux.c
> index 100b268..e729a8e 100644
> --- a/loader/i386/efi/linux.c
> +++ b/loader/i386/efi/linux.c
> @@ -18,6 +18,7 @@
>
> #include <grub/loader.h>
> #include <grub/machine/loader.h>
> +#include <grub/machine/memory.h>
> #include <grub/file.h>
> #include <grub/disk.h>
> #include <grub/err.h>
> @@ -46,9 +47,10 @@ static int loaded;
> static void *real_mode_mem;
> static void *prot_mode_mem;
> static void *initrd_mem;
> -static grub_efi_uintn_t real_mode_pages;
> -static grub_efi_uintn_t prot_mode_pages;
> -static grub_efi_uintn_t initrd_pages;
> +static grub_size_t real_size;
> +static grub_size_t mmap_size;
> +static grub_size_t prot_size;
> +static grub_size_t initrd_size;
> static void *mmap_buf;
>
> static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
> @@ -95,26 +97,26 @@ page_align (grub_size_t size)
>
> /* Find the optimal number of pages for the memory map. Is it better  
> to
>    move this code to efi/mm.c?  */
> -static grub_efi_uintn_t
> +static grub_size_t
> find_mmap_size (void)
> {
> -  static grub_efi_uintn_t mmap_size = 0;
> +  static grub_efi_uintn_t cache_mmap_size = 0;
>
> -  if (mmap_size != 0)
> -    return mmap_size;
> +  if (cache_mmap_size != 0)
> +    return cache_mmap_size;
>
> -  mmap_size = (1 << 12);
> +  cache_mmap_size = (1 << 12);
>   while (1)
>     {
>       int ret;
>       grub_efi_memory_descriptor_t *mmap;
>       grub_efi_uintn_t desc_size;
>
> -      mmap = grub_malloc (mmap_size);
> +      mmap = grub_malloc (cache_mmap_size);
>       if (! mmap)
> 	return 0;
>
> -      ret = grub_efi_get_memory_map (&mmap_size, mmap, 0,  
> &desc_size, 0);
> +      ret = grub_efi_get_memory_map (&cache_mmap_size, mmap, 0,  
> &desc_size, 0);
>       grub_free (mmap);
>
>       if (ret < 0)
> @@ -122,14 +124,14 @@ find_mmap_size (void)
>       else if (ret > 0)
> 	break;
>
> -      mmap_size += (1 << 12);
> +      cache_mmap_size += (1 << 12);
>     }
>
>   /* Increase the size a bit for safety, because GRUB allocates more  
> on
>      later, and EFI itself may allocate more.  */
> -  mmap_size += (1 << 12);
> +  cache_mmap_size += (1 << 12);
>
> -  return page_align (mmap_size);
> +  return page_align (cache_mmap_size);
> }
>
> static void
> @@ -137,19 +139,19 @@ free_pages (void)
> {
>   if (real_mode_mem)
>     {
> -      grub_efi_free_pages ((grub_addr_t) real_mode_mem,  
> real_mode_pages);
> +      grub_declaimmap ((grub_addr_t) real_mode_mem, real_size +  
> mmap_size);
>       real_mode_mem = 0;
>     }
>
>   if (prot_mode_mem)
>     {
> -      grub_efi_free_pages ((grub_addr_t) prot_mode_mem,  
> prot_mode_pages);
> +      grub_declaimmap ((grub_addr_t) prot_mode_mem, prot_size);
>       prot_mode_mem = 0;
>     }
>
>   if (initrd_mem)
>     {
> -      grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
> +      grub_declaimmap ((grub_addr_t) initrd_mem, initrd_size);
>       initrd_mem = 0;
>     }
> }
> @@ -161,9 +163,8 @@ allocate_pages (grub_size_t prot_size)
> {
>   grub_efi_uintn_t desc_size;
>   grub_efi_memory_descriptor_t *mmap, *mmap_end;
> -  grub_efi_uintn_t mmap_size, tmp_mmap_size;
> +  grub_efi_uintn_t tmp_mmap_size;
>   grub_efi_memory_descriptor_t *desc;
> -  grub_size_t real_size;
>
>   /* Make sure that each size is aligned to a page boundary.  */
>   real_size = GRUB_LINUX_CL_END_OFFSET;
> @@ -173,11 +174,6 @@ allocate_pages (grub_size_t prot_size)
>   grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size  
> = %x\n",
> 		(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
>
> -  /* Calculate the number of pages; Combine the real mode code with
> -     the memory map buffer for simplicity.  */
> -  real_mode_pages = ((real_size + mmap_size) >> 12);
> -  prot_mode_pages = (prot_size >> 12);
> -
>   /* Initialize the memory pointers with NULL for convenience.  */
>   real_mode_mem = 0;
>   prot_mode_mem = 0;
> @@ -192,44 +188,40 @@ allocate_pages (grub_size_t prot_size)
>     grub_fatal ("cannot get memory map");
>
>   mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
> -
> -  /* First, find free pages for the real mode code
> -     and the memory map buffer.  */
> -  for (desc = mmap;
> -       desc < mmap_end;
> -       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
> +
> +  /* FIXME: Should request low memory from the heap when this  
> feature is
> +     implemented.  */
> +
> +  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)
>     {
> -      /* Probably it is better to put the real mode code in the  
> traditional
> -	 space for safety.  */
> -      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
> -	  && desc->physical_start <= 0x90000
> -	  && desc->num_pages >= real_mode_pages)
> +      /* We must put real mode code in the traditional space.  */
> +
> +      if (type == GRUB_MACHINE_MEMORY_AVAILABLE
> +	  && addr <= 0x90000)
> 	{
> -	  grub_efi_physical_address_t physical_end;
> -	  grub_efi_physical_address_t addr;
> -	
> -	  physical_end = desc->physical_start + (desc->num_pages << 12);
> -	  if (physical_end > 0x90000)
> -	    physical_end = 0x90000;
> -
> -	  grub_dprintf ("linux", "physical_start = %x, physical_end = %x\n",
> -			(unsigned) desc->physical_start,
> -			(unsigned) physical_end);
> -	  addr = physical_end - real_size - mmap_size;
> 	  if (addr < 0x10000)
> -	    continue;
> +	    {
> +	      size += addr - 0x10000;
> +	      addr = 0x10000;
> +	    }
>
> -	  grub_dprintf ("linux", "trying to allocate %u pages at %lx\n",
> -			(unsigned) real_mode_pages, (unsigned long) addr);
> -	  real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages);
> -	  if (! real_mode_mem)
> -	    grub_fatal ("cannot allocate pages");
> -	
> -	  desc->num_pages -= real_mode_pages;
> -	  break;
> +	  if (addr + size > 0x90000)
> +	    size = 0x90000 - addr;
> +
> +	  if (real_size + mmap_size > size)
> +	    return 0;
> +
> +	  real_mode_mem = (void *) ((addr + size) - (real_size +  
> mmap_size));
> +	  if (grub_claimmap ((grub_addr_t) real_mode_mem,
> +			     real_size + mmap_size) < 0)
> +	    return 0;
> +	  return 1;
> 	}
> -    }
>
> +      return 0;
> +    }
> +  grub_machine_mmap_iterate (hook);
>   if (! real_mode_mem)
>     {
>       grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode  
> pages");
> @@ -238,20 +230,20 @@ allocate_pages (grub_size_t prot_size)
>
>   mmap_buf = (void *) ((char *) real_mode_mem + real_size);
> 	
> +  prot_mode_mem = (void *) 0x100000;
>   /* Next, find free pages for the protected mode code.  */
>   /* XXX what happens if anything is using this address?  */
> -  prot_mode_mem = grub_efi_allocate_pages (0x100000,  
> prot_mode_pages);
> -  if (! prot_mode_mem)
> +  if (grub_claimmap (0x100000, prot_size) < 0)
>     {
>       grub_error (GRUB_ERR_OUT_OF_MEMORY,
> 		  "cannot allocate protected mode pages");
>       goto fail;
>     }
>
> -  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages =  
> %x, "
> -		"prot_mode_mem = %lx, prot_mode_pages = %x\n",
> -		(unsigned long) real_mode_mem, (unsigned) real_mode_pages,
> -		(unsigned long) prot_mode_mem, (unsigned) prot_mode_pages);
> +  grub_dprintf ("linux", "real_mode_mem = %lx, real_size = %x, "
> +                "prot_mode_mem = %lx, prot_size = %x\n",
> +                (unsigned long) real_mode_mem, (unsigned) real_size,
> +                (unsigned long) prot_mode_mem, (unsigned) prot_size);
>
>   grub_free (mmap);
>   return 1;
> @@ -300,7 +292,6 @@ grub_linux_boot (void)
>   grub_efi_uintn_t map_key;
>   grub_efi_uintn_t desc_size;
>   grub_efi_uint32_t desc_version;
> -  grub_efi_memory_descriptor_t *desc;
>   int e820_num;
>
>   params = real_mode_mem;
> @@ -318,77 +309,46 @@ grub_linux_boot (void)
> 			       &desc_size, &desc_version) <= 0)
>     grub_fatal ("cannot get memory map");
>
> -  e820_num = 0;
> -  for (desc = mmap_buf;
> -       desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
> -       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
> +  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)
>     {
> -      switch (desc->type)
> -	{
> -	case GRUB_EFI_ACPI_RECLAIM_MEMORY:
> +      switch (type)
> +        {
> +        case GRUB_MACHINE_MEMORY_AVAILABLE:
> 	  grub_e820_add_region (params->e820_map, &e820_num,
> -				desc->physical_start,
> -				desc->num_pages << 12,
> -				GRUB_E820_ACPI);
> +				addr, size, GRUB_E820_RAM);
> 	  break;
>
> -	case GRUB_EFI_ACPI_MEMORY_NVS:
> +#ifdef GRUB_MACHINE_MEMORY_ACPI
> +        case GRUB_MACHINE_MEMORY_ACPI:
> 	  grub_e820_add_region (params->e820_map, &e820_num,
> -				desc->physical_start,
> -				desc->num_pages << 12,
> -				GRUB_E820_NVS);
> +				addr, size, GRUB_E820_ACPI);
> 	  break;
> +#endif
>
> -	case GRUB_EFI_RUNTIME_SERVICES_CODE:
> +#ifdef GRUB_MACHINE_MEMORY_NVS
> +        case GRUB_MACHINE_MEMORY_NVS:
> 	  grub_e820_add_region (params->e820_map, &e820_num,
> -				desc->physical_start,
> -				desc->num_pages << 12,
> -				GRUB_E820_EXEC_CODE);
> +				addr, size, GRUB_E820_NVS);
> 	  break;
> +#endif
>
> -	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:
> -	  {
> -	    grub_uint64_t start, size, end;
> -
> -	    start = desc->physical_start;
> -	    size = desc->num_pages << 12;
> -	    end = start + size;
> -
> -	    /* Skip A0000 - 100000 region.  */
> -	    if ((start < 0x100000ULL) && (end > 0xA0000ULL))
> -	      {
> -		if (start < 0xA0000ULL)
> -		  {
> -		    grub_e820_add_region (params->e820_map, &e820_num,
> -					  start,
> -					  0xA0000ULL - start,
> -					  GRUB_E820_RAM);
> -		  }
> -
> -		if (end <= 0x100000ULL)
> -		  continue;
> -
> -		start = 0x100000ULL;
> -		size = end - start;
> -	      }
> -
> -	    grub_e820_add_region (params->e820_map, &e820_num,
> -				  start, size, GRUB_E820_RAM);
> -	    break;
> -	  }
> -
> -	default:
> +#ifdef GRUB_MACHINE_MEMORY_CODE
> +        case GRUB_MACHINE_MEMORY_CODE:
> 	  grub_e820_add_region (params->e820_map, &e820_num,
> -				desc->physical_start,
> -				desc->num_pages << 12,
> -				GRUB_E820_RESERVED);
> -	}
> +				addr, size, GRUB_E820_EXEC_CODE);
> +	  break;
> +#endif
> +
> +        default:
> +          grub_e820_add_region (params->e820_map, &e820_num,
> +                                addr, size, GRUB_E820_RESERVED);
> +        }
> +      return 0;
>     }
>
> +  e820_num = 0;
> +  grub_machine_mmap_iterate (hook);
>   params->mmap_size = e820_num;
>
>   if (! grub_efi_exit_boot_services (map_key))
> @@ -633,7 +593,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__  
> ((unused)),
>   struct linux_kernel_header lh;
>   struct linux_kernel_params *params;
>   grub_uint8_t setup_sects;
> -  grub_size_t real_size, prot_size;
>   grub_ssize_t len;
>   int i;
>   char *dest;
> @@ -916,9 +875,6 @@ grub_cmd_initrd (grub_command_t cmd  
> __attribute__ ((unused)),
>   grub_ssize_t size;
>   grub_addr_t addr_min, addr_max;
>   grub_addr_t addr;
> -  grub_efi_uintn_t mmap_size;
> -  grub_efi_memory_descriptor_t *desc;
> -  grub_efi_uintn_t desc_size;
>   struct linux_kernel_header *lh;
>
>   if (argc == 0)
> @@ -938,11 +894,24 @@ grub_cmd_initrd (grub_command_t cmd  
> __attribute__ ((unused)),
>     goto fail;
>
>   size = grub_file_size (file);
> -  initrd_pages = (page_align (size) >> 12);
> +  initrd_size = page_align (size);
>
>   lh = (struct linux_kernel_header *) real_mode_mem;
> +
> +  /* Get the highest address available for the initrd.  */
> +  if (grub_le_to_cpu16 (lh->version) >= 0x0203)
> +    {
> +      addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);
> +
> +      /* XXX in reality, Linux specifies a bogus value, so
> +	 it is necessary to make sure that ADDR_MAX does not exceed
> +	 0x3fffffff.  */
> +      if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
> +	addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
> +    }
> +  else
> +    addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
>
> -  addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
>   if (linux_mem_size != 0 && linux_mem_size < addr_max)
>     addr_max = linux_mem_size;
>
> @@ -953,49 +922,21 @@ grub_cmd_initrd (grub_command_t cmd  
> __attribute__ ((unused)),
>   addr_max -= 0x10000;
>
>   /* Usually, the compression ratio is about 50%.  */
> -  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3)  
> << 12)
> -	     + page_align (size);
> +  addr_min = (grub_addr_t) prot_mode_mem + prot_size * 3
> +             + page_align (size);
>
> -  /* Find the highest address to put the initrd.  */
> -  mmap_size = find_mmap_size ();
> -  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size,  
> 0) <= 0)
> -    grub_fatal ("cannot get memory map");
> -
> -  addr = 0;
> -  for (desc = mmap_buf;
> -       desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);
> -       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
> -    {
> -      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
> -	  && desc->num_pages >= initrd_pages)
> -	{
> -	  grub_efi_physical_address_t physical_end;
> -	
> -	  physical_end = desc->physical_start + (desc->num_pages << 12);
> -	  if (physical_end > addr_max)
> -	    physical_end = addr_max;
> -
> -	  if (physical_end < page_align (size))
> -	    continue;
> -
> -	  physical_end -= page_align (size);
> -
> -	  if ((physical_end >= addr_min) &&
> -	      (physical_end >= desc->physical_start) &&
> -	      (physical_end > addr))
> -	    addr = physical_end;
> -	}
> -    }
> +  /* Put the initrd as high as possible, 4KiB aligned.  */
> +  addr = (addr_max - size) & ~0xFFF;
> +  while (addr >= addr_min && grub_claimmap (addr, initrd_size) < 0)
> +    addr -= 0x1000;
>
> -  if (addr == 0)
> +  if (addr < addr_min)
>     {
> -      grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
> +      grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big");
>       goto fail;
>     }
>
> -  initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);
> -  if (! initrd_mem)
> -    grub_fatal ("cannot allocate pages");
> +  initrd_mem = (void *) addr;
>
>   if (grub_file_read (file, initrd_mem, size) != size)
>     {
> diff --git a/loader/i386/linux.c b/loader/i386/linux.c
> index 01d10d5..4811f1a 100644
> --- a/loader/i386/linux.c
> +++ b/loader/i386/linux.c
> @@ -45,9 +45,10 @@ static int loaded;
> static void *real_mode_mem;
> static void *prot_mode_mem;
> static void *initrd_mem;
> -static grub_uint32_t real_mode_pages;
> -static grub_uint32_t prot_mode_pages;
> -static grub_uint32_t initrd_pages;
> +static grub_size_t real_size;
> +static grub_size_t mmap_size;
> +static grub_size_t prot_size;
> +static grub_size_t initrd_size;
>
> static grub_uint8_t gdt[] __attribute__ ((aligned(16))) =
>   {
> @@ -182,7 +183,24 @@ find_mmap_size (void)
> static void
> free_pages (void)
> {
> -  real_mode_mem = prot_mode_mem = initrd_mem = 0;
> +  if (real_mode_mem)
> +    {
> +      grub_declaimmap ((grub_addr_t) real_mode_mem, real_size
> +			       + mmap_size);
> +      real_mode_mem = 0;
> +    }
> +
> +  if (prot_mode_mem)
> +    {
> +      grub_declaimmap ((grub_addr_t) prot_mode_mem, prot_size);
> +      prot_mode_mem = 0;
> +    }
> +
> +  if (initrd_mem)
> +    {
> +      grub_declaimmap ((grub_addr_t) initrd_mem, initrd_size);
> +      initrd_mem = 0;
> +    }
> }
>
> /* Allocate pages for the real mode code and the protected mode code
> @@ -190,8 +208,6 @@ free_pages (void)
> static int
> allocate_pages (grub_size_t prot_size)
> {
> -  grub_size_t real_size, mmap_size;
> -
>   /* Make sure that each size is aligned to a page boundary.  */
>   real_size = GRUB_LINUX_CL_END_OFFSET;
>   prot_size = page_align (prot_size);
> @@ -200,11 +216,6 @@ allocate_pages (grub_size_t prot_size)
>   grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size  
> = %x\n",
> 		(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
>
> -  /* Calculate the number of pages; Combine the real mode code with
> -     the memory map buffer for simplicity.  */
> -  real_mode_pages = ((real_size + mmap_size) >> 12);
> -  prot_mode_pages = (prot_size >> 12);
> -
>   /* Initialize the memory pointers with NULL for convenience.  */
>   free_pages ();
>
> @@ -232,6 +243,8 @@ allocate_pages (grub_size_t prot_size)
> 	    return 0;
>
> 	  real_mode_mem = (void *) ((addr + size) - (real_size + mmap_size));
> +	  if (grub_claimmap (real_mode_mem, real_size + mmap_size) < 0)
> +	    return 0;
> 	  return 1;
> 	}
>
> @@ -245,6 +258,14 @@ allocate_pages (grub_size_t prot_size)
>     }
>
>   prot_mode_mem = (void *) 0x100000;
> +  /* Next, find free pages for the protected mode code.  */
> +  /* XXX what happens if anything is using this address?  */
> +  if (grub_claimmap (0x100000, prot_size) < 0)
> +    {
> +      grub_error (GRUB_ERR_OUT_OF_MEMORY,
> +		  "cannot allocate protected mode pages");
> +      goto fail;
> +    }
>
>   grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_pages = %x, "
>                 "prot_mode_mem = %lx, prot_mode_pages = %x\n",
> @@ -396,6 +417,27 @@ grub_linux_boot (void)
> 				addr, size, GRUB_E820_RAM);
> 	  break;
>
> +#ifdef GRUB_MACHINE_MEMORY_ACPI
> +        case GRUB_MACHINE_MEMORY_ACPI:
> +	  grub_e820_add_region (params->e820_map, &e820_num,
> +				addr, size, GRUB_E820_ACPI);
> +	  break;
> +#endif
> +
> +#ifdef GRUB_MACHINE_MEMORY_NVS
> +        case GRUB_MACHINE_MEMORY_NVS:
> +	  grub_e820_add_region (params->e820_map, &e820_num,
> +				addr, size, GRUB_E820_NVS);
> +	  break;
> +#endif
> +
> +#ifdef GRUB_MACHINE_MEMORY_CODE
> +        case GRUB_MACHINE_MEMORY_CODE:
> +	  grub_e820_add_region (params->e820_map, &e820_num,
> +				addr, size, GRUB_E820_EXEC_CODE);
> +	  break;
> +#endif
> +
>         default:
>           grub_e820_add_region (params->e820_map, &e820_num,
>                                 addr, size, GRUB_E820_RESERVED);
> @@ -457,7 +499,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__  
> ((unused)),
>   struct linux_kernel_header lh;
>   struct linux_kernel_params *params;
>   grub_uint8_t setup_sects;
> -  grub_size_t real_size, prot_size;
>   grub_ssize_t len;
>   int i;
>   char *dest;
> @@ -693,7 +734,7 @@ grub_cmd_initrd (grub_command_t cmd  
> __attribute__ ((unused)),
>     goto fail;
>
>   size = grub_file_size (file);
> -  initrd_pages = (page_align (size) >> 12);
> +  initrd_size = page_align (size);
>
>   lh = (struct linux_kernel_header *) real_mode_mem;
>
> @@ -724,11 +765,10 @@ grub_cmd_initrd (grub_command_t cmd  
> __attribute__ ((unused)),
>   addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) <<  
> 12)
>              + page_align (size);
>
> -  if (addr_max > grub_os_area_addr + grub_os_area_size)
> -    addr_max = grub_os_area_addr + grub_os_area_size;
> -
>   /* Put the initrd as high as possible, 4KiB aligned.  */
>   addr = (addr_max - size) & ~0xFFF;
> +  while (addr >= addr_min && grub_claimmap (addr, initrd_size) < 0)
> +    addr -= 0x1000;
>
>   if (addr < addr_min)
>     {
> diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c
> index 27042a5..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,6 +61,13 @@ static grub_size_t code_size;
> static grub_err_t
> grub_multiboot_boot (void)
> {
> +  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);
>
>   /* Not reached.  */
> @@ -109,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++;
>
> @@ -199,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 ();
> @@ -286,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;
>
> @@ -341,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);
> @@ -370,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/pc/linux.c b/loader/i386/pc/linux.c
> index 8ff97f4..4823ddc 100644
> --- a/loader/i386/pc/linux.c
> +++ b/loader/i386/pc/linux.c
> @@ -71,11 +71,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__  
> ((unused)),
>   if (! file)
>     goto fail;
>
> -  if ((grub_size_t) grub_file_size (file) > grub_os_area_size)
> +  if (grub_claimmap (GRUB_LINUX_BZIMAGE_ADDR, grub_file_size  
> (file)) < 0)
>     {
> -      grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x > 0x 
> %x)",
> -		  (grub_size_t) grub_file_size (file),
> -		  grub_os_area_size);
> +      grub_error (GRUB_ERR_OUT_OF_RANGE, "too big kernel (0x%x)",
> +		  (grub_size_t) grub_file_size (file));
>       goto fail;
>     }
>
> @@ -340,9 +339,6 @@ grub_cmd_initrd (grub_command_t cmd  
> __attribute__ ((unused)),
>      worse than that of Linux 2.3.xx, so avoid the last 64kb.  */
>   addr_max -= 0x10000;
>
> -  if (addr_max > grub_os_area_addr + grub_os_area_size)
> -    addr_max = grub_os_area_addr + grub_os_area_size;
> -
>   addr_min = (grub_addr_t) grub_linux_tmp_addr +  
> GRUB_LINUX_CL_END_OFFSET;
>
>   file = grub_file_open (argv[0]);
> @@ -353,6 +349,8 @@ grub_cmd_initrd (grub_command_t cmd  
> __attribute__ ((unused)),
>
>   /* Put the initrd as high as possible, 4KiB aligned.  */
>   addr = (addr_max - size) & ~0xFFF;
> +  while (addr >= addr_min && grub_claimmap (addr, size) < 0)
> +    addr -= 0x1000;
>
>   if (addr < addr_min)
>     {
> diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c
> index d5fe8e3..b065fa7 100644
> --- a/loader/i386/pc/multiboot2.c
> +++ b/loader/i386/pc/multiboot2.c
> @@ -25,32 +25,6 @@
> #include <grub/mm.h>
>
> grub_err_t
> -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
> -{
> -  Elf32_Addr paddr = phdr->p_paddr;
> -
> -  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);
> -
> -  return GRUB_ERR_NONE;
> -}
> -
> -grub_err_t
> -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
> -{
> -  Elf64_Addr paddr = phdr->p_paddr;
> -
> -  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);
> -
> -  return GRUB_ERR_NONE;
> -}
> -
> -grub_err_t
> grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
> {
>   grub_addr_t modaddr;
> @@ -73,6 +47,7 @@ grub_mb2_arch_module_free (grub_addr_t addr,  
> UNUSED grub_size_t size)
> void
> grub_mb2_arch_boot (grub_addr_t entry, void *tags)
> {
> +  grub_stop_floppy ();
>   grub_multiboot2_real_boot (entry, tags);
> }
>
> diff --git a/loader/ieee1275/multiboot2.c b/loader/ieee1275/ 
> multiboot2.c
> index c253fc9..462135b 100644
> --- a/loader/ieee1275/multiboot2.c
> +++ b/loader/ieee1275/multiboot2.c
> @@ -31,41 +31,6 @@
> typedef void (*kernel_entry_t) (unsigned long, void *, int (void *),
>                                 unsigned long, unsigned long);
>
> -/* Claim the memory occupied by the multiboot kernel.  */
> -grub_err_t
> -grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
> -{
> -  int rc;
> -
> -  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
> -  if (rc)
> -    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x -  
> %x",
> -		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
> -
> -  grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr- 
> >p_paddr,
> -		phdr->p_paddr + phdr->p_memsz);
> -
> -  return GRUB_ERR_NONE;
> -}
> -
> -/* Claim the memory occupied by the multiboot kernel.  */
> -grub_err_t
> -grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
> -{
> -  int rc;
> -
> -  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
> -  if (rc)
> -    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx  
> - 0x%lx",
> -		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
> -
> -  grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
> -		(unsigned long) phdr->p_paddr,
> -		(unsigned long) (phdr->p_paddr + phdr->p_memsz));
> -
> -  return GRUB_ERR_NONE;
> -}
> -
> grub_err_t
> grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr)
> {
> diff --git a/loader/multiboot2.c b/loader/multiboot2.c
> index 2fb56bf..a6cee06 100644
> --- a/loader/multiboot2.c
> +++ b/loader/multiboot2.c
> @@ -38,6 +38,42 @@ static char *grub_mb2_tags_pos;
> static grub_size_t grub_mb2_tags_len;
> static int grub_mb2_tags_count;
>
> +/* Claim the memory occupied by the multiboot kernel.  */
> +static grub_err_t
> +grub_mb2_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr)
> +{
> +  int rc;
> +
> +  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
> +  if (rc)
> +    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x -  
> %x",
> +		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
> +
> +  grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr- 
> >p_paddr,
> +		phdr->p_paddr + phdr->p_memsz);
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +/* Claim the memory occupied by the multiboot kernel.  */
> +static grub_err_t
> +grub_mb2_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr)
> +{
> +  int rc;
> +
> +  rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz);
> +  if (rc)
> +    return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx  
> - 0x%lx",
> +		      phdr->p_paddr, phdr->p_paddr + phdr->p_memsz);
> +
> +  grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n",
> +		(unsigned long) phdr->p_paddr,
> +		(unsigned long) (phdr->p_paddr + phdr->p_memsz));
> +
> +  return GRUB_ERR_NONE;
> +}
> +
> +
> static void
> grub_mb2_tags_free (void)
> {
> @@ -279,13 +315,13 @@ grub_mb2_load_elf (grub_elf_t elf, int argc,  
> char *argv[])
>   if (grub_elf_is_elf32 (elf))
>     {
>       entry = elf->ehdr.ehdr32.e_entry;
> -      err = grub_elf32_load (elf, grub_mb2_arch_elf32_hook,  
> &kern_base,
> +      err = grub_elf32_load (elf, grub_mb2_elf32_hook, &kern_base,
> 			     &kern_size);
>     }
>   else if (grub_elf_is_elf64 (elf))
>     {
>       entry = elf->ehdr.ehdr64.e_entry;
> -      err = grub_elf64_load (elf, grub_mb2_arch_elf64_hook,  
> &kern_base,
> +      err = grub_elf64_load (elf, grub_mb2_elf64_hook, &kern_base,
> 			     &kern_size);
>     }
>   else
> diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c
> index f4a3933..6c30d5a 100644
> --- a/loader/multiboot_loader.c
> +++ b/loader/multiboot_loader.c
> @@ -137,9 +137,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd  
> __attribute__ ((unused)),
>
>    /* Launch multi boot with header */
>
> -   /* XXX Find a better way to identify this.
> -      This is for i386-pc */
> -#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
> +#if defined(__i386__)
>   if (header_multi_ver_found == 1)
>     {
>       grub_dprintf ("multiboot_loader",
> @@ -152,7 +150,9 @@ grub_cmd_multiboot_loader (grub_command_t cmd  
> __attribute__ ((unused)),
>     {
>       grub_dprintf ("multiboot_loader",
>            "Launching multiboot 2 grub_multiboot2() function\n");
> +#ifndef GRUB_MACHINE_EFI
>       grub_multiboot2 (argc, argv);
> +#endif
>       module_version_status = 2;
>     }
>
> @@ -172,7 +172,7 @@ grub_cmd_module_loader (grub_command_t cmd  
> __attribute__ ((unused)),
> 			int argc, char *argv[])
> {
>
> -#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
> +#if defined(__i386__)
>   if (module_version_status == 1)
>     {
>       grub_dprintf("multiboot_loader",
> @@ -184,7 +184,9 @@ grub_cmd_module_loader (grub_command_t cmd  
> __attribute__ ((unused)),
>     {
>       grub_dprintf("multiboot_loader",
>           "Launching multiboot 2 grub_module2() function\n");
> +#ifndef GRUB_MACHINE_EFI
>       grub_module2 (argc, argv);
> +#endif
>     }
>
>   return grub_errno;
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386
  2009-04-15 13:58       ` Drew Rosen
@ 2009-04-15 15:24         ` Bean
  2009-04-15 16:23           ` multiboot module in grub2 --with-platform=efi --target=i386 - TestingOnXserve Drew Rosen
  0 siblings, 1 reply; 13+ messages in thread
From: Bean @ 2009-04-15 15:24 UTC (permalink / raw)
  To: The development of GRUB 2

Hi,

From the wiki page you put up, you're obvious not familiar with
grub2's efi support. x86_64-efi have been in grub2 for a long time,
you just need to know how to build it, take a look at this page:

http://grub.enbug.org/TestingOnMacbook

Also, you can check out this post at ubuntu forum:

http://ubuntuforums.org/showthread.php?t=995704

D4T have successfully booted both 32-bit and 64-bit linux with Xserver
1.1 and 1.2.

BTW, please don't put anything you're not sure of to the wiki page,
it's misleading for other users.

On Wed, Apr 15, 2009 at 9:58 PM, Drew Rosen <drewsta@mac.com> wrote:
> We're interested, I've got 30 Xserves that will be paper weights pretty soon
> if we don't get a 64 bit linux OS on them... rendering for 3d fx in movies.
>
> I'll try to start a http://grub.enbug.org/TestingOnXserve page shortly to
> combine all the info we've gathered so far.

-- 
Bean



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386 - TestingOnXserve
  2009-04-15 15:24         ` Bean
@ 2009-04-15 16:23           ` Drew Rosen
  2009-04-15 17:15             ` Bean
  0 siblings, 1 reply; 13+ messages in thread
From: Drew Rosen @ 2009-04-15 16:23 UTC (permalink / raw)
  To: The development of GRUB 2

Thanks Bean. Totally appreciate your help with this.

I'm not familiar with the x86_64 support, and these notes were created  
6 months ago, but I thought they would be a good place to start...  
Don't hesitate to remove anything you think is misleading. I'm going  
to try to update it with better info as soon as possible.

Also, please be clear, we are not talking about Xserver. I'm trying to  
run 64 Bit Linux on an Apple MacIntel Xserve.

The systems I have are 2 x 2.66 Dual-Core Intel Xeon.

Thanks!



On Apr 15, 2009, at 8:24 AM, Bean wrote:

> Hi,
>
> From the wiki page you put up, you're obvious not familiar with
> grub2's efi support. x86_64-efi have been in grub2 for a long time,
> you just need to know how to build it, take a look at this page:
>
> http://grub.enbug.org/TestingOnMacbook
>
> Also, you can check out this post at ubuntu forum:
>
> http://ubuntuforums.org/showthread.php?t=995704
>
> D4T have successfully booted both 32-bit and 64-bit linux with Xserver
> 1.1 and 1.2.
>
> BTW, please don't put anything you're not sure of to the wiki page,
> it's misleading for other users.
>
> On Wed, Apr 15, 2009 at 9:58 PM, Drew Rosen <drewsta@mac.com> wrote:
>> We're interested, I've got 30 Xserves that will be paper weights  
>> pretty soon
>> if we don't get a 64 bit linux OS on them... rendering for 3d fx in  
>> movies.
>>
>> I'll try to start a http://grub.enbug.org/TestingOnXserve page  
>> shortly to
>> combine all the info we've gathered so far.
>
> -- 
> Bean
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: multiboot module in grub2 --with-platform=efi --target=i386 -  TestingOnXserve
  2009-04-15 16:23           ` multiboot module in grub2 --with-platform=efi --target=i386 - TestingOnXserve Drew Rosen
@ 2009-04-15 17:15             ` Bean
  0 siblings, 0 replies; 13+ messages in thread
From: Bean @ 2009-04-15 17:15 UTC (permalink / raw)
  To: The development of GRUB 2

Hi,

On Thu, Apr 16, 2009 at 12:23 AM, Drew Rosen <drewsta@mac.com> wrote:
> Thanks Bean. Totally appreciate your help with this.
>
> I'm not familiar with the x86_64 support, and these notes were created 6
> months ago, but I thought they would be a good place to start... Don't
> hesitate to remove anything you think is misleading. I'm going to try to
> update it with better info as soon as possible.
>

Oh never mind, it would be nice if you can get it working, then there
is another efi platform supported by grub2.

> Also, please be clear, we are not talking about Xserver. I'm trying to run
> 64 Bit Linux on an Apple MacIntel Xserve.
>
> The systems I have are 2 x 2.66 Dual-Core Intel Xeon.
>

I don't know they're different, but I guess the efi firmware is more
or less the same.

> Thanks!
>
>
>
> On Apr 15, 2009, at 8:24 AM, Bean wrote:
>
>> Hi,
>>
>> From the wiki page you put up, you're obvious not familiar with
>> grub2's efi support. x86_64-efi have been in grub2 for a long time,
>> you just need to know how to build it, take a look at this page:
>>
>> http://grub.enbug.org/TestingOnMacbook
>>
>> Also, you can check out this post at ubuntu forum:
>>
>> http://ubuntuforums.org/showthread.php?t=995704
>>
>> D4T have successfully booted both 32-bit and 64-bit linux with Xserver
>> 1.1 and 1.2.
>>
>> BTW, please don't put anything you're not sure of to the wiki page,
>> it's misleading for other users.
>>
>> On Wed, Apr 15, 2009 at 9:58 PM, Drew Rosen <drewsta@mac.com> wrote:
>>>
>>> We're interested, I've got 30 Xserves that will be paper weights pretty
>>> soon
>>> if we don't get a 64 bit linux OS on them... rendering for 3d fx in
>>> movies.
>>>
>>> I'll try to start a http://grub.enbug.org/TestingOnXserve page shortly to
>>> combine all the info we've gathered so far.
>>
>> --
>> Bean
>>
>>
>> _______________________________________________
>> Grub-devel mailing list
>> Grub-devel@gnu.org
>> http://lists.gnu.org/mailman/listinfo/grub-devel
>
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> http://lists.gnu.org/mailman/listinfo/grub-devel
>



-- 
Bean



^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2009-04-15 17:16 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <fd8d61830903180608l2ad4b32ag8122fbc748c64515@mail.gmail.com>
2009-03-18 13:22 ` multiboot module in grub2 --with-platform=efi --target=i386 uzer cheg
2009-03-18 13:38   ` phcoder
2009-03-18 13:54     ` uzer cheg
2009-03-18 14:09       ` phcoder
2009-03-18 14:15         ` uzer cheg
2009-03-18 14:58           ` phcoder
2009-04-14  8:22   ` Drew Rosen
2009-04-14  9:12     ` phcoder
2009-04-15 13:58       ` Drew Rosen
2009-04-15 15:24         ` Bean
2009-04-15 16:23           ` multiboot module in grub2 --with-platform=efi --target=i386 - TestingOnXserve Drew Rosen
2009-04-15 17:15             ` Bean
2009-04-14 20:31     ` multiboot module in grub2 --with-platform=efi --target=i386 uzer cheg

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.