Messages in this thread Patch in this message | | | Date | Tue, 24 Aug 1999 18:40:49 +0200 (CEST) | From | Andrea Arcangeli <> | Subject | [patch] endbase patch in 2.2.12-final3 may lose 640k of ram |
| |
Some time ago I written this proggy to check the endbase value from lots of BIOSes:
#include <fcntl.h> #include <unistd.h>
main() { unsigned long bios_base_mem_limit_addr; unsigned short bios_base_mem_limit; unsigned long value; int mem;
bios_base_mem_limit_addr = 0x413; mem = open("/dev/mem", O_RDONLY); if (mem < 0) perror("open"), exit(1); if (lseek(mem, bios_base_mem_limit_addr, SEEK_SET) < 0) perror("lseek"), exit(1); if (read(mem, &bios_base_mem_limit, 2) < 2) perror("read"), exit(1);
value = ((unsigned long) bios_base_mem_limit) << 10; printf("high limit of low memory: decimal %lu, hex %lx\n", value, value); }
and I had report about some motherbard that was reading zero from the endbase address. This mean that 2.2.12-final3 will lose around 640k of ram in such _real-world_ motherboards. Also the endbios code completly depends on the presence of a bios.
Due these issues I rewritten the endbase patch to allow the end user to override the endbase address. I also noticed an error in smp_alloc_memory and I fixed it as well.
Patch against 2.2.12-final3:
diff -urN 2.2.12-final3/Documentation/memory.txt 2.2.12-final3-endbase/Documentation/memory.txt --- 2.2.12-final3/Documentation/memory.txt Mon Jan 18 02:29:29 1999 +++ 2.2.12-final3-endbase/Documentation/memory.txt Tue Aug 24 18:13:59 1999 @@ -54,3 +54,11 @@ * Try passing the "no-hlt" option to disable the potentially buggy HLT instruction in your CPU. + + * Passing for example the "endbase=0x9F000" option to the kernel, + you'll _force_ the kernel to not touch the memory between 0x9F000 + and 1Mbyte. As default the kernel reads the endbase limit from + the BIOS. So you need to specify this option only if the BIOS + does not provide the right information to the kernel (or if you + don't have a BIOS at all :). You can discover the endbase value + of your running kernel with this command `dmesg | grep endbase`. diff -urN 2.2.12-final3/arch/i386/kernel/setup.c 2.2.12-final3-endbase/arch/i386/kernel/setup.c --- 2.2.12-final3/arch/i386/kernel/setup.c Sun Aug 22 15:51:43 1999 +++ 2.2.12-final3-endbase/arch/i386/kernel/setup.c Tue Aug 24 18:15:17 1999 @@ -122,6 +122,8 @@ #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 +#define BIOS_ENDBASE 0x9F000 + #ifdef CONFIG_VISWS char visws_board_type = -1; char visws_board_rev = -1; @@ -251,6 +253,7 @@ static char command_line[COMMAND_LINE_SIZE] = { 0, }; char saved_command_line[COMMAND_LINE_SIZE]; +unsigned long i386_endbase __initdata = 0; __initfunc(void setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)) @@ -258,6 +261,7 @@ unsigned long memory_start, memory_end; char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; + int read_endbase_from_BIOS = 1; #ifdef CONFIG_VISWS visws_get_board_type_and_rev(); @@ -326,6 +330,13 @@ } } } + else if (c == ' ' && !memcmp(from, "endbase=", 8)) + { + if (to != command_line) to--; + i386_endbase = simple_strtoul(from+8, &from, 0); + i386_endbase += PAGE_OFFSET; + read_endbase_from_BIOS = 0; + } c = *(from++); if (!c) break; @@ -335,6 +346,29 @@ } *to = '\0'; *cmdline_p = command_line; + + if (read_endbase_from_BIOS) + { + /* + * IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000. + * They seem to have done something stupid with the floppy + * controller as well.. + * The amount of available base memory is now taken from + * WORD 40:13 in order to account for some recent systems, + * where its value is smaller than the standard BIOS_ENDBASE + * (this was pointed out by Josef Moellers from + * Siemens Paderborn (Germany) ). + */ + i386_endbase = (*(unsigned short *)__va(0x413)*1024)&PAGE_MASK; + if (!i386_endbase || i386_endbase > 0xA0000) + { + printk(KERN_NOTICE + "endbase 0x%lx is weird so revert to %x\n", + i386_endbase, BIOS_ENDBASE); + i386_endbase = BIOS_ENDBASE; + } + i386_endbase += PAGE_OFFSET; + } #define VMALLOC_RESERVE (64 << 20) /* 64MB for vmalloc */ #define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)) diff -urN 2.2.12-final3/arch/i386/kernel/smp.c 2.2.12-final3-endbase/arch/i386/kernel/smp.c --- 2.2.12-final3/arch/i386/kernel/smp.c Tue Jul 13 00:33:20 1999 +++ 2.2.12-final3-endbase/arch/i386/kernel/smp.c Tue Aug 24 18:16:04 1999 @@ -657,13 +657,14 @@ return virt_to_phys(trampoline_base); } +extern unsigned long i386_endbase __initdata; /* * We are called very early to get the low memory for the * SMP bootup trampoline page. */ unsigned long __init smp_alloc_memory(unsigned long mem_base) { - if (virt_to_phys((void *)mem_base) >= 0x9F000) + if (mem_base + PAGE_SIZE > i386_endbase) panic("smp_alloc_memory: Insufficient low memory for kernel trampoline 0x%lx.", mem_base); trampoline_base = (void *)mem_base; return mem_base + PAGE_SIZE; diff -urN 2.2.12-final3/arch/i386/mm/init.c 2.2.12-final3-endbase/arch/i386/mm/init.c --- 2.2.12-final3/arch/i386/mm/init.c Sun Aug 22 15:51:43 1999 +++ 2.2.12-final3-endbase/arch/i386/mm/init.c Tue Aug 24 18:19:08 1999 @@ -384,6 +384,8 @@ printk(".\n"); } +extern unsigned long i386_endbase __initdata; + __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem)) { unsigned long start_low_mem = PAGE_SIZE; @@ -392,7 +394,6 @@ int datapages = 0; int initpages = 0; unsigned long tmp; - unsigned long endbase; end_mem &= PAGE_MASK; high_memory = (void *) end_mem; @@ -416,14 +417,7 @@ #endif start_mem = PAGE_ALIGN(start_mem); - /* - * IBM messed up *AGAIN* in their thinkpad: 0xA0000 -> 0x9F000. - * They seem to have done something stupid with the floppy - * controller as well.. - * The amount of available base memory is in WORD 40:13. - */ - endbase = PAGE_OFFSET + ((*(unsigned short *)__va(0x413) * 1024) & PAGE_MASK); - while (start_low_mem < endbase) { + while (start_low_mem < i386_endbase) { clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags); start_low_mem += PAGE_SIZE; } @@ -458,11 +452,12 @@ #endif free_page(tmp); } - printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", + printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved (endbase 0x%lx), %dk data, %dk init)\n", (unsigned long) nr_free_pages << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), codepages << (PAGE_SHIFT-10), reservedpages << (PAGE_SHIFT-10), + __pa(i386_endbase), datapages << (PAGE_SHIFT-10), initpages << (PAGE_SHIFT-10)); Andrea
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |