Page 2 of 2

Posted: Tue Jul 31, 2007 10:29 am
by Brendan
Hi,
Brynet-Inc wrote:I know OpenBSD uses int 15, AX=E820 first, then int 15, AX=E801.. (Or it did? E801 is #if 0'd out apparently..)

After if those two methods fail, it attempts int 15, AX=8800 which has a 64MB barrier..

If "all" of this fails, It seems to have "two" methods of probing memory.. View Source Here.

Memory can also be "manually added" via the boot console as well..
Hehe...

Tell me if this code does what you'd expect:

Code: Select all

        /* Check for 94 or later bios */
        info = (void *)0xFFFFB;
        if (info[0] == '9' && info[1] <= '3')
                return NULL;
I'm guessing they didn't test that on computers with BIOSs made during or before 1989... ;)

They only have one way of probing memory, but their memory probing code is split into 2 parts - one function to test for RAM at a specific address, and another function to test a range of addresses (by calling the first function).

The function to test for RAM at a specific address doesn't even flush caches between writing and reading (they write to the cache then check if the value is still in the cache, all without accessing RAM). This should actually work for newer computers with MTRRs (which probably support the BIOS functions anyway), but won't work on older computers unless the memory controller is "friendly".

The function to test a range of addresses will (hopefully) stop at the first non-RAM address, so if you've got a computer with 256 MB of RAM with an ISA memory hole then it'll only detect 15 MB of RAM (unless there's an ISA video card in this area, in which case it'll think the video display memory is usable RAM).

Their "checkA20()" also may not work on some computers due to caching. AFAIK the caches in newer CPUs are aware of A20, but older CPUs and computers with external caches aren't. Not that this matters much - they don't check A20 until *after* they've done manual probing ("Yay, my 8 MB computer has 9 MB now!"), so A20 had better be enabled.... ;)

I'm not sure how many other bugs there are in this (short) piece of code - I only spent 5 minutes or so looking.


Cheers,

Brendan

Posted: Tue Jul 31, 2007 11:39 am
by exkor
To make manual probing safer one may exclude memory mapped io by reading pci conf space (thats easy) and may need chipset database (thats not) for devices that are not PCI devices (such as Local APIC which may not be pci and doesn't have fixed address).
So i'd say first thing to do is to detect all possible hardware(which will be done anyway) if manual probing is used.

Posted: Tue Jul 31, 2007 1:35 pm
by Brendan
Hi,
inflater wrote:I think AX=E820 with INT 15h should work. I use it borrowed from DexOS, and it works in Bochs, QEMU, MS VPC, VMware Workstation, and my development computer and the testbed (testbed is a pentium-s 120 MHz, 40 MB RAM, and dev PC is pentium 4 1.8 GHz, 256 MB RAM). :) Note that detecting memory from CMOS may return strange results if the memory is above 64 MB RAM. So I wouldn't use this. And INT 12h, that's almost 0x280 - 640 kB, except if some MBR protector program, viruses or something other (if running under DOS) is present in RAM. Or you may get a lower value too :), do you have the original IBM PC from 1981 or PCjr in your house somewhere? :)
I support 80486 and later computers, but "Int 0x15, EAX=0xE820" doesn't work on any 80486 I've tried and may not work on some Pentiums.

I work from the oldest method to the newest method, testing each time I add a newer method. For example, I'd start with manual probing, then test, then add CMOS locations, then test, then add "Int 0x15, ah = 0x88", then test, etc. AFAIK each method I use either works correctly or isn't present, for all computers I have here.
exkor wrote:To make manual probing safer one may exclude memory mapped io by reading pci conf space (thats easy) and may need chipset database (thats not) for devices that are not PCI devices (such as Local APIC which may not be pci and doesn't have fixed address).
So i'd say first thing to do is to detect all possible hardware(which will be done anyway) if manual probing is used.
Except for computers with 3 GB or more RAM and newer AMD systems (with hyper-transport), there's normally a gap between the top of RAM and the first memory mapped PCI device. This means that if the computer is too old to support newer BIOS functions then I shouldn't need to worry about PCI devices, etc. I do have to worry about memory mapped ISA devices though - my manual probing skips 1 MB from 0x00F00000 to 0x01000000 to avoid that. It also stops at 512 MB just in case (I'm guessing any computer with 512 MB of RAM will have at least one of the BIOS functions that returns RAM above 64 MB).

If the OS doesn't get any information from the BIOS at all or if it only gets information from CMOS locations, and if the computer has more than 15 MB of RAM, and if the ISA hole isn't present, then the OS will end up using 1 MB less RAM than it could because it avoids the ISA hole when it doesn't really need to.


Cheers,

Brendan

Posted: Tue Jul 31, 2007 4:17 pm
by jnc100
And to further complicate matters the Compaq Contura does allow more than 16MB to be installed but from the article I guess it doesn't support e820 or any other standard method. A quick search of the latest linux 2.6 reveals no hits for 'e802' apart from networking ones (ieee80211). And as we have no idea as to what format e802 returns, I guess we're a bit stuck without a machine. Emails to compaq (or is it hp now?) anyone?

Regards,
John.