Messages in this thread | | | From | Ian Campbell <> | Date | Thu, 28 Feb 2008 21:12:11 +0000 | Subject | Re: [RFC] use realmode code to reserve end-of-conventional-memory to 1MB |
| |
On Thu, 2008-02-28 at 14:28 +0100, Alexander van Heukelum wrote: > 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.
An e820 is already faked up in machine_specific_memory_setup() if one doesn't already exist.
> Comments?
This won't work for Xen since the real-mode code never runs there. I think it could be fixed in xen_memory_setup() though if native goes down this route.
Ian.
> > Signed-off-by: Alexander van Heukelum <heukelum@fastmail.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; > } > > > -- Ian Campbell
Nasrudin walked into a teahouse and declaimed, "The moon is more useful than the sun." "Why?", he was asked. "Because at night we need the light more."
| |