RE: Perform minimal RAM test at boot

Richard B. Johnson (root@chaos.analogic.com)
Mon, 1 Nov 1999 16:45:54 -0500 (EST)


On Mon, 1 Nov 1999 nathan.zook@amd.com wrote:

> Two things. First, you don't want to detect memory this way. I'm told some
> systems crash if you address memory which is not present. Note also that
> the only way to test for memory's presence is to write to it & try to read
> back. This destroys any data which might have been put there by the
> bios.........
>
[SNIPPED]

There is no 'bus error' on any ix86 machines. Reading nonexistant memory
will not hurt anything. Once in protected mode, all ix86 machines can
access memory as 'pages'. There will never be a partial page. A page
in ix86-land is 0x1000 bytes. Since the bad BIOSes are in ix86 machines,
a memory-check that is ix86-specific can be readily made.

To find the memory limit, you need to set a data selector to map
1:1 physical memory. Then, with the interrupts disabled, save the
last longword in each page into a register. Invert it, then write
it back. Exercise the bus by pushing, then poping any register, then
read the longword. If it is what you wrote, memory exists. Put the
original longword back, then go to the next page. You do this until
the test fails. The memory is thus determined. This will work even if you
end up modifying your own code because what you execute has already been
prefetched. To assure success, with modifying code, you need to do the
modification at a 2-byte boundary which keeps you off the end of a cache-
line, i.e.:

This is Intel syntax
dest <-- source

push ds ; Save segment
mov ds, _linear_selector
xor ebx, ebx ; Start with zero
chkm: mov eax [ebx] ; Get memory DWORD
mov ecx, eax ; Save
not eax ; Invert
nop
align 2 ; Get off DWORD boundary
not [ebx] ; Invert memory byte
push eax ; Exercise the bus
pop eax
cmp eax, [ebx] ; See if it took
mov [ebx], ecx ; Put original back
jz end_of_mem ; No memory here
add ebx,1000h ; Ready next page
jmp short chkm

end_of_mem:
pop ds ; Restore segment
; EBX = 1000h past last good memory

This code is "swiped" from something working that I did for one of
our scanners which has no BIOS, etc. With Linux, you can assume that
your code (which is executing) must be in RAM, therefore you can
start above your code if you don't like the idea of modifying your
own instruction-stream. But, if the code is written as shown, by
the time the cache is refetched (because of the detected write), it
will have been changed back to the original.

This takes only 2-3 seconds to execute on a 128 megabyte 400 MHz machine.

Cheers,
Dick Johnson

Penguin : Linux version 2.3.13 on an i686 machine (400.59 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.

-
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/