diff -urN linux-2.2.10/Documentation/memory.txt linux-2.2.10.SuSE/Documentation/memory.txt --- linux-2.2.10/Documentation/memory.txt Tue Dec 22 17:31:07 1998 +++ linux-2.2.10.SuSE/Documentation/memory.txt Sun Jul 4 14:32:23 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 linux-2.2.10/arch/i386/kernel/setup.c linux-2.2.10.SuSE/arch/i386/kernel/setup.c --- linux-2.2.10/arch/i386/kernel/setup.c Tue Jun 8 19:43:21 1999 +++ linux-2.2.10.SuSE/arch/i386/kernel/setup.c Sun Jul 4 14:35:00 1999 @@ -119,6 +119,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; @@ -248,6 +250,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)) @@ -255,6 +258,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(); @@ -323,6 +327,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; @@ -332,6 +343,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 linux-2.2.10/arch/i386/kernel/smp.c linux-2.2.10.SuSE/arch/i386/kernel/smp.c --- linux-2.2.10/arch/i386/kernel/smp.c Wed Jun 2 20:29:27 1999 +++ linux-2.2.10.SuSE/arch/i386/kernel/smp.c Sun Jul 4 14:32:23 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 linux-2.2.10/arch/i386/mm/init.c linux-2.2.10.SuSE/arch/i386/mm/init.c --- linux-2.2.10/arch/i386/mm/init.c Thu Jan 21 20:28:40 1999 +++ linux-2.2.10.SuSE/arch/i386/mm/init.c Sun Jul 4 14:32:23 1999 @@ -382,6 +382,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; @@ -413,12 +415,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.. - */ - while (start_low_mem < 0x9f000+PAGE_OFFSET) { + while (start_low_mem < i386_endbase) { clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags); start_low_mem += PAGE_SIZE; } @@ -453,11 +450,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));