memory probing such a difficult thing?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
JJeronimo
Member
Member
Posts: 202
Joined: Wed Oct 18, 2006 3:29 pm

memory probing such a difficult thing?

Post by JJeronimo »

In spite good-thinking-peoples's worst wishes, I decided to probe memory directly... It works perfecty! Else, it worked perfectly when I had coded something similar in ASM some weeks ago...

Note that the code that executes it is a boot loader and is loaded below 1M... and... it assumes that there are 640KB of usable memory below 1MB and that there *is* some memory available above 1MB (at least 1 byte!)...
It will have unpredictable results is this two conditions are not guaranteed (like overwriting BIOS code or so)...
I've not explicitly disabled interrupts, however: (1) in my case the function will really *assume* they are disabled, (2) I don't see how correclty setup interrupts could affect this... If they aren't correctly setup the code would triple fault, anyway!

Anyway, can someone do a simple evaluation about my code, please? Memory allocation is still a sensible area for me and I don't risk relying very much on my own skills! And... it was very easy for my taste!

JJ



Code: Select all

void* probe_memory (void)
{
	register unsigned char* memptr;

	for( memptr = (char*) (4 * 1024 * 1024); 	//We start at 4MB
		*memptr = 0x55, *memptr = ~*memptr, *memptr == 0xAA;
		memptr += 4 * 1024 * 1024 )					//Using a granularity of 4MB...
		;			//The loop is empty...

	for(	;
		*memptr = 0x55, *memptr = ~*memptr, *memptr != 0xAA	;
		memptr-- )
		;			//The loop is empty... remember?!

	return (void*) memptr;
}
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

From the FAQ: How do I determine the amount of RAM?:
WE DISCOURAGE YOU FROM DIRECTLY PROBING MEMORY

Use BIOS to get a memory map, or use GRUB.

When perfectly implemented, directly probing memory may allow you to detect the amount of memory even on systems where the BIOS fails to provide the appropriate support (or without even worrying about whether your BIOS can do it or not). Depending on how its coded, may or may not take into account holes in system memory (15/16mb mark ala OS/2) or memory mapped devices like frame buffering SVGA cards, etc.

However, your BIOS knows things you ignore about your motherboard and PCI devices. Probing memory-mapped PCI devices may have unpredictable results and possibly damage your system, so once again we discourage its use.
Every good solution is obvious once you've found it.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: memory probing such a difficult thing?

Post by Brendan »

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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply