installation steps:
1. patching
cd /usr/src/linux/arch/i386/kernel
patch < mem-2.0.xx.patch
2. re-compile your kernel
3. edit lilo, remove "mem=xxx[MmKk]"
3. run lilo and reboot your box
patches:
-------------------8<-----mem-2.0.32.patch-----------8<-------------------
diff -c -r -N setup.c.orig setup.c
*** setup.c.orig Sat Jul 18 21:54:40 1998
--- setup.c Sun Jul 19 16:34:02 1998
***************
*** 32,37 ****
--- 32,38 ----
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/smp.h>
+ #include <asm/pgtable.h>
/*
* Tell us the machine setup..
***************
*** 76,87 ****
extern int root_mountflags;
extern int _etext, _edata, _end;
extern char empty_zero_page[PAGE_SIZE];
/*
* This is set up by the setup-routine at boot-time
*/
! #define PARAM empty_zero_page
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#ifdef CONFIG_APM
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
--- 77,90 ----
extern int root_mountflags;
extern int _etext, _edata, _end;
+ #if 0
extern char empty_zero_page[PAGE_SIZE];
+ #endif
/*
* This is set up by the setup-routine at boot-time
*/
! #define PARAM ((char *)empty_zero_page)
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#ifdef CONFIG_APM
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
***************
*** 109,117 ****
void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
! unsigned long memory_start, memory_end;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
! int len = 0;
static unsigned char smptrap=0;
if(smptrap==1)
--- 112,120 ----
void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
! unsigned long memory_start, memory_end, cfg;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
! int len = 0, page_ok;
static unsigned char smptrap=0;
if(smptrap==1)
***************
*** 128,133 ****
--- 131,182 ----
#endif
aux_device_present = AUX_DEVICE_INFO;
memory_end = (1<<20) + (EXT_MEM_K<<10);
+ if (EXT_MEM_K >= 63 * 1024) {
+ printk("BIOS report extended memory %d\n", EXT_MEM_K);
+ /* 63MB extended memory (totally 64MB memory) is the largest
+ * amount that BIOS can currently report. Probe real amount
+ * of memory when BIOS report us there is totally 64MB memory
+ */
+ /* store PTE0, linux kernel store all 0's in PTE0 to
+ * catch NULL references */
+ cfg = pg0[0];
+ page_ok = 1;
+ do {
+ /* mmap address 0 to where we will test */
+ pg0[0] = (memory_end |
+ _PAGE_PRESENT |
+ _PAGE_RW |
+ _PAGE_PCD); /* uncachable */
+ local_flush_tlb(); /* invalidate local TLB */
+
+ /* test for alternating 1's and 0's */
+ *((volatile unsigned long *)0) = 0xaaaaaaaa;
+ if (*((volatile unsigned long *)0) != 0xaaaaaaaa)
+ page_ok = 0;
+
+ /* test for alternating 0's and 1's */
+ *((volatile unsigned long *)0) = 0x55555555;
+ if (*((volatile unsigned long *)0) != 0x55555555)
+ page_ok = 0;
+
+ /* test for all 1's */
+ *((volatile unsigned long *)0) = 0xffffffff;
+ if (*((volatile unsigned long *)0) != 0xffffffff)
+ page_ok = 0;
+
+ /* test for all 0's */
+ *((volatile unsigned long *)0) = 0x00000000;
+ if (*((volatile unsigned long *)0) != 0x00000000)
+ page_ok = 0;
+
+ if (page_ok)
+ memory_end += PAGE_SIZE;
+ } while (page_ok);
+
+ /* restore PTE0 */
+ pg0[0] = cfg;
+ local_flush_tlb(); /* invalidate local TLB */
+ }
memory_end &= PAGE_MASK;
#ifdef CONFIG_BLK_DEV_RAM
rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-------------------8<-----mem-2.0.32.patch-----------8<-------------------
-------------------8<-----mem-2.0.34.patch-----------8<-------------------
diff -c -r -N setup.c.orig setup.c
*** setup.c.orig Sat Jul 18 17:40:35 1998
--- setup.c Sun Jul 19 16:08:16 1998
***************
*** 32,37 ****
--- 32,38 ----
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/smp.h>
+ #include <asm/pgtable.h>
/*
* Tell us the machine setup..
***************
*** 81,92 ****
extern int root_mountflags;
extern int _etext, _edata, _end;
extern char empty_zero_page[PAGE_SIZE];
/*
* This is set up by the setup-routine at boot-time
*/
! #define PARAM empty_zero_page
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#ifdef CONFIG_APM
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
--- 82,95 ----
extern int root_mountflags;
extern int _etext, _edata, _end;
+ #if 0
extern char empty_zero_page[PAGE_SIZE];
+ #endif
/*
* This is set up by the setup-routine at boot-time
*/
! #define PARAM ((char *)empty_zero_page)
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
#ifdef CONFIG_APM
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
***************
*** 114,122 ****
void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
! unsigned long memory_start, memory_end;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
! int len = 0;
static unsigned char smptrap=0;
if(smptrap==1)
--- 117,125 ----
void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p)
{
! unsigned long memory_start, memory_end, cfg;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
! int len = 0, page_ok;
static unsigned char smptrap=0;
if(smptrap==1)
***************
*** 133,138 ****
--- 136,187 ----
#endif
aux_device_present = AUX_DEVICE_INFO;
memory_end = (1<<20) + (EXT_MEM_K<<10);
+ if (EXT_MEM_K >= 63 * 1024) {
+ printk("BIOS report extened memory %d\n", EXT_MEM_K);
+ /* 63MB extended memory (totally 64MB memory) is the largest
+ * amount that BIOS can currently report. Probe real amount
+ * of memory when BIOS report us there is totally 64MB memory
+ */
+ /* store PTE0, linux kernel store all 0's in PTE0 to
+ * catch NULL references */
+ cfg = pg0[0];
+ page_ok = 1;
+ do {
+ /* mmap address 0 to where we will test */
+ pg0[0] = (memory_end |
+ _PAGE_PRESENT |
+ _PAGE_RW |
+ _PAGE_PCD); /* uncachable */
+ local_flush_tlb(); /* invalidate local TLB */
+
+ /* test for alternating 1's and 0's */
+ *((volatile unsigned long *)0) = 0xaaaaaaaa;
+ if (*((volatile unsigned long *)0) != 0xaaaaaaaa)
+ page_ok = 0;
+
+ /* test for alternating 0's and 1's */
+ *((volatile unsigned long *)0) = 0x55555555;
+ if (*((volatile unsigned long *)0) != 0x55555555)
+ page_ok = 0;
+
+ /* test for all 1's */
+ *((volatile unsigned long *)0) = 0xffffffff;
+ if (*((volatile unsigned long *)0) != 0xffffffff)
+ page_ok = 0;
+
+ /* test for all 0's */
+ *((volatile unsigned long *)0) = 0x00000000;
+ if (*((volatile unsigned long *)0) != 0x00000000)
+ page_ok = 0;
+
+ /* if this page is available, try the next one */
+ if (page_ok)
+ memory_end += PAGE_SIZE;
+ } while (page_ok);
+ /* restore PTE0 */
+ pg0[0] = cfg;
+ local_flush_tlb(); /* invalidate local TLB */
+ }
memory_end &= PAGE_MASK;
#ifdef CONFIG_BLK_DEV_RAM
rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
-------------------8<-----mem-2.0.34.patch-----------8<-------------------
If your kernel is not 2.0.32 or 2.0.34, you can modify
arch/kernel/setup.c manually by the following steps.
1. add '#include <asm/pgtable.h>'
2. comment out the line 'extern char empty_zero_page[PAGE_SIZE];'
3. re-define PARAM to '((char *)empty_zero_page)'
4. in function setup_arch(), add declarations of cfg(unsigned long)
and page_ok(int)
5. still in function setup_arch() find two line likes this
'memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= PAGE_MASK;', now insert the following codes between
the two lines
if (EXT_MEM_K >= 63 * 1024) {
printk("BIOS report extened memory %d\n", EXT_MEM_K);
/* 63MB extended memory (totally 64MB memory) is the largest
* amount that BIOS can currently report. Probe real amount
* of memory when BIOS report us there is totally 64MB memory
*/
/* store PTE0, linux kernel store all 0's in PTE0 to
* catch NULL references */
cfg = pg0[0];
page_ok = 1;
do {
/* mmap address 0 to where we will test */
pg0[0] = (memory_end |
_PAGE_PRESENT |
_PAGE_RW |
_PAGE_PCD); /* uncachable */
local_flush_tlb(); /* invalidate local TLB */
/* test for alternating 1's and 0's */
*((volatile unsigned long *)0) = 0xaaaaaaaa;
if (*((volatile unsigned long *)0) != 0xaaaaaaaa)
page_ok = 0;
/* test for alternating 0's and 1's */
*((volatile unsigned long *)0) = 0x55555555;
if (*((volatile unsigned long *)0) != 0x55555555)
page_ok = 0;
/* test for all 1's */
*((volatile unsigned long *)0) = 0xffffffff;
if (*((volatile unsigned long *)0) != 0xffffffff)
page_ok = 0;
/* test for all 0's */
*((volatile unsigned long *)0) = 0x00000000;
if (*((volatile unsigned long *)0) != 0x00000000)
page_ok = 0;
/* if this page is available, try the next one */
if (page_ok)
memory_end += PAGE_SIZE;
} while (page_ok);
/* restore PTE0 */
pg0[0] = cfg;
local_flush_tlb(); /* invalidate local TLB */
}
Codes for automatical probing memory size is inspired by booting codes
of FreeBSD. Wish you can enjoy it.
I have test it on two machines, one is PentiumIIx2/128MB/6GB, the other
is PentiumIIx2/196MB/6GB, it works. I want to know whether it works on
other machine ( 386, 486, Pentium, PentiumPro, especially 386 boxes). If
you encounter some problem, please contract me at para@cs.sebuaa.ac.cn.
More strict way to describe physical memory is using set of <base,size>
pairs. Instead Linux use a single <memory_start, memory_end>. It may
crash system on some motherboard and BIOS. But, fortunately, most system
apply to the Linux' way, it works very well.
Michael Liao
1998/7/19
______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com
-
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.altern.org/andrebalsa/doc/lkml-faq.html