nalika / rpms / grub2

Forked from rpms/grub2 2 years ago
Clone

Blame SOURCES/0171-Enable-linux16-on-non-BIOS-systems-for-i.a.-memtest.patch

f96e0b
From d8d7d9fd00cfac60bb26d66c2a1ce07275c35b8b Mon Sep 17 00:00:00 2001
f96e0b
From: Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
f96e0b
Date: Thu, 28 Feb 2013 22:48:41 +0100
f96e0b
Subject: [PATCH 171/482] 	Enable linux16 on non-BIOS systems for i.a.
f96e0b
 memtest.
f96e0b
f96e0b
	* grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Handle hole at 0
f96e0b
	correctly.
f96e0b
	* grub-core/Makefile.core.def (linux16): Enable on all x86 flavours.
f96e0b
---
f96e0b
 ChangeLog                        |  8 ++++++
f96e0b
 grub-core/Makefile.core.def      |  6 ++--
f96e0b
 grub-core/loader/i386/pc/linux.c | 60 ++++++++++++++++++++++++++++------------
f96e0b
 3 files changed, 54 insertions(+), 20 deletions(-)
f96e0b
f96e0b
diff --git a/ChangeLog b/ChangeLog
f96e0b
index 0eb0516..135586c 100644
f96e0b
--- a/ChangeLog
f96e0b
+++ b/ChangeLog
f96e0b
@@ -1,5 +1,13 @@
f96e0b
 2013-02-28  Vladimir Serbinenko  <phcoder@gmail.com>
f96e0b
 
f96e0b
+	Enable linux16 on non-BIOS systems for i.a. memtest.
f96e0b
+
f96e0b
+	* grub-core/loader/i386/pc/linux.c (grub_cmd_linux): Handle hole at 0
f96e0b
+	correctly.
f96e0b
+	* grub-core/Makefile.core.def (linux16): Enable on all x86 flavours.
f96e0b
+
f96e0b
+2013-02-28  Vladimir Serbinenko  <phcoder@gmail.com>
f96e0b
+
f96e0b
 	* grub-core/kern/i386/coreboot/mmap.c (grub_linuxbios_table_iterate):
f96e0b
 	Fix end of table condition.
f96e0b
 
f96e0b
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
f96e0b
index 4b0e6e6..93ff2a8 100644
f96e0b
--- a/grub-core/Makefile.core.def
f96e0b
+++ b/grub-core/Makefile.core.def
f96e0b
@@ -1390,9 +1390,9 @@ module = {
f96e0b
 
f96e0b
 module = {
f96e0b
   name = linux16;
f96e0b
-  i386_pc = loader/i386/pc/linux.c;
f96e0b
-  i386_pc = lib/cmdline.c;
f96e0b
-  enable = i386_pc;
f96e0b
+  common = loader/i386/pc/linux.c;
f96e0b
+  common = lib/cmdline.c;
f96e0b
+  enable = x86;
f96e0b
 };
f96e0b
 
f96e0b
 module = {
f96e0b
diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
f96e0b
index 4eeb1b6..39206c8 100644
f96e0b
--- a/grub-core/loader/i386/pc/linux.c
f96e0b
+++ b/grub-core/loader/i386/pc/linux.c
f96e0b
@@ -79,6 +79,42 @@ grub_linux_unload (void)
f96e0b
   return GRUB_ERR_NONE;
f96e0b
 }
f96e0b
 
f96e0b
+static int
f96e0b
+target_hook (grub_uint64_t addr, grub_uint64_t size, grub_memory_type_t type,
f96e0b
+	    void *data)
f96e0b
+{
f96e0b
+  grub_uint64_t *result = data;
f96e0b
+  grub_uint64_t candidate;
f96e0b
+
f96e0b
+  if (type != GRUB_MEMORY_AVAILABLE)
f96e0b
+    return 0;
f96e0b
+  if (addr >= 0xa0000)
f96e0b
+    return 0;
f96e0b
+  if (addr + size >= 0xa0000)
f96e0b
+    size = 0xa0000 - addr;
f96e0b
+
f96e0b
+  /* Put the real mode part at as a high location as possible.  */
f96e0b
+  candidate = addr + size - (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size);
f96e0b
+  /* But it must not exceed the traditional area.  */
f96e0b
+  if (candidate > GRUB_LINUX_OLD_REAL_MODE_ADDR)
f96e0b
+    candidate = GRUB_LINUX_OLD_REAL_MODE_ADDR;
f96e0b
+  if (candidate < addr)
f96e0b
+    return 0;
f96e0b
+
f96e0b
+  if (candidate > *result || *result == (grub_uint64_t) -1)
f96e0b
+    *result = candidate;
f96e0b
+  return 0;
f96e0b
+}
f96e0b
+
f96e0b
+static grub_addr_t
f96e0b
+grub_find_real_target (void)
f96e0b
+{
f96e0b
+  grub_uint64_t result = (grub_uint64_t) -1;
f96e0b
+
f96e0b
+  grub_mmap_iterate (target_hook, &result);
f96e0b
+  return result;
f96e0b
+}
f96e0b
+
f96e0b
 static grub_err_t
f96e0b
 grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
f96e0b
 		int argc, char *argv[])
f96e0b
@@ -141,12 +177,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
f96e0b
       if (grub_le_to_cpu16 (lh.version) >= 0x0206)
f96e0b
 	maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1;
f96e0b
 
f96e0b
-      /* Put the real mode part at as a high location as possible.  */
f96e0b
-      grub_linux_real_target = grub_mmap_get_lower () 
f96e0b
-	- (GRUB_LINUX_CL_OFFSET + maximal_cmdline_size);
f96e0b
-      /* But it must not exceed the traditional area.  */
f96e0b
-      if (grub_linux_real_target > GRUB_LINUX_OLD_REAL_MODE_ADDR)
f96e0b
-	grub_linux_real_target = GRUB_LINUX_OLD_REAL_MODE_ADDR;
f96e0b
+      grub_linux_real_target = grub_find_real_target ();
f96e0b
+      if (grub_linux_real_target == (grub_addr_t)-1)
f96e0b
+	{
f96e0b
+	  grub_error (GRUB_ERR_OUT_OF_RANGE,
f96e0b
+		      "no appropriate low memory found");
f96e0b
+	  goto fail;
f96e0b
+	}
f96e0b
 
f96e0b
       if (grub_le_to_cpu16 (lh.version) >= 0x0201)
f96e0b
 	{
f96e0b
@@ -193,17 +230,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
f96e0b
       goto fail;
f96e0b
     }
f96e0b
 
f96e0b
-  if (grub_linux_real_target + GRUB_LINUX_CL_OFFSET + maximal_cmdline_size
f96e0b
-      > grub_mmap_get_lower ())
f96e0b
-    {
f96e0b
-      grub_error (GRUB_ERR_OUT_OF_RANGE,
f96e0b
-		 "too small lower memory (0x%x > 0x%x)",
f96e0b
-		  grub_linux_real_target + GRUB_LINUX_CL_OFFSET
f96e0b
-		  + maximal_cmdline_size,
f96e0b
-		  (int) grub_mmap_get_lower ());
f96e0b
-      goto fail;
f96e0b
-    }
f96e0b
-
f96e0b
   grub_dprintf ("linux", "[Linux-%s, setup=0x%x, size=0x%x]\n",
f96e0b
 		grub_linux_is_bzimage ? "bzImage" : "zImage", real_size,
f96e0b
 		grub_linux16_prot_size);
f96e0b
-- 
f96e0b
1.8.2.1
f96e0b