git: 9front

Download patch

ref: 68cda8f4a0a560c08ad8e025e334bd66f9ef2bcd
parent: d266f3af96513436a00da71db545cd54ad0225b2
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Nov 20 14:05:43 EST 2014

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.

--- a/sys/src/9/pc/memory.c
+++ b/sys/src/9/pc/memory.c
@@ -340,6 +340,24 @@
 	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 @@
 				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 @@
 static void
 lowraminit(void)
 {
-	ulong pa, x;
-	uchar *bda;
+	uintptr pa, x;
 
 	/*
 	 * Initialise the memory bank information for conventional memory
@@ -387,16 +402,13 @@
 	 * 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");
--- a/sys/src/9/pc64/memory.c
+++ b/sys/src/9/pc64/memory.c
@@ -337,6 +337,24 @@
 	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 @@
 				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 @@
 lowraminit(void)
 {
 	uintptr pa, x;
-	uchar *bda;
 
 	/*
 	 * Initialise the memory bank information for conventional memory
@@ -384,10 +399,7 @@
 	 * 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 */
--