Hi,
Some notes..
First, you should disable CPU caches so that you're actually testing memory (especially on older machines). Otherwise you can write a value and then read the same value from the cache (and not RAM), and think there's RAM where there isn't.
For older machines (80486 and older IIRC) there can be a problem with bus capacitance, where you write a value out to the system bus and read the same value back in when nothing is at that address. To solve this problem it's best to write to a dummy address in RAM between the write and the read.
Your code has a bug - if the computer has 4 MB or less, then it'll test for RAM at 0x00400000, decide there's none (hopefully) and then the second loop will start looking for RAM at 0x00000000. In this case it'd think the video display memory area (from 0x000A0000 to 0x000BFFFF is RAM when it's not, and then stop when it reaches the video ROM. Also, if the video ROM happens to contain the value 0xAA then it'll think that's a byte of RAM too.
For some computers there can be a memory hole from 15 MB to 16 MB (a reserved area for memory mapped ISA devices). If this hole is present and the computer has more than 16 MB of RAM your code will skip over the memory hole and think it's RAM when it's not.
If the computer has 15/16 MB of RAM and something (e.g. an old ISA SVGA card) mapped in the area from 15 MB to 16 MB, then your code will think that's an extra 1 MB of RAM. I guess you could provide warnings but be carefull with your wording - there's a difference between not supporting the cards (e.g. OS works but card doesn't) and not supporting any computer that contains these cards (e.g. OS crashes).
If you ever want to use ACPI then it'd be good if your OS didn't trash areas in RAM used by ACPI. It's impossible for manual probing to determine the difference between "system RAM" and "usable RAM".
If you ever want to support more than 4 GB of RAM (e.g. PAE and/or long mode) then your code won't detect anything above 4 GB, and due to the area below 4 GB that's reserved for BIOS, APICs and PCI you'll (hopefully) only be able to access 3 GB or 3.5 GB.
If there's memory mapped PCI devices after RAM then your code will probably think they're RAM too. For Intel machines PCI devices are normally mapped at the highest free 32-bit addresses, so your code will work (unless there's more than 3 GB or 3.5 GB of RAM). For AMD machines, AMD recommends that PCI devices are mapped just above the RAM to (see the note on page 478 of AMD's "
AMD64 Architecture Programmer's Manual: Volume 2: System Programming").
Lastly, code like this limits your OSs ability to run on non-standard equipment, and generally isn't "future-proof". Basically there's a set of (mostly unwritten) rules that define the "standard architecture", that OS programmers, hardware manufacturers and BIOS writers all follow to ensure things work. These rules include stupid stuff like the A20 gate, the default PIC configuration and "MSDOS compatable" FPU error handling, but they also include more useful things like the state of the CPU at power-on or reset, the default location of the real mode IVT, etc. One of these unwritten rules is that the BIOS/chipset can do anything it likes with any physical addresses, as long as it tells the OS what it did via. BIOS functions (and as long as it doesn't break DOS
).
Cheers,
Brendan