On 24.05.2012 19:27, stuart_ha...@dell.com wrote:

> Hello…
> 
>  
> 
> I just submitted a grub2 bug, along with a patch, at
> <http://savannah.gnu.org/bugs/?36532>.

Could you test the attached patch on top of HEAD?
-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
=== modified file 'grub-core/loader/efi/chainloader.c'
--- grub-core/loader/efi/chainloader.c	2012-03-10 19:41:28 +0000
+++ grub-core/loader/efi/chainloader.c	2012-05-27 14:29:35 +0000
@@ -111,14 +111,16 @@
 
   fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
   fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
-  size = len * sizeof (grub_efi_char16_t) + sizeof (*fp);
+
+  size = grub_utf8_to_utf16 (fp->path_name, len * GRUB_MAX_UTF16_PER_UTF8,
+			     (const grub_uint8_t *) str, len, 0);
+  for (p = fp->path_name; p < fp->path_name + size; p++)
+    if (*p == '/')
+      *p = '\\';
+
+  size = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
   fp->header.length[0] = (grub_efi_uint8_t) (size & 0xff);
   fp->header.length[1] = (grub_efi_uint8_t) (size >> 8);
-  for (p = fp->path_name; len > 0; len--, p++, str++)
-    {
-      /* FIXME: this assumes that the path is in ASCII.  */
-      *p = (grub_efi_char16_t) (*str == '/' ? '\\' : *str);
-    }
 }
 
 static grub_efi_device_path_t *
@@ -154,6 +156,7 @@
 
   file_path = grub_malloc (size
 			   + ((grub_strlen (dir_start) + 1)
+			      * GRUB_MAX_UTF16_PER_UTF8
 			      * sizeof (grub_efi_char16_t))
 			   + sizeof (grub_efi_file_path_device_path_t) * 2);
   if (! file_path)

=== modified file 'grub-core/loader/i386/linux.c'
--- grub-core/loader/i386/linux.c	2012-04-17 11:00:06 +0000
+++ grub-core/loader/i386/linux.c	2012-05-27 14:44:23 +0000
@@ -59,14 +59,10 @@
 #define ACCEPTS_PURE_TEXT 1
 #endif
 
-#define GRUB_LINUX_CL_OFFSET		0x1000
-
 static grub_dl_t my_mod;
 
 static grub_size_t linux_mem_size;
 static int loaded;
-static void *real_mode_mem;
-static grub_addr_t real_mode_target;
 static void *prot_mode_mem;
 static grub_addr_t prot_mode_target;
 static void *initrd_mem;
@@ -78,6 +74,8 @@
 static struct grub_relocator *relocator = NULL;
 static void *efi_mmap_buf;
 static grub_size_t maximal_cmdline_size;
+static struct linux_kernel_params linux_params;
+static char *linux_cmdline;
 #ifdef GRUB_MACHINE_EFI
 static grub_efi_uintn_t efi_mmap_size;
 #else
@@ -183,8 +181,8 @@
 {
   grub_relocator_unload (relocator);
   relocator = NULL;
-  real_mode_mem = prot_mode_mem = initrd_mem = 0;
-  real_mode_target = prot_mode_target = initrd_mem_target = 0;
+  prot_mode_mem = initrd_mem = 0;
+  prot_mode_target = initrd_mem_target = 0;
 }
 
 /* Allocate pages for the real mode code and the protected mode code
@@ -194,31 +192,13 @@
 		grub_size_t min_align, int relocatable,
 		grub_uint64_t prefered_address)
 {
-  grub_size_t real_size, mmap_size;
   grub_err_t err;
-
-  /* Make sure that each size is aligned to a page boundary.  */
-  real_size = GRUB_LINUX_CL_OFFSET + maximal_cmdline_size;
-  prot_size = page_align (prot_size);
-  mmap_size = find_mmap_size ();
-
-#ifdef GRUB_MACHINE_EFI
-  efi_mmap_size = find_efi_mmap_size ();
-  if (efi_mmap_size == 0)
-    return grub_errno;
-#endif
-
-  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 + efi_mmap_size) >> 12);
   prot_mode_pages = (prot_size >> 12);
 
   /* Initialize the memory pointers with NULL for convenience.  */
   free_pages ();
 
