Skip to content

Incorrect PFN calculation from MemTest86 addresses (physical address is truncated instead of converted) #1

Description

@Maks33im

I found the reason why generated badmemorylist contains invalid PFNs.
The script takes the MemTest86 error address and does:
$pageAddr = "0x" + $fullAddr.Substring(0, 6)
This does not convert a physical address to a PFN. It only truncates the hexadecimal string.
Example:
MemTest86 log:
Address: 4A0BC000
Current script generates:

badmemorylist
0x4A0BC0

But Windows badmemorylist expects PFN (Page Frame Number), not a physical address.
The correct conversion is:
PFN = PhysicalAddress >> 12
because Windows pages are 4096 bytes.
Correct result:
0x4A0BC000 >> 12 = 0x4A0BC
not:
0x4A0BC0
The current conversion makes Windows interpret the address as:
0x4A0BC0 * 0x1000 = 0x4A0BC0000
which is about 18.5 GB physical address.
This explains why on a system with only 8 GB RAM the generated badmemorylist contains PFNs outside the installed memory range:

badmemorylist
0x4a0bc0
0x4a0bc1
0x4a0bc2
...

Those pages cannot exist on this system, so Windows ignores them.
Suggested fix:
Replace:

$fullAddr = $matches[1]
if ($fullAddr.Length -ge 6) {
    $pageAddr = "0x" + $fullAddr.Substring(0, 6)
    $null = $uniquePages.Add($pageAddr)
}

with:

$fullAddr = [Convert]::ToUInt64($matches[1],16)
$pfn = $fullAddr -shr 12
$pageAddr = "0x{0:X}" -f $pfn
$null = $uniquePages.Add($pageAddr)

Also it would be useful to validate that generated PFNs are within the detected physical RAM range before writing them to BCD.
Thanks.

Image

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions