Is this memory map sane?

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.
User avatar
moondeck
Member
Member
Posts: 56
Joined: Sat Dec 19, 2015 12:18 pm
Libera.chat IRC: moondeck
Location: The Zone, Chernobyl

Is this memory map sane?

Post 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:
Image
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Is this memory map sane?

Post 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.
User avatar
sleephacker
Member
Member
Posts: 97
Joined: Thu Aug 06, 2015 6:41 am
Location: Netherlands

Re: Is this memory map sane?

Post 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.
User avatar
moondeck
Member
Member
Posts: 56
Joined: Sat Dec 19, 2015 12:18 pm
Libera.chat IRC: moondeck
Location: The Zone, Chernobyl

Re: Is this memory map sane?

Post by moondeck »

I think i've got it, what do you think? Now, how do i find out what is mapped where?
Image
User avatar
sleephacker
Member
Member
Posts: 97
Joined: Thu Aug 06, 2015 6:41 am
Location: Netherlands

Re: Is this memory map sane?

Post 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.
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Is this memory map sane?

Post 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
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Is this memory map sane?

Post 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
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.
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Is this memory map sane?

Post 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
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Is this memory map sane?

Post 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
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.
User avatar
deleted
Member
Member
Posts: 82
Joined: Mon Jul 21, 2014 7:23 pm

Re: Is this memory map sane?

Post by deleted »

Brendan wrote:Snip
Okay awesome :D

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 :D
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Is this memory map sane?

Post 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
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.
User avatar
moondeck
Member
Member
Posts: 56
Joined: Sat Dec 19, 2015 12:18 pm
Libera.chat IRC: moondeck
Location: The Zone, Chernobyl

Re: Is this memory map sane?

Post by moondeck »

But how can region 1 start at 0 and be 9fc001 in length, and 2nd region start at 9fc00 o.0?
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: Is this memory map sane?

Post by Octocontrabass »

Octocontrabass wrote:there's no space between the length and the type.
:wink:
User avatar
moondeck
Member
Member
Posts: 56
Joined: Sat Dec 19, 2015 12:18 pm
Libera.chat IRC: moondeck
Location: The Zone, Chernobyl

Re: Is this memory map sane?

Post by moondeck »

So, when it ends with "1" its free?
User avatar
sleephacker
Member
Member
Posts: 97
Joined: Thu Aug 06, 2015 6:41 am
Location: Netherlands

Re: Is this memory map sane?

Post 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
Post Reply