[2011] 2009-03-03 Robert Millan <[email protected]>

Robert Millan <[email protected]>
Newsgroups gmane.comp.boot-loaders.grub.cvs
Message-ID <[email protected]>
Revision: 2011
          http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=2011
Author:   robertmh
Date:     2009-03-03 19:00:41 +0000 (Tue, 03 Mar 2009)
Log Message:
-----------
2009-03-03  Robert Millan  <[email protected]>

        Move more components to the relocation area, and fix mbi pointer
        handling to use the destination rather than the origin (thanks to
        Vladimir Serbinenko for spotting).

        * loader/i386/multiboot.c (mbi_dest): New variable.
        (grub_multiboot_boot): Use `mbi_dest' instead of `mbi'.
        (grub_multiboot): Put cmdline, boot_loader_name and mbi in the
        relocation area.

Modified Paths:
--------------
    trunk/grub2/ChangeLog
    trunk/grub2/loader/i386/multiboot.c

Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog	2009-03-01 17:57:57 UTC (rev 2010)
+++ trunk/grub2/ChangeLog	2009-03-03 19:00:41 UTC (rev 2011)
@@ -1,3 +1,14 @@
+2009-03-03  Robert Millan  <[email protected]>
+
+	Move more components to the relocation area, and fix mbi pointer
+	handling to use the destination rather than the origin (thanks to
+	Vladimir Serbinenko for spotting).
+
+	* loader/i386/multiboot.c (mbi_dest): New variable.
+	(grub_multiboot_boot): Use `mbi_dest' instead of `mbi'.
+	(grub_multiboot): Put cmdline, boot_loader_name and mbi in the
+	relocation area.
+
 2009-03-01  Bean  <[email protected]>
 
 	* include/grub/efi/api.h (GRUB_EFI_MPS_TABALE_GUID): New constant.

Modified: trunk/grub2/loader/i386/multiboot.c
===================================================================
--- trunk/grub2/loader/i386/multiboot.c	2009-03-01 17:57:57 UTC (rev 2010)
+++ trunk/grub2/loader/i386/multiboot.c	2009-03-03 19:00:41 UTC (rev 2011)
@@ -44,7 +44,7 @@
 #include <grub/env.h>
 
 extern grub_dl_t my_mod;
-static struct grub_multiboot_info *mbi;
+static struct grub_multiboot_info *mbi, *mbi_dest;
 static grub_addr_t entry;
 
 static char *playground = NULL;
@@ -52,7 +52,7 @@
 static grub_err_t
 grub_multiboot_boot (void)
 {
-  grub_multiboot_real_boot (entry, mbi);
+  grub_multiboot_real_boot (entry, mbi_dest);
 
   /* Not reached.  */
   return GRUB_ERR_NONE;
@@ -195,7 +195,7 @@
   grub_file_t file = 0;
   char buffer[MULTIBOOT_SEARCH], *cmdline = 0, *p;
   struct grub_multiboot_header *header;
-  grub_ssize_t len;
+  grub_ssize_t len, cmdline_length, boot_loader_name_length;
   grub_uint32_t mmap_length;
   int i;
 
@@ -253,8 +253,23 @@
 
   mmap_length = grub_get_multiboot_mmap_len ();
 
-  grub_multiboot_payload_size = sizeof (struct grub_multiboot_info) + mmap_length + MULTIBOOT_INFO_ALIGN;
+  /* Figure out cmdline length.  */
+  for (i = 0, cmdline_length = 0; i < argc; i++)
+    cmdline_length += grub_strlen (argv[i]) + 1;
 
+  boot_loader_name_length = sizeof(PACKAGE_STRING);
+
+#define cmdline_addr(x)		((void *) ((x) + grub_multiboot_payload_size - mmap_length - sizeof (struct grub_multiboot_info) - boot_loader_name_length - cmdline_length))
+#define boot_loader_name_addr(x) \
+				((void *) ((x) + grub_multiboot_payload_size - mmap_length - sizeof (struct grub_multiboot_info) - boot_loader_name_length))
+#define mbi_addr(x)		((void *) ((x) + grub_multiboot_payload_size - mmap_length - sizeof (struct grub_multiboot_info)))
+#define mmap_addr(x)		((void *) ((x) + grub_multiboot_payload_size - mmap_length))
+
+  /* This provides alignment for the MBI, the memory map and the backward relocator.  */
+  boot_loader_name_length += (ALIGN_UP (mbi_addr (0), 4) - (unsigned long) mbi_addr (0));
+
+  grub_multiboot_payload_size = cmdline_length + boot_loader_name_length + sizeof (struct grub_multiboot_info) + mmap_length;
+
   if (header->flags & MULTIBOOT_AOUT_KLUDGE)
     {
       int offset = ((char *) header - buffer -
@@ -291,19 +306,16 @@
   else if (grub_multiboot_load_elf (file, buffer) != GRUB_ERR_NONE)
     goto fail;
 
-  grub_multiboot_payload_size = ALIGN_UP (grub_multiboot_payload_size, MULTIBOOT_INFO_ALIGN);
-
-  mbi = (void *) (grub_multiboot_payload_orig + grub_multiboot_payload_size - mmap_length - sizeof (struct grub_multiboot_info));
+  mbi = mbi_addr (grub_multiboot_payload_orig);
+  mbi_dest = mbi_addr (grub_multiboot_payload_dest);
   grub_memset (mbi, 0, sizeof (struct grub_multiboot_info));
   mbi->mmap_length = mmap_length;
       
-  grub_fill_multiboot_mmap ((struct grub_multiboot_mmap_entry *) (grub_multiboot_payload_orig
-								  + grub_multiboot_payload_size
-								  - mbi->mmap_length));
+  grub_fill_multiboot_mmap (mmap_addr (grub_multiboot_payload_orig));
 
   /* 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?  */
-  mbi->mmap_addr = grub_multiboot_payload_dest + grub_multiboot_payload_size - mbi->mmap_length;
+  mbi->mmap_addr = mmap_addr (grub_multiboot_payload_dest);
   mbi->flags |= MULTIBOOT_INFO_MEM_MAP;
 
   if (grub_multiboot_payload_dest >= grub_multiboot_payload_orig)
@@ -328,10 +340,7 @@
   mbi->mem_upper = grub_upper_mem / 1024;
   mbi->flags |= MULTIBOOT_INFO_MEMORY;
 
-  for (i = 0, len = 0; i < argc; i++)
-    len += grub_strlen (argv[i]) + 1;
-
-  cmdline = p = grub_malloc (len);
+  cmdline = p = cmdline_addr (grub_multiboot_payload_orig);
   if (! cmdline)
     goto fail;
 
@@ -345,10 +354,12 @@
   *(--p) = '\0';
 
   mbi->flags |= MULTIBOOT_INFO_CMDLINE;
-  mbi->cmdline = (grub_uint32_t) cmdline;
+  mbi->cmdline = (grub_uint32_t) cmdline_addr (grub_multiboot_payload_dest);
 
+
+  grub_strcpy (boot_loader_name_addr (grub_multiboot_payload_orig), PACKAGE_STRING);
   mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
-  mbi->boot_loader_name = (grub_uint32_t) grub_strdup (PACKAGE_STRING);
+  mbi->boot_loader_name = (grub_uint32_t) boot_loader_name_addr (grub_multiboot_payload_dest);
 
   if (grub_multiboot_get_bootdev (&mbi->boot_device))
     mbi->flags |= MULTIBOOT_INFO_BOOTDEV;
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.