+  prot_size = page_align (prot_size);
   relocator = grub_relocator_new ();
   if (!relocator)
     {
@@ -229,59 +209,6 @@
   /* 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_memory_type_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
-			     grub_memory_type_t type)
-    {
-      /* We must put real mode code in the traditional space.  */
-
-      if (type == GRUB_MEMORY_AVAILABLE
-	  && addr <= 0x90000)
-	{
-	  if (addr < 0x10000)
-	    {
-	      size += addr - 0x10000;
-	      addr = 0x10000;
-	    }
-
-	  if (addr + size > 0x90000)
-	    size = 0x90000 - addr;
-
-	  if (real_size + mmap_size + efi_mmap_size > size)
-	    return 0;
-
-	  real_mode_target = ((addr + size) - (real_size + mmap_size + efi_mmap_size));
-	  return 1;
-	}
-
-      return 0;
-    }
-#ifdef GRUB_MACHINE_EFI
-  grub_efi_mmap_iterate (hook, 1);
-  if (! real_mode_target)
-    grub_efi_mmap_iterate (hook, 0);
-#else
-  grub_mmap_iterate (hook);
-#endif
-  if (! real_mode_target)
-    {
-      err = grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
-      goto fail;
-    }
-
-  {
-    grub_relocator_chunk_t ch;
-    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
-					   real_mode_target,
-					   (real_size + mmap_size 
-					    + efi_mmap_size));
-    if (err)
-      goto fail;
-    real_mode_mem = get_virtual_current_address (ch);
-  }
-  efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size;
-
   {
     grub_relocator_chunk_t ch;
     if (relocatable)
@@ -315,9 +242,6 @@
     prot_mode_target = get_physical_target_address (ch);
   }
 
-  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_target = %lx, real_mode_pages = %x\n",
-                (unsigned long) real_mode_mem, (unsigned long) real_mode_target,
-		(unsigned) real_mode_pages);
   grub_dprintf ("linux", "prot_mode_mem = %lx, prot_mode_target = %lx, prot_mode_pages = %x\n",
                 (unsigned long) prot_mode_mem, (unsigned long) prot_mode_target,
 		(unsigned) prot_mode_pages);
@@ -335,12 +259,6 @@
 {
   int n = *e820_num;
 
-  if (n >= GRUB_E820_MAX_ENTRY)
-    {
-      return grub_error (GRUB_ERR_OUT_OF_RANGE,
-			 "Too many e820 memory map entries");
-    }
-
   if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
       (e820_map[n - 1].type == type))
       e820_map[n - 1].size += size;
@@ -462,9 +380,89 @@
   const char *modevar;
   char *tmp;
   struct grub_relocator32_state state;
+  void *real_mode_mem;
+  grub_addr_t real_mode_target;
+  grub_size_t real_size, mmap_size;
+  grub_size_t cl_offset;
+
+  mmap_size = find_mmap_size ();
+  /* Make sure that each size is aligned to a page boundary.  */
+  cl_offset = ALIGN_UP (mmap_size + sizeof (*params), 4096);
+  real_size = cl_offset + maximal_cmdline_size;
+
+#ifdef GRUB_MACHINE_EFI
+  efi_mmap_size = find_efi_mmap_size ();
+  if (efi_mmap_size == 0)
+    return grub_errno;
+#endif
+
+  grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n",
+		(unsigned) real_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 + efi_mmap_size) >> 12);
+
+  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
+				  grub_memory_type_t);
+  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
+			     grub_memory_type_t type)
+    {
+      /* We must put real mode code in the traditional space.  */
+
+      if (type == GRUB_MEMORY_AVAILABLE
+	  && addr <= 0x90000)
+	{
+	  if (addr < 0x10000)
+	    {
+	      size += addr - 0x10000;
+	      addr = 0x10000;
+	    }
+
+	  if (addr + size > 0x90000)
+	    size = 0x90000 - addr;
+
+	  if (real_size + efi_mmap_size > size)
+	    return 0;
+
+	  real_mode_target = ((addr + size) - (real_size + efi_mmap_size));
+	  return 1;
+	}
+
+      return 0;
+    }
+#ifdef GRUB_MACHINE_EFI
+  grub_efi_mmap_iterate (hook, 1);
+  if (! real_mode_target)
+    grub_efi_mmap_iterate (hook, 0);
+#else
+  grub_mmap_iterate (hook);
+#endif
+  if (! real_mode_target)
+    return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
+
+  {
+    grub_relocator_chunk_t ch;
+    err = grub_relocator_alloc_chunk_addr (relocator, &ch,
+					   real_mode_target,
+					   (real_size + efi_mmap_size));
+    if (err)
+     return err;
+    real_mode_mem = get_virtual_current_address (ch);
+  }
+  efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size;
+
+  grub_dprintf ("linux", "real_mode_mem = %lx, real_mode_target = %lx, real_mode_pages = %x\n",
+                (unsigned long) real_mode_mem, (unsigned long) real_mode_target,
+		(unsigned) real_mode_pages);
 
   params = real_mode_mem;
 
