Page 1 of 2
Is this memory map sane?
Posted: Tue Apr 26, 2016 2:47 am
by moondeck
Hi
i am doing memory detection with GRUB.
I am wondering if this memory map is sane, as the numbers look strange
Code here:
Code: Select all
mmap = mbd->mmap_addr;
while(mmap < mbd->mmap_addr + mbd->mmap_length) {
ltoa(mmap->base_addr_low,memorybase,10);
ltoa(mmap->length_low,memorylenght,10);
ltoa(mmap->type,memorytype,10);
kout_mem(memorybase," | ",memorylenght,memorytype);
mmap = (memory_map_t*) ( (unsigned int)mmap + mmap->size + sizeof(unsigned int) );
}
and the image here:
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 3:39 am
by Octocontrabass
Code: Select all
00000000 00000000 | 00000000 0009FC00 | 1
00000000 0009FC00 | 00000000 00000400 | 2
00000000 000F0000 | 00000000 00010000 | 2
00000000 00100000 | 00000000 07EE0000 | 1
00000000 07FE0000 | 00000000 00020000 | 2
00000000 FFFC0000 | 00000000 00040000 | 2
It looks strange because there's no space between the length and the type. When I add that space (and convert the numbers to hexadecimal to make it easier for me to read), the memory map looks fine.
Don't forget, the base address and length are 64-bit values. Your OS will fail on real hardware if you don't handle it correctly.
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 4:22 am
by sleephacker
I think it's better to always print addresses (and most other things as well) in hexadecimal format because it's much easier to understand.
For example it makes it way easier to see if something is page aligned (just check the last 3 digits) or below 1 MiB (0x00100000) or any memory barrier for that matter.
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 4:28 am
by moondeck
I think i've got it, what do you think? Now, how do i find out what is mapped where?
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 4:53 am
by sleephacker
Now, how do i find out what is mapped where?
The memory map doesn't tell you that, it only tells you which areas are reserved and which are free to use.
To find out which devices are mapped where you'd have to do a PCI scan and check all the BARs.
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 7:27 am
by deleted
Hey there!
Have you made sure that the flag for memory mapping is set? If not, then the multiboot spec says not to trust any values.
I just implemented memory-mapping last night, so correct me if I am wrong, but this is how I detect the size of memory:
Code: Select all
if(CHECK_FLAG(multiboot->flags, 0)){
kprintf("Lower Memory: %dMB (or less than 1 MB)\n", multiboot->memoryLower / 1000, multiboot->memoryLower / 100);
kprintf("Upper Memory: %dMB (or less than 1 MB)\n", multiboot->memoryUpper / 1000);
kprintf("Total Memory: %dMB (or less than 1 MB)\n", (multiboot->memoryUpper + multiboot->memoryLower) / 1000);
}else{
kprintf("Bit 0 of multiboot->flags is unset. Not trusting memory map values.\n");
}
Where
multiboot is a
multiboot_info_t* structure, passed by pushing ebx.
You can then do what you are doing to conduct/read memory map, but make sure that bit 6 of multiboot->flags is set. Otherwise you can't trust any values
Source:
http://www.gnu.org/software/grub/manual ... rnel_002ec
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 10:24 am
by Brendan
Hi,
wxwsk8er wrote:I just implemented memory-mapping last night, so correct me if I am wrong, but this is how I detect the size of memory:
Code: Select all
if(CHECK_FLAG(multiboot->flags, 0)){
kprintf("Lower Memory: %dMB (or less than 1 MB)\n", multiboot->memoryLower / 1000, multiboot->memoryLower / 100);
kprintf("Upper Memory: %dMB (or less than 1 MB)\n", multiboot->memoryUpper / 1000);
kprintf("Total Memory: %dMB (or less than 1 MB)\n", (multiboot->memoryUpper + multiboot->memoryLower) / 1000);
}else{
kprintf("Bit 0 of multiboot->flags is unset. Not trusting memory map values.\n");
}
That's wrong!
There are 2 different pieces of "memory" information. The first piece is the "memoryLower" and "memoryUpper" fields. On modern hardware, these fields are mostly just a worthless joke that can't work properly and shouldn't be used. The problem is that you can have multiple areas of RAM above 0x00100000 and it can only report one of them as "upper memory". The other problem is that they don't tell you anything useful (like which areas are safe for the OS to use for memory mapped PCI devices, which areas need special attention for ACPI to work, etc).
The second piece of "memory" information is the memory map, which gives you a list of "address, length, type" entries that describe the physical address space (excluding areas used by devices). This is the only usable option on modern hardware.
The flag you're talking about determines if the memory map is present (and has nothing to do with the "memoryLower" and "memoryUpper" fields). If this flag says that there's no memory map, then you can assume the computer is ancient (e.g. an 80486 or older that doesn't support the "int 0x15, eax=0xE820" BIOS function), and you can either use the "memoryLower" and "memoryUpper" fields as a fall-back or refuse to boot.
Cheers,
Brendan
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 10:42 am
by deleted
Brendan wrote:Snip
Hello,
That makes more sense. I was wondering about that, thanks for clearing it up. So the proper way would be to use the memory map and calculate the amount of available memory using the entries?
Cheers,
Walt
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 11:37 am
by Brendan
Hi,
wxwsk8er wrote:That makes more sense. I was wondering about that, thanks for clearing it up. So the proper way would be to use the memory map and calculate the amount of available memory using the entries?
Yes - depending on how you define "available memory", it'd be something roughly similar to a "for each entry { if (entry.type == usable_RAM) total += entry.length; }" loop.
Cheers,
Brendan
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 12:04 pm
by deleted
Brendan wrote:Snip
Okay awesome
I'd say that total memory would be the amount of undamaged memory installed (even if it is unavailable to the OS)
I'd say usable memory would be memory that is installed and available to the OS.
Thanks for the clarification! I've been reading and trying to grasp some memory-management concepts, so the explanations are great
Re: Is this memory map sane?
Posted: Tue Apr 26, 2016 12:17 pm
by Brendan
Hi,
wxwsk8er wrote:I'd say that total memory would be the amount of undamaged memory installed (even if it is unavailable to the OS)
In that case, you can't really determine total memory from the memory map alone (because you can't know which "reserved by firmware" areas are actually RAM) and would probably need to use
system management BIOS tables to get the total memory installed (and then subtract any "faulty" RAM reported by the memory map).
wxwsk8er wrote:I'd say usable memory would be memory that is installed and available to the OS.
In that case, you'd probably want to include "ACPI reclaimable" area/s, and exclude partial pages (e.g. if there's a page at 0x9F000 that is half RAM and half reserved and OS can't use it because OS only uses whole pages, then it wouldn't be counted as "available").
Cheers,
Brendan
Re: Is this memory map sane?
Posted: Wed Apr 27, 2016 2:28 am
by moondeck
But how can region 1 start at 0 and be 9fc001 in length, and 2nd region start at 9fc00 o.0?
Re: Is this memory map sane?
Posted: Wed Apr 27, 2016 2:32 am
by Octocontrabass
Octocontrabass wrote:there's no space between the length and the type.
Re: Is this memory map sane?
Posted: Wed Apr 27, 2016 4:01 am
by moondeck
So, when it ends with "1" its free?
Re: Is this memory map sane?
Posted: Wed Apr 27, 2016 4:11 am
by sleephacker
So, when it ends with "1" its free?
the "type" field is defined as "1 = usable RAM" and "anything else is unusable".
See also:
http://wiki.osdev.org/Detecting_Memory_ ... p_Via_GRUB