			===================
			= MemTest-86 v1.3 =
			===================

Introduction
============
Memtest86 is thorough, stand alone memory test for 386, 486 and Pentium
systems.  Memtest86 uses a "moving inversions" algorithm that is proven
to be effective in finding memory errors.  The BIOS based memory test is
just a quick check that will often miss many of the failures that are
detected by Memtest86.


Enhancements in v1.3
====================

1) Scrolling of memory errors is now provided.  Previously only one screen
   of error information was displayed.

2) Memtest86 can now be booted from any disk via lilo.

3) Testing of up to 4gb of memory has been fixed is now enabled by default.
   This capability was clearly broken in v1.2a and should work correctly
   now but has not been fully tested (4gb PC's are a bit rare).

4) The maximum memory size supported by the motherboard is now being
   calculated correctly.  In previous versions there were cases where all
   of memory would not be tested and the maximum memory size supported
   was incorrect.

5) For some types of failures the good and bad values were reported to be
   same with an Xor value of 0.  This has been fixed by retaining the
   initial data read from memory and not re-reading the bad data in the
   error reporting routine.

6) Advanced power management (APM) is now disabled by Memtest86.  This
   keeps the screen from blanking while the test is running.

7) Problems with enabling & disabling cache on some motherboards has been
   corrected.


Installation
============
Memtest86 is a stand alone program and can be loaded from either a disk
partition or a floppy disk.

Building Memtest86:
   1) Edit the Makefile and adjust options as needed.
   2) Type "make"

This creates a file named "image" which is a boot-able image.  This image
file may be copied to a floppy disk or lilo may be used to boot this image
from a hard disk partition.

Creating a Memtest86 boot-disk
   1) Insert a blank write enabled floppy disk.
   2) As root, Type "make install"

Booting from a disk partition via lilo (assuming you are using lilo and
already have a lilo config file)
   1) Copy the image file to a permanent location (ie. /memtest86).
   2) Add an entry in the lilo config file (usually /etc/lilo.conf) to boot
      Memtest86.  Only the image and label fields need to be specified. 
      The following is a sample lilo entry for booting Memtest86:

	image = /memtest86
	label = memt

   3) As root,  type "lilo"

If you encounter build problems a binary image has been included (image.bin).
This pre-compiled image may be used with lilo or to create a boot-disk with
this image do the following:
   1) Insert a blank write enabled floppy disk.
   2) Type "make install-bin"


Problems
========
Memtest86 has not been designed for or tested with parity checking enabled
or error correcting (ECC) memory.  With parity checking enabled the test
should execute without problem, but will most likely die with an
unexpected exception when an error is detected.  With ECC memory the test
will not be able to detect single bit errors but the should otherwise execute
correctly.  Support for parity and ecc memory is planned for a future release.

There have been a number of compatibility problems reported.  Most of
these problems have been identified and corrected, but it is likely that
there are still some incompatibilities.  Please report problems.

It has been reported that with some motherboards Memtest86 fails when
shadow memory is enabled.  The cause for this failure is not yet
understood.  If you encounter large numbers of errors on an otherwise
working system try disabling shadow memory. 

Incompatibilities have been encountered with various versions of bintools.
Building Memtest86 has been tested with the slackware 3.1 and 3.2 releases
(bintools 2.6.0.14 and 2.7.0.9). 


Functional Description
======================
Bootstrap and setup code (robbed shamelessly from the Linux kernel) is used
to load Memtest86 from the floppy disk, setup memory management registers
and do miscellaneous setup.  When the load and setup are complete the
memory map is as follows.

0x000	|-----------------------------------------------|
	|	Stack (4k)				|
0x1000	|-----------------------------------------------|
	|	Memtest-text (5.5k) Origin  0x1000	|
0x2600	-------------------------------------------------
	|	Memtest-data (.5k)  Origin  0x2600	|
0x2800	-------------------------------------------------
	|	Memtest-text (5.5k) Origin  0x102800	|
0x3e00	-------------------------------------------------
	|	Memtest-data (.5k)  Origin  0x103e00	|
0x4000	-------------------------------------------------
	|	Common variables (1k)			|
0x4400	-------------------------------------------------

Relocation of the test is accomplished by using two copies of the test
code that have been built to execute at different addresses (different
origins).  When the test is started, the code with an origin of 0x1000 is
executed.  At the end of the testing phase the code from 0x1000 to 0x4400
is copied to 0x101000, the stack is set to 0x101000 and then we jump to
address 0x102800 (the code with an origin of 0x1002800).  When the code is
relocated only the first 640k of memory is tested.  When this test is
complete then the code is moved back to 0x1000, the stack is set back to
0x1000 and then we jump to 0x1000 (the code with an origin of 0x1000).
	