+  *params = linux_params;
+  params->cmd_line_ptr = real_mode_target + cl_offset;
+  grub_memcpy ((char *) params + cl_offset, linux_cmdline,
+	       maximal_cmdline_size);
+
 #ifdef GRUB_MACHINE_IEEE1275
   {
     const char *bootpath;
@@ -482,10 +480,10 @@
   grub_dprintf ("linux", "code32_start = %x\n",
 		(unsigned) params->code32_start);
 
-  auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
+  auto int NESTED_FUNC_ATTR hook_fill (grub_uint64_t, grub_uint64_t,
 				  grub_memory_type_t);
-  int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, 
-			     grub_memory_type_t type)
+  int NESTED_FUNC_ATTR hook_fill (grub_uint64_t addr, grub_uint64_t size, 
+				  grub_memory_type_t type)
     {
       grub_uint32_t e820_type;
       switch (type)
@@ -517,7 +515,7 @@
     }
 
   e820_num = 0;
-  if (grub_mmap_iterate (hook))
+  if (grub_mmap_iterate (hook_fill))
     return grub_errno;
   params->mmap_size = e820_num;
 
@@ -652,6 +650,8 @@
 {
   grub_dl_unref (my_mod);
   loaded = 0;
+  grub_free (linux_cmdline);
+  linux_cmdline = 0;
   return GRUB_ERR_NONE;
 }
 
@@ -781,16 +781,16 @@
 		      preffered_address))
     goto fail;
 
-  params = (struct linux_kernel_params *) real_mode_mem;
-  grub_memset (params, 0, GRUB_LINUX_CL_OFFSET + maximal_cmdline_size);
+  params = (struct linux_kernel_params *) &linux_params;
+  grub_memset (params, 0, sizeof (*params));
   grub_memcpy (&params->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
 
   params->code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
   params->kernel_alignment = (1 << align);
   params->ps_mouse = params->padding10 =  0;
 
-  len = 0x400 - sizeof (lh);
-  if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len)
+  len = sizeof (*params) - sizeof (lh);
+  if (grub_file_read (file, (char *) params + sizeof (lh), len) != len)
     {
       if (!grub_errno)
 	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -805,7 +805,6 @@
   params->cl_magic = GRUB_LINUX_CL_MAGIC;
   params->cl_offset = 0x1000;
 
-  params->cmd_line_ptr = real_mode_target + 0x1000;
   params->ramdisk_image = 0;
   params->ramdisk_size = 0;
 
@@ -978,10 +977,12 @@
       }
 
   /* Create kernel command line.  */
-  grub_memcpy ((char *)real_mode_mem + GRUB_LINUX_CL_OFFSET, LINUX_IMAGE,
-	      sizeof (LINUX_IMAGE));
+  linux_cmdline = grub_malloc (maximal_cmdline_size);
+  if (!linux_cmdline)
+    goto fail;
+  grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
   grub_create_loader_cmdline (argc, argv,
-			      (char *)real_mode_mem + GRUB_LINUX_CL_OFFSET
+			      linux_cmdline
 			      + sizeof (LINUX_IMAGE) - 1,
 			      maximal_cmdline_size
 			      - (sizeof (LINUX_IMAGE) - 1));
@@ -1054,7 +1055,7 @@
 
   initrd_pages = (page_align (size) >> 12);
 
-  lh = (struct linux_kernel_header *) real_mode_mem;
+  lh = (struct linux_kernel_header *) &linux_params;
 
   /* Get the highest address available for the initrd.  */
   if (grub_le_to_cpu16 (lh->version) >= 0x0203)

=== modified file 'include/grub/i386/linux.h'
--- include/grub/i386/linux.h	2012-03-04 11:13:05 +0000
+++ include/grub/i386/linux.h	2012-05-27 14:34:29 +0000
@@ -69,8 +69,6 @@
 #define GRUB_E820_NVS        4
 #define GRUB_E820_BADRAM     5
 
-#define GRUB_E820_MAX_ENTRY  128
-
 struct grub_e820_mmap
 {
   grub_uint64_t addr;
@@ -298,7 +296,7 @@
   grub_uint32_t payload_length;
   grub_uint64_t setup_data;
   grub_uint8_t pad2[120];		/* 258 */
-  struct grub_e820_mmap e820_map[GRUB_E820_MAX_ENTRY];	/* 2d0 */
+  struct grub_e820_mmap e820_map[(0x400 - 0x2d0) / 20];	/* 2d0 */
 
 } __attribute__ ((packed));
 #endif /* ! ASM_FILE */

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to