lkml.org 
[lkml]   [2008]   [Feb]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    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@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;
    }



    \
     
     \ /
      Last update: 2008-02-28 14:35    [W:2.699 / U:0.284 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site