When Memtest86 is loaded into memory it first scans memory to find all
segments of available read/write memory (DRAM).  DRAM is identified by
reading a location and then writing its complement.  If any bits change
then we assume that it is DRAM.  To save time we only do this check every
512 bytes.  All memory from 0xa0000 to 0xf0000 is skipped.  Each segment of
memory is displayed on the left side of the screen.  All segments of memory
that are found will be tested regardless of size.  The memory scan is limited
to the maximum memory size supported by the motherboard.

After the memory segments have been identified the actual testing begins.
Since the memory chips currently used in PC's are either one or four bits
wide (ie. 1x1meg, 4x1meg, 1x4meg or 4x4meg) a four bit wide test patterns
replicated to fill a 32 bit word are used.  If memory chips become available
in PC's that are wider than four bits then this pattern should be adjusted.
A moving inversions algorithm is then used to test all of memory.  Every
pass through memory is done sequentially through each memory segment.  This
must be done to preserve the integrity of the moving inversions algorithm. 

A provision to disable L1, L2 caches was added in release 1.1.  With this
enhancement cache is on for even numbered passes and off for odd passes.
The test algorithms used by Memtest86 are able to do fairly effective
testing of memory with cache on.  However, in some instances testing with
cache off may be more effective.  In addition the test algorithms will not
work correctly on systems with write-back cache when cache is enabled.  The
down side is that execution time is much, much longer when cache is off.
This feature may be disabled by commenting out the "CACHE=-DCACHE" line in
the Makefile.

Memtest86 has the ability to test memory using longer refresh rates.  This
makes is possible to detect marginal errors that otherwise would go
undetected with the normal refresh rate.  Two refresh rates are used, the
normal of 15ms and an extended refresh rate of 150ms.  The test alternates
between normal and extended refresh every two passes.  This allows for
testing with cache both on and off before switching refresh rates.  This
feature may be disabled by commenting out the "REFRESH=-DREFRESH" line in
the Makefile.  If this feature is disabled the refresh rate set by the BIOS
will be used.


Display Description
===================
The following is a description of each field displayed by Memtest86:

Testing:	A list of all DRAM segments that have been found and will
		be tested.

Max_Mem:	Maximum memory size supported by the motherboard.

Pattern:	The current 32 bit data pattern used for testing

Refresh:	The current refresh rate  ("Default" indicates that the
		refresh rate has not been altered)

Pass:		Pass count.  (A complete checkout with/without cache and
		extended refresh requires four passes)

Errors:		Total errors.

Cache:		Cache status for both L1 and L2 cache.

The "windmill" turns 9 times per pattern. There are 10 patterns per
pass: 8, 7, 4, B, 2, D, 1, E, 0, F, each filling a 32 bit word.

The following information is displayed when a memory error is detected.
An error message is only displayed for errors with a different address or
failing bit pattern.  All displayed values are hexadecimal.

Addrs:		Failing memory address 
Good:		Current data pattern 
Bad:		Failing data pattern 
Xor:		Exclusive or of good and bad data (this shows the position
		of the failing bit(s))


Troubleshooting Memory Errors
=============================
Once a memory error has been detected, determining the failing SIMM is not
a clear cut procedure.  With the large number of motherboard vendors and
possible combinations of SIMM slots it would be difficult if not impossible
to assemble complete information about how a particular error would map
to a failing SIMM.  However, there are steps that may be taken to find
the failing SIMM.  Here are three techniques that may be helpful:

1) Removing SIMMs
This is simplest method for isolating a failing SIMM, but may only be
employed when one or more SIMM can be removed from the system without
making it unusable.  By selectively removing SIMMs from the system and
then running the test you will be able to find the bad SIMM.  Be sure to
note exactly which SIMMs are in the system when the test passes and when
the test fails.

2) Rotating SIMMs
When none of the SIMMs can be removed then you may wish to rotate SIMMs
to find the failing one.  This technique can only be used if there are
4 or more SIMMs in the system.  Change the location of two SIMMs at a time.
For example put the SIMM from slot 1 into slot 2 and put the SIMM from slot
2 in slot 1.  Run the test and if either the failing bit or address changes
then you know that the failing SIMM is one of the ones just moved. 
By using several combinations of SIMM movement you should be able to
determine which SIMM is failing.

3) Replacing SIMMs
If you are unable to use either of the previous techniques then you are
left to selective replacement of SIMMs to find the failure.  Not useful if
you don't have any replacement SIMMs.


Acknowledgments
===============
The initial versions of the source files bootsect.S, setup.S, head.S and
build.c are from the Linux 1.2.1 kernel and have been heavily modified. 

Thanks to the many users who have reported problems and especially those
who submitted corrective code.

--
Chris Brady
E-mail cbrady@cray.com
