[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20080228132822.GA25278@mailshack.com>
Date: Thu, 28 Feb 2008 14:28:23 +0100
From: Alexander van Heukelum <heukelum@...lshack.com>
To: Ingo Molnar <mingo@...e.hu>, Ian Campbell <ijc@...lion.org.uk>
Cc: Alexander van Heukelum <heukelum@...tmail.fm>,
"H. Peter Anvin" <hpa@...or.com>, Andi Kleen <ak@...e.de>,
Thomas Gleixner <tglx@...utronix.de>,
Jeremy Fitzhardinge <jeremy@...p.org>,
Mark McLoughlin <markmc@...hat.com>,
LKML <linux-kernel@...r.kernel.org>
Subject: [RFC] use realmode code to reserve end-of-conventional-memory to 1MB
Instead of using early reservations inside the kernel code,
we could use the realmode code to modify the e820 memmap.
This patch shows what that would look like. I have not looked
at the case where the BIOS does not provide an e820 memmap
yet. Probably a full solution would need to create a fake
e820 memmap in that case.
Comments?
Signed-off-by: Alexander van Heukelum <heukelum@...tmail.fm>
diff --git a/arch/x86/boot/memory.c b/arch/x86/boot/memory.c
index e77d89f..522920a 100644
--- a/arch/x86/boot/memory.c
+++ b/arch/x86/boot/memory.c
@@ -23,6 +23,7 @@ static int detect_memory_e820(void)
int count = 0;
u32 next = 0;
u32 size, id;
+ u32 lowmem, ebda_addr;
u8 err;
struct e820entry *desc = boot_params.e820_map;
@@ -50,13 +51,51 @@ static int detect_memory_e820(void)
just return failure. */
if (id != SMAP) {
count = 0;
- break;
+ goto out;
}
count++;
desc++;
- } while (next && count < E820MAX);
-
+ } while (next && count < (E820MAX - 1));
+
+ /* Some BIOSes do not reserve the EBDA/XBDA area correctly in.
+ The e820-map. Find out where the EBDA resides by looking at
+ the BIOS data area and reserve the EBDA and the following
+ legacy adapter area explicitly. */
+#define BIOS_EBDA_SEGMENT 0x40E
+#define BIOS_LOWMEM_KILOBYTES 0x413
+
+ /* end of low (conventional) memory */
+ set_fs(0);
+ lowmem = rdfs16(BIOS_LOWMEM_KILOBYTES);
+ lowmem <<= 10;
+
+ /* start of EBDA area */
+ ebda_addr = rdfs16(BIOS_EBDA_SEGMENT);
+ ebda_addr <<= 4;
+
+ /* Fixup: bios puts an EBDA in the top 64K segment */
+ /* of conventional memory, but does not adjust lowmem. */
+ if ((lowmem - ebda_addr) <= 0x10000)
+ lowmem = ebda_addr;
+
+ /* Fixup: bios does not report an EBDA at all. */
+ /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */
+ if ((ebda_addr == 0) && (lowmem >= 0x9f000))
+ lowmem = 0x9f000;
+
+ /* Paranoia: should never happen, but... */
+ if (lowmem >= 0x100000)
+ lowmem = 0xa0000;
+
+ /* reserve all memory between lowmem and the 1MB mark */
+ desc->addr = lowmem;
+ desc->size = 0x100000 - lowmem;
+ desc->type = E820_RESERVED;
+ count++;
+ desc++;
+
+out:
return boot_params.e820_entries = count;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists