7

I am working on a small x86 kernel. I am accessing and attempting to read the memory map that GRUB provides in the multiboot header. I have an Intel i3 cpu and 4 GiB of RAM. While running on this machine, I am reading the following memory map:

 --Base Address--          --Length--      --Type--

0x0000000000000000     0x000000000009d000     0x1
0x000000000009d000     0x0000000000003000     0x2
0x00000000000e0000     0x0000000000020000     0x2
0x0000000000100000     0x00000000bb53f000     0x1
0x00000000bb63f000     0x0000000000080000     0x2
0x00000000bb6bf000     0x0000000000100000     0x4
0x00000000bb7bf000     0x0000000000040000     0x3
0x00000000bb7ff000     0x0000000000001000     0x1
0x00000000bb800000     0x0000000004800000     0x2
0x00000000e0000000     0x0000000010000000     0x2
0x00000000feb00000     0x0000000000004000     0x2
0x00000000fec00000     0x0000000000001000     0x2
0x00000000fed10000     0x0000000000004000     0x2
0x00000000fed18000     0x0000000000002000     0x2
0x00000000fed1b000     0x0000000000005000     0x2
0x00000000fee00000     0x0000000000001000     0x2
0x00000000ffe80000     0x0000000000180000     0x2
0x0000000100000000     0x0000000038000000     0x1

When I total up the available memory areas, I get...

0x1 (Available) - 3893.8 MiB

Which seems about right, leaving the last 200ish MiB reserved for other devices. The only problem is the total of the other memory types:

0x2, 0x3, 0x4 - 331.5 MiB

Putting my total amount of RAM at 4225.3 MiB or a little over 4.1 GiB, which leads me to my questions:

  1. Why am I totaling more than 4GiB of RAM when I only have 4GiB installed?

  2. Why is the last base address in the memory map 0x0000000100000000? With only 4GiB of RAM, 32 bits should be the max address size needed to address all of it. Am I misunderstanding something here?

Joel
  • 4,732
  • 9
  • 39
  • 54

1 Answers1

3

Some thoughts:

  • Address space != physical memory size.
  • An i3 supports virtual address spaces in either 64bit, or 32bit mode with 36bit PAE (optional, with kernel support). If you actually have 4GiB of RAM available in the booted 32bit system, PAE must be enabled. How to check: https://serverfault.com/q/247080
  • AFAIR, those ranges could overlap and appear in any order, so that ordering and re-typing to the most restricted type or range splitting is required.
  • That last base address 0x0000000100000000 is >= 2^32. This is usually done, because hardware, ROM images and other special ranges are allocated below 2^32 in (all?) PCs. Thus, either PAE or long mode is required to access main memory ranges starting at or above 2^32.

Edit:

Look here for more details: http://wiki.osdev.org/Detecting_Memory_%28x86%29

Edit 2:

Today, I stumbled upon a Sysinternals tool, which shows following physical range mapping for my EFI System, without any related setting altered. As one can see, all of 64GiB main memory is mapped at 0x100000000, right at 2^32:

Sysinternals RamMap on Win 7 / ASUS EFI BIOS

Community
  • 1
  • 1
Sam
  • 7,778
  • 1
  • 23
  • 49
  • I did not enable PAE; I need to use 64 bit addresses to reach that last portion of memory. So the lower ranges that are mapped elsewhere cause the need for addresses above 4GiB? – Joel Sep 21 '13 at 19:05
  • 1
    Exactly, the ranges with type 0x2,0x3,0x4 are causing this. How exactly the mapping is created depends on the system firmware. Usually, there are also 'memory holes', which exmplain, why more memory than expected is mapped above 4G. – Sam Sep 21 '13 at 19:16
  • Yeah I was wondering about that, since there is almost 900MiB mapped above 4GiB.. Can it really account for that much? – Joel Sep 21 '13 at 19:21
  • Yes, according to various sources, the main memory ranges below 4G can sum up to 2.0 - 3.75GiB at most, depending on how the firmware (BIOS) can/does map it. There could be device mappings above 4G, what would obviously require an appropriate CPU mode. I never saw such a configuration myself. Regarding 'holes': http://en.wikipedia.org/wiki/PCI_hole – Sam Sep 21 '13 at 19:36
  • Just found this tool: http://technet.microsoft.com/en-us/sysinternals/ff700229.aspx – Sam Oct 03 '13 at 18:05
  • Looks like a useful tool! Unfortunately I am running linux so I am unable to use it.. It looks to me your answer is correct here after some further research. Should confirm in a few days. – Joel Oct 04 '13 at 17:45
  • 2
    @Joel in Linux you can look at /proc/iomem to see the physical address mapping. It incorporates information from the PCI configuration, etc. to actually label the non-RAM areas with what they are used for. – Geoff Reedy Dec 23 '13 at 19:03
  • (Here's some extra info to this old answer:) If I've understood correctly, most x86-64 hardware/firmware creates map where physical addressses between 3GB and 4GB from the start of the RAM doesn't contain actual physical RAM. This is because many devices support DMA transfers into these physical addresses only so the OS must access the RAM using different addresses. This is also the reason why PAE is needed to access full 4 GB of RAM with a 32-bit OS kernel – part of the 32-bit address space is lost for hardware access interfaces so some of the RAM must reside outside 32-bit addressible range. – Mikko Rantalainen Aug 07 '23 at 08:07