From 529082d34d2bafd81d5987a2ed646c3a3c88a0a2 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Thu, 20 Nov 2014 19:05:43 +0100 Subject: pc, pc64: preserve last KB of conventional memory (might contain bios tables) we add new function convmemsize() that returns the size of *usable* conventional memory that does some sanity checking and reserves the last KB below the top of memory pointer. this avoids lowraminit() overriding potential bios tables and sigsearch() going off the rails looking for tables at above 640K. --- sys/src/9/pc/memory.c | 34 +++++++++++++++++++++++----------- sys/src/9/pc64/memory.c | 30 +++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/sys/src/9/pc/memory.c b/sys/src/9/pc/memory.c index acff53d10..53e81758a 100644 --- a/sys/src/9/pc/memory.c +++ b/sys/src/9/pc/memory.c @@ -340,6 +340,24 @@ sigscan(uchar* addr, int len, char* signature) return nil; } +static uintptr +convmemsize(void) +{ + uintptr top; + uchar *bda; + + bda = KADDR(0x400); + top = ((bda[0x14]<<8) | bda[0x13])*KB; + + if(top < 64*KB || top > 640*KB) + top = 640*KB; /* sanity */ + + /* reserved for bios tables (EBDA) */ + top -= 1*KB; + + return top; +} + void* sigsearch(char* signature) { @@ -362,11 +380,9 @@ sigsearch(char* signature) return r; } } + if((r = sigscan(KADDR(convmemsize()), 1024, signature)) != nil) + return r; - if((p = ((bda[0x14]<<8)|bda[0x13])*1024) != 0){ - if((r = sigscan(KADDR(p-1024), 1024, signature)) != nil) - return r; - } /* hack for virtualbox: look in KiB below 0xa0000 */ if((r = sigscan(KADDR(0xa0000-1024), 1024, signature)) != nil) return r; @@ -377,8 +393,7 @@ sigsearch(char* signature) static void lowraminit(void) { - ulong pa, x; - uchar *bda; + uintptr pa, x; /* * Initialise the memory bank information for conventional memory @@ -387,16 +402,13 @@ lowraminit(void) * the BIOS data area. */ x = PADDR(CPU0END); - bda = (uchar*)KADDR(0x400); - pa = ((bda[0x14]<<8)|bda[0x13])*KB; - if(pa > 640*KB) - pa = 640*KB; + pa = convmemsize(); if(x < pa){ mapfree(&rmapram, x, pa-x); memset(KADDR(x), 0, pa-x); /* keep us honest */ } - x = PADDR(PGROUND((ulong)end)); + x = PADDR(PGROUND((uintptr)end)); pa = MemMin; if(x > pa) panic("kernel too big"); diff --git a/sys/src/9/pc64/memory.c b/sys/src/9/pc64/memory.c index 349133976..cb2c15219 100644 --- a/sys/src/9/pc64/memory.c +++ b/sys/src/9/pc64/memory.c @@ -337,6 +337,24 @@ sigscan(uchar* addr, int len, char* signature) return nil; } +static uintptr +convmemsize(void) +{ + uintptr top; + uchar *bda; + + bda = KADDR(0x400); + top = ((bda[0x14]<<8) | bda[0x13])*KB; + + if(top < 64*KB || top > 640*KB) + top = 640*KB; /* sanity */ + + /* reserved for bios tables (EBDA) */ + top -= 1*KB; + + return top; +} + void* sigsearch(char* signature) { @@ -359,11 +377,9 @@ sigsearch(char* signature) return r; } } + if((r = sigscan(KADDR(convmemsize()), 1024, signature)) != nil) + return r; - if((p = ((bda[0x14]<<8)|bda[0x13])*1024) != 0){ - if((r = sigscan(KADDR(p-1024), 1024, signature)) != nil) - return r; - } /* hack for virtualbox: look in KiB below 0xa0000 */ if((r = sigscan(KADDR(0xa0000-1024), 1024, signature)) != nil) return r; @@ -375,7 +391,6 @@ static void lowraminit(void) { uintptr pa, x; - uchar *bda; /* * Initialise the memory bank information for conventional memory @@ -384,10 +399,7 @@ lowraminit(void) * the BIOS data area. */ x = PADDR(CPU0END); - bda = (uchar*)KADDR(0x400); - pa = ((bda[0x14]<<8)|bda[0x13])*KB; - if(pa > 640*KB) - pa = 640*KB; + pa = convmemsize(); if(x < pa){ mapfree(&rmapram, x, pa-x); memset(KADDR(x), 0, pa-x); /* keep us honest */ -- cgit v1.2.3