[1817] 2008-08-17 Robert Millan <[email protected]>

Robert Millan <[email protected]>
Newsgroups gmane.comp.boot-loaders.grub.cvs
Message-ID <[email protected]>
Revision: 1817
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1817
Author:   robertmh
Date:     2008-08-17 16:32:18 +0000 (Sun, 17 Aug 2008)

Log Message:
-----------
2008-08-17  Robert Millan  <[email protected]>

        * conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pc/mmap.c'.

        * include/grub/i386/pc/init.h (GRUB_MACHINE_MEMORY_AVAILABLE)
        (GRUB_MACHINE_MEMORY_RESERVED): New macros.
        (grub_machine_mmap_iterate): New function declaration.
        * include/grub/multiboot.h (struct grub_multiboot_mmap_entry): New
        structure.
        (GRUB_MMAP_MEMORY_AVAILABLE, GRUB_MMAP_MEMORY_RESERVED): New
        macros.

        * kern/i386/pc/init.c (grub_machine_init): Replace hardcoded region
        type check value with `GRUB_MACHINE_MEMORY_AVAILABLE'.
        Move e820 parsing from here ...
        * kern/i386/pc/mmap.c: New file.
        (grub_machine_mmap_iterate): ... to here.

        * include/grub/i386/coreboot/memory.h: Remove `<grub/err.h>'.
        (GRUB_LINUXBIOS_MEMORY_AVAILABLE): Rename (for consistency) to ...
        (GRUB_MACHINE_MEMORY_AVAILABLE): ... this.  Update all users.
        (grub_available_iterate): Redeclare to return `void', and redeclare
        its hook to use grub_uint64_t as addr and size parameters, and rename
        to ...
        (grub_machine_mmap_iterate): ... this.  Update all users.

        * kern/i386/coreboot/mmap.c (grub_mmap_iterate): Simplify parser loop
        to make it more readable.  Rename to ...
        (grub_machine_mmap_iterate): ... this.

        * loader/i386/pc/multiboot.c (mmap_addr, mmap_length): New variables.
        (grub_get_multiboot_mmap_len, grub_fill_multiboot_mmap): New functions.
        (grub_multiboot): Allocate an extra region after the payload, and fill
        it with a Multiboot memory map.  Adjust a.out loader to calculate size
        with the extra space.
        (grub_multiboot_load_elf32): Adjust elf32 loader to calculate size
        with the extra space.

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/conf/i386-pc.rmk
    trunk/grub2/include/grub/i386/coreboot/memory.h
    trunk/grub2/include/grub/i386/pc/init.h
    trunk/grub2/include/grub/multiboot.h
    trunk/grub2/kern/i386/coreboot/init.c
    trunk/grub2/kern/i386/coreboot/mmap.c
    trunk/grub2/kern/i386/pc/init.c
    trunk/grub2/loader/i386/pc/multiboot.c

Added Paths:
-----------
    trunk/grub2/kern/i386/pc/mmap.c

Property Changed:
----------------
    trunk/grub2/


Property changes on: trunk/grub2
___________________________________________________________________
Name: svn:ignore
   - *.d
*.exec
*.img
*.lst
*.mod
*.elf
*.pff
00_header
10_hurd
10_linux
10_windows
30_os-prober
40_custom
Makefile
autom4te.cache
config.cache
config.h
config.log
config.status
genkernsyms.sh
gensymlist.sh
grub-editenv
grub-install
grub-mkdevicemap
grub-mkimage
grub-mkrescue
grub-pe2elf
grub-probe
grub-setup
grub_probe_init.c
grub_probe_init.h
grub_script.tab.c
grub_script.tab.h
grub_setup_init.c
grub_setup_init.h
mod-*.c
stamp-h
stamp-h1
symlist.c
update-grub
update-grub_lib

   + *.d
*.exec
*.img
*.lst
*.mod
*.elf
*.pff
00_header
10_hurd
10_linux
10_windows
30_os-prober
40_custom
Makefile
autom4te.cache
config.cache
config.h
config.log
config.status
genkernsyms.sh
gensymlist.sh
grub-editenv
grub-install
grub-mkdevicemap
grub-mk*image
grub-mkrescue
grub-pe2elf
grub-probe
grub-setup
grub_probe_init.c
grub_probe_init.h
grub_script.tab.c
grub_script.tab.h
grub_setup_init.c
grub_setup_init.h
mod-*.c
stamp-h
stamp-h1
symlist.c
update-grub
update-grub_lib


Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/ChangeLog	2008-08-17 16:32:18 UTC (rev 1817)
@@ -1,3 +1,41 @@
+2008-08-17  Robert Millan  <[email protected]>
+
+	* conf/i386-pc.rmk (kernel_img_SOURCES): Add `kern/i386/pc/mmap.c'.
+
+	* include/grub/i386/pc/init.h (GRUB_MACHINE_MEMORY_AVAILABLE)
+	(GRUB_MACHINE_MEMORY_RESERVED): New macros.
+	(grub_machine_mmap_iterate): New function declaration.
+	* include/grub/multiboot.h (struct grub_multiboot_mmap_entry): New
+	structure.
+	(GRUB_MMAP_MEMORY_AVAILABLE, GRUB_MMAP_MEMORY_RESERVED): New
+	macros.
+
+	* kern/i386/pc/init.c (grub_machine_init): Replace hardcoded region
+	type check value with `GRUB_MACHINE_MEMORY_AVAILABLE'.
+	Move e820 parsing from here ...
+	* kern/i386/pc/mmap.c: New file.
+	(grub_machine_mmap_iterate): ... to here.
+
+	* include/grub/i386/coreboot/memory.h: Remove `<grub/err.h>'.
+	(GRUB_LINUXBIOS_MEMORY_AVAILABLE): Rename (for consistency) to ...
+	(GRUB_MACHINE_MEMORY_AVAILABLE): ... this.  Update all users.
+	(grub_available_iterate): Redeclare to return `void', and redeclare
+	its hook to use grub_uint64_t as addr and size parameters, and rename
+	to ...
+	(grub_machine_mmap_iterate): ... this.  Update all users.
+
+	* kern/i386/coreboot/mmap.c (grub_mmap_iterate): Simplify parser loop
+	to make it more readable.  Rename to ...
+	(grub_machine_mmap_iterate): ... this.
+
+	* loader/i386/pc/multiboot.c (mmap_addr, mmap_length): New variables.
+	(grub_get_multiboot_mmap_len, grub_fill_multiboot_mmap): New functions.
+	(grub_multiboot): Allocate an extra region after the payload, and fill
+	it with a Multiboot memory map.  Adjust a.out loader to calculate size
+	with the extra space.
+	(grub_multiboot_load_elf32): Adjust elf32 loader to calculate size
+	with the extra space.
+
 2008-08-17  Carles Pina i Estany  <[email protected]>
 
 	* menu/normal.c (run_menu): Add Home and End keys in grub-menu.

Modified: trunk/grub2/conf/i386-pc.rmk
===================================================================
--- trunk/grub2/conf/i386-pc.rmk	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/conf/i386-pc.rmk	2008-08-17 16:32:18 UTC (rev 1817)
@@ -43,7 +43,8 @@
 	kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
 	kern/misc.c kern/mm.c kern/loader.c kern/rescue.c kern/term.c \
 	kern/time.c \
-	kern/i386/dl.c kern/i386/pc/init.c kern/parser.c kern/partition.c \
+	kern/i386/dl.c kern/i386/pc/init.c kern/i386/pc/mmap.c \
+	kern/parser.c kern/partition.c \
 	kern/i386/tsc.c kern/i386/pit.c \
 	kern/generic/rtc_get_time_ms.c \
 	kern/generic/millisleep.c \

Modified: trunk/grub2/include/grub/i386/coreboot/memory.h
===================================================================
--- trunk/grub2/include/grub/i386/coreboot/memory.h	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/include/grub/i386/coreboot/memory.h	2008-08-17 16:32:18 UTC (rev 1817)
@@ -25,7 +25,6 @@
 
 #ifndef ASM_FILE
 #include <grub/types.h>
-#include <grub/err.h>
 #endif
 
 #define GRUB_MEMORY_MACHINE_LOWER_USABLE		0x9fc00		/* 640 kiB - 1 kiB */
@@ -55,13 +54,13 @@
 {
   grub_uint64_t addr;
   grub_uint64_t size;
-#define GRUB_LINUXBIOS_MEMORY_AVAILABLE	1
+#define GRUB_MACHINE_MEMORY_AVAILABLE		1
   grub_uint32_t type;
 };
 typedef struct grub_linuxbios_mem_region *mem_region_t;
 
-grub_err_t EXPORT_FUNC(grub_available_iterate)
-     (int (*hook) (mem_region_t));
+void EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
 
 #endif
 

Modified: trunk/grub2/include/grub/i386/pc/init.h
===================================================================
--- trunk/grub2/include/grub/i386/pc/init.h	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/include/grub/i386/pc/init.h	2008-08-17 16:32:18 UTC (rev 1817)
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2002,2004,2005,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2002,2004,2005,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
@@ -35,6 +35,8 @@
   grub_uint32_t size;
   grub_uint64_t addr;
   grub_uint64_t len;
+#define GRUB_MACHINE_MEMORY_AVAILABLE	1
+#define GRUB_MACHINE_MEMORY_RESERVED	2
   grub_uint32_t type;
 } __attribute__((packed));
 
@@ -43,6 +45,9 @@
 grub_uint32_t EXPORT_FUNC(grub_get_mmap_entry) (struct grub_machine_mmap_entry *entry,
 				   grub_uint32_t cont);
 
+void EXPORT_FUNC(grub_machine_mmap_iterate)
+     (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
+
 /* Turn on/off Gate A20.  */
 void grub_gate_a20 (int on);
 

Modified: trunk/grub2/include/grub/multiboot.h
===================================================================
--- trunk/grub2/include/grub/multiboot.h	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/include/grub/multiboot.h	2008-08-17 16:32:18 UTC (rev 1817)
@@ -1,7 +1,7 @@
 /* multiboot.h - multiboot header file with grub definitions. */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2003,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
@@ -101,6 +101,16 @@
   grub_uint16_t vbe_interface_len;
 };
 
+struct grub_multiboot_mmap_entry
+{
+  grub_uint32_t size;
+  grub_uint64_t addr;
+  grub_uint64_t len;
+#define GRUB_MULTIBOOT_MEMORY_AVAILABLE		1
+#define GRUB_MULTIBOOT_MEMORY_RESERVED		2
+  grub_uint32_t type;
+} __attribute__((packed));
+
 struct grub_mod_list
 {
   /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */

Modified: trunk/grub2/kern/i386/coreboot/init.c
===================================================================
--- trunk/grub2/kern/i386/coreboot/init.c	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/kern/i386/coreboot/init.c	2008-08-17 16:32:18 UTC (rev 1817)
@@ -83,12 +83,9 @@
   grub_lower_mem = GRUB_MEMORY_MACHINE_LOWER_USABLE;
   grub_upper_mem = 0;
 
-  auto int heap_init (mem_region_t);
-  int heap_init (mem_region_t mem_region)
+  auto int NESTED_FUNC_ATTR heap_init (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR heap_init (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
   {
-    grub_uint64_t addr = mem_region->addr;
-    grub_uint64_t size = mem_region->size;
-
 #if GRUB_CPU_SIZEOF_VOID_P == 4
     /* Restrict ourselves to 32-bit memory space.  */
     if (addr > ULONG_MAX)
@@ -102,7 +99,7 @@
 
     grub_upper_mem = grub_max (grub_upper_mem, addr + size);
 
-    if (mem_region->type != GRUB_LINUXBIOS_MEMORY_AVAILABLE)
+    if (type != GRUB_MACHINE_MEMORY_AVAILABLE)
       return 0;
 
     /* Avoid the lower memory.  */
@@ -135,7 +132,7 @@
     return 0;
   }
 
-  grub_available_iterate (heap_init);
+  grub_machine_mmap_iterate (heap_init);
 
   /* This variable indicates size, not offset.  */
   grub_upper_mem -= GRUB_MEMORY_MACHINE_UPPER_START;

Modified: trunk/grub2/kern/i386/coreboot/mmap.c
===================================================================
--- trunk/grub2/kern/i386/coreboot/mmap.c	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/kern/i386/coreboot/mmap.c	2008-08-17 16:32:18 UTC (rev 1817)
@@ -63,8 +63,8 @@
   return 0;
 }
 
-grub_err_t
-grub_available_iterate (int (*hook) (mem_region_t))
+void
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
 {
   mem_region_t mem_region;
 
@@ -77,11 +77,17 @@
     mem_region =
       (mem_region_t) ((long) table_item +
 				 sizeof (struct grub_linuxbios_table_item));
-    for (; (long) mem_region < (long) table_item + (long) table_item->size;
-	 mem_region++)
-      if (hook (mem_region))
-	return 1;
+    while ((long) mem_region < (long) table_item + (long) table_item->size)
+      {
+	if (hook (mem_region->addr, mem_region->size,
+		  /* Multiboot mmaps match with the coreboot mmap definition.
+		     Therefore, we can just pass type through.  */
+		  mem_region->type))
+	  return 1;
 
+	mem_region++;
+      }
+
     return 0;
   }
 

Modified: trunk/grub2/kern/i386/pc/init.c
===================================================================
--- trunk/grub2/kern/i386/pc/init.c	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/kern/i386/pc/init.c	2008-08-17 16:32:18 UTC (rev 1817)
@@ -132,9 +132,6 @@
 void
 grub_machine_init (void)
 {
-  grub_uint32_t cont;
-  struct grub_machine_mmap_entry *entry
-    = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
   int i;
   
   /* Initialize the console as early as possible.  */
@@ -156,55 +153,35 @@
     add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END,
 		    grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
   
-  /* Check if grub_get_mmap_entry works.  */
-  cont = grub_get_mmap_entry (entry, 0);
-
-  if (entry->size)
-    do
-      {
-	/* Avoid the lower memory.  */
-	if (entry->addr < 0x100000)
-	  {
-	    if (entry->len <= 0x100000 - entry->addr)
-	      goto next;
-
-	    entry->len -= 0x100000 - entry->addr;
-	    entry->addr = 0x100000;
-	  }
-	
-	/* Ignore >4GB.  */
-	if (entry->addr <= 0xFFFFFFFF && entry->type == 1)
-	  {
-	    grub_addr_t addr;
-	    grub_size_t len;
-
-	    addr = (grub_addr_t) entry->addr;
-	    len = ((addr + entry->len > 0xFFFFFFFF)
-		   ? 0xFFFFFFFF - addr
-		   : (grub_size_t) entry->len);
-	    add_mem_region (addr, len);
-	  }
-	
-      next:
-	if (! cont)
-	  break;
-	
-	cont = grub_get_mmap_entry (entry, cont);
-      }
-    while (entry->size);
-  else
+  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)
     {
-      grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
-
-      if (eisa_mmap)
+      /* Avoid the lower memory.  */
+      if (addr < 0x100000)
 	{
-	  add_mem_region (0x100000, (eisa_mmap & 0xFFFF) << 10);
-	  add_mem_region (0x1000000, eisa_mmap & ~0xFFFF);
+	  if (size <= 0x100000 - addr)
+	    return 0;
+	  
+	  size -= 0x100000 - addr;
+	  addr = 0x100000;
 	}
-      else
-	add_mem_region (0x100000, grub_get_memsize (1) << 10);
+	
+      /* Ignore >4GB.  */
+      if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE)
+	{
+	  grub_size_t len;
+	  
+	  len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
+		 ? 0xFFFFFFFF - addr
+		 : size);
+	  add_mem_region (addr, len);
+	}
+
+      return 0;
     }
 
+  grub_machine_mmap_iterate (hook);
+  
   compact_mem_regions ();
 
   /* Add the memory regions to free memory, except for the region starting

Added: trunk/grub2/kern/i386/pc/mmap.c
===================================================================
--- trunk/grub2/kern/i386/pc/mmap.c	                        (rev 0)
+++ trunk/grub2/kern/i386/pc/mmap.c	2008-08-17 16:32:18 UTC (rev 1817)
@@ -0,0 +1,60 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,2003,2004,2005,2006,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 <grub/machine/init.h>
+#include <grub/machine/memory.h>
+#include <grub/types.h>
+
+void
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t))
+{
+  grub_uint32_t cont;
+  struct grub_machine_mmap_entry *entry
+    = (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+  
+  /* Check if grub_get_mmap_entry works.  */
+  cont = grub_get_mmap_entry (entry, 0);
+
+  if (entry->size)
+    do
+      {
+	if (hook (entry->addr, entry->len,
+		  /* Multiboot mmaps have been defined to match with the E820 definition.
+		     Therefore, we can just pass type through.  */
+		  entry->type))
+	  break;
+
+	if (! cont)
+	  break;
+
+	cont = grub_get_mmap_entry (entry, cont);
+      }
+    while (entry->size);
+  else
+    {
+      grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
+
+      if (eisa_mmap)
+	{
+	  if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10, GRUB_MACHINE_MEMORY_AVAILABLE) == 0)
+	    hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MACHINE_MEMORY_AVAILABLE);
+	}
+      else
+	hook (0x100000, grub_get_memsize (1) << 10, GRUB_MACHINE_MEMORY_AVAILABLE);
+    }
+}

Modified: trunk/grub2/loader/i386/pc/multiboot.c
===================================================================
--- trunk/grub2/loader/i386/pc/multiboot.c	2008-08-17 15:50:36 UTC (rev 1816)
+++ trunk/grub2/loader/i386/pc/multiboot.c	2008-08-17 16:32:18 UTC (rev 1817)
@@ -78,14 +78,60 @@
       grub_free ((void *) mbi->cmdline);
       grub_free (mbi);
     }
-
-
+  
   mbi = 0;
   grub_dl_unref (my_mod);
 
   return GRUB_ERR_NONE;
 }
 
+/* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is mandated
+   by the spec.  Is there something we can do about it?  */
+static grub_uint32_t mmap_addr = 0;
+static grub_uint32_t mmap_length;
+
+/* Return the length of the Multiboot mmap that will be needed to allocate
+   our platform's map.  */
+static grub_uint32_t
+grub_get_multiboot_mmap_len ()
+{
+  grub_size_t count = 0;
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
+			     grub_uint64_t size __attribute__ ((unused)),
+			     grub_uint32_t type __attribute__ ((unused)))
+    {
+      count++;
+      return 0;
+    }
+  
+  grub_machine_mmap_iterate (hook);
+  
+  return count * sizeof (struct grub_multiboot_mmap_entry);
+}
+
+/* Fill previously allocated Multiboot mmap.  */
+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;
+
+  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;
+      mmap_entry->size = sizeof (struct grub_multiboot_mmap_entry) - sizeof (mmap_entry->size);
+      mmap_entry++;
+
+      return 0;
+    }
+
+  grub_machine_mmap_iterate (hook);
+}
+
 /* Check if BUFFER contains ELF32.  */
 static int
 grub_multiboot_is_elf32 (void *buffer)
@@ -127,7 +173,7 @@
 	if (phdr(i)->p_paddr > phdr(highest_segment)->p_paddr)
 	  highest_segment = i;
       }
-  grub_multiboot_payload_size = (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
+  grub_multiboot_payload_size += (phdr(highest_segment)->p_paddr + phdr(highest_segment)->p_memsz) - phdr(lowest_segment)->p_paddr;
   grub_multiboot_payload_dest = phdr(lowest_segment)->p_paddr;
 
   playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
@@ -379,6 +425,9 @@
       playground = NULL;
     }
 
+  mmap_length = grub_get_multiboot_mmap_len ();
+  grub_multiboot_payload_size = mmap_length;
+
   if (header->flags & MULTIBOOT_AOUT_KLUDGE)
     {
       int offset = ((char *) header - buffer -
@@ -387,9 +436,9 @@
 		       header->load_end_addr - header->load_addr);
 
       if (header->bss_end_addr)
-	grub_multiboot_payload_size = (header->bss_end_addr - header->load_addr);
+	grub_multiboot_payload_size += (header->bss_end_addr - header->load_addr);
       else
-	grub_multiboot_payload_size = load_size;
+	grub_multiboot_payload_size += load_size;
       grub_multiboot_payload_dest = header->load_addr;
 
       playground = grub_malloc (RELOCATOR_SIZEOF(forward) + grub_multiboot_payload_size + RELOCATOR_SIZEOF(backward));
@@ -416,6 +465,12 @@
     goto fail;
 
       
+  grub_fill_multiboot_mmap ((struct grub_mmap_entry *) (grub_multiboot_payload_orig
+							+ grub_multiboot_payload_size
+							- mmap_length));
+
+  mmap_addr = grub_multiboot_payload_dest + grub_multiboot_payload_size - mmap_length;
+
   if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig)
     {
       grub_memmove (playground, &grub_multiboot_forward_relocator, RELOCATOR_SIZEOF(forward));
@@ -439,12 +494,15 @@
 
   grub_memset (mbi, 0, sizeof (struct grub_multiboot_info));
 
-  mbi->flags = MULTIBOOT_INFO_MEMORY;
-
   /* Convert from bytes to kilobytes.  */
   mbi->mem_lower = grub_lower_mem / 1024;
   mbi->mem_upper = grub_upper_mem / 1024;
+  mbi->flags |= MULTIBOOT_INFO_MEMORY;
 
+  mbi->mmap_addr = mmap_addr;
+  mbi->mmap_length = mmap_length;
+  mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
+
   for (i = 0, len = 0; i < argc; i++)
     len += grub_strlen (argv[i]) + 1;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.