slow last 128MB of RAM in a 2GB system?

Dave Johnson dave-gnhlug at davej.org
Fri Apr 13 16:49:49 EDT 2007


Bill McGonigle writes:
> Into -h units:
> 
> 639K  - BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
> 1K    - BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
> 128K  - BIOS-e820: 00000000000e0000 - 0000000000100000 (reserved)
> 2014M - BIOS-e820: 0000000000100000 - 000000007dfd0000 (usable)
> 60K   - BIOS-e820: 000000007dfd0000 - 000000007dfdf000 (ACPI data)
> 132K  - BIOS-e820: 000000007dfdf000 - 000000007e000000 (ACPI NVS)
> 4K    - BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
> 8M    - BIOS-e820: 00000000ff780000 - 0000000100000000 (reserved)
> 
> 1919M - limit_regions endfor: 0000000000100000 - 0000000078000000  
> (usable)

0MB to 2016MB is basically RAM.

The remaining 32MB isn't listed in the e820 map.  It's likely the 32MB
is being reserved for the integrated graphics.

Now this will cause a challenge to the BIOS's MTRR logic.  It will
want to cover that entire 2016MB exactly with the MTRR registers.

The MTRR registers allow you to specify a base address and size, but
the size must be a power of two.

There are 2 basic ways BIOSs can do this:

1) It can list the cacheable memory using power of 2's.
   That would be: 1024+512+256+128+64+32.

reg00: base=0x00000000 (   0MB), size=1024MB: write-back, count=1
reg01: base=0x40000000 (1024MB), size= 512MB: write-back, count=1
reg02: base=0x60000000 (1536MB), size= 256MB: write-back, count=1
reg03: base=0x70000000 (1792MB), size= 128MB: write-back, count=1
reg04: base=0x78000000 (1920MB), size=  64MB: write-back, count=1
reg05: base=0x7C000000 (1984MB), size=  32MB: write-back, count=1

2) It can list all 2048MB as cachable, then work backwards for the
   uncachable part by doing:

reg00: base=0x00000000 (   0MB), size=2048MB: write-back, count=1
reg01: base=0x7e000000 (2016MB), size=  32MB: uncachable, count=1

Also, note it is customary to leave 1 or 2 MTRR registers available
for the OS to use.  On intel cpus, there are 6 MTRR registers so the
BIOS will tend to only use 4.

Your BIOS is using #1 above, prefering to list out each cachable part.

When you had 1GB of RAM, you needed 4 MTRR registers to fully express
992MB, but with 2GB you need 5 MTRR registers to fully express 2016MB.

Using #2 method is much more preferable for the case were some amount
of memory at the end of RAM is reserved.  With this you only need 2
MTRR registers no matter what the size of RAM.

You can easially fix this using /proc/mtrr.  Since the BIOS filled
out the first 4 entries in #1 above, you can simply add the 5th one
yourself.  You could also convert the table into #2 above, but unless
you plan to run Xorg you dont need any more MTRR registers.

Simply add this to a startup script and you should be all set:

echo "base=0x7c000000 size=0x2000000 type=write-back" >/proc/mtrr

After that the output should look exactly like #1 above.


> While I feel it should be the manufacturer's responsibility to get  
> this right, I think linux would be stronger for knowing how to deal  
> with as much buggy BIOS as is out there.  I'll run bug reports up the  
> flagpole as necessary if you can set me on the right track.

Good luck.

> aside: Is it just more or is this on the uptick? - I'm seeing 'buggy  
> BIOS' as the cause of so many problems recently.  I've been through  
> nasty problems with nVidia, ATI, and SiS BIOS bugs, all in the past  
> year, where I haven't worried much about it previously.  Intel  
> chipsets are, so far, batting 1000 recently.

Yes, my ASUS M2N-SLI shipped with a buggy BIOS where it wouldn't place
any memory over 4GB, limiting usable memory to 3.75GB.  Upgrading the
bios to the latest version fixed that, but broke ACPI.

-- 
Dave



More information about the gnhlug-discuss mailing list