Search code examples
memoryx86bootloaderosdevmemory-mapping

How to detect or probe or scan usable/accessible physical memory?


How to exhaustively detect or probe or scan usable/accessible physical memory?

I'm currently making a custom bootloader in NASM for a x86_64 custom operating system.

In order to assign which physical address to contain which data, I want to make sure that the memory is guaranteed free for use. I've already tried BIOS interrupt int 0x15 eax 0xE820 and checked out device manager memory resources. The problem is that none of them covers fully.

For example, it says 0x0000000000000000 ~ 0x000000000009FC00 is usable. But strictly speaking, 0x0000000000000000 ~ 0x0000000000000500 is not usable because it stores IVT and BDA.

Also, there are PCI holes here and there.

My objective here is detecting or probing or scanning entire memory available in my hardware and make a memory map so that I can distinguish which address is which. (Example map below)

0x0000000000000000 ~ 0x00000000000003FF : Real Mode IVT
0x0000000000000400 ~ 0x00000000000004FF : BDA
...
0x0000000000007C00 ~ 0x0000000000007DFF : MBR Load Address
...
0x00000000000B8000 ~ 0x00000000000B8FA0 : VGA Color Text Video Memory
...
0x00000000C0000000 ~ 0x00000000FFFFFFFF : PCI Space

My processor is intel i7-8700K 8th gen.


Solution

  • How much information do you want?

    If you only want to know which areas are usable RAM; then "int 0x15, eax=0xE820" (with the restriction that the BDA will be considered usable), or UEFI's "get memory map" function, are all you need. Note that for both cases one/some areas may be reported as "ACPI reclaimable", which means that after you've finished parsing ACPI tables (or if you don't care about ACPT tables) the RAM will become usable.

    If you want more information you need to do more work, because the information is scattered everywhere. Specifically:

    • ACPI's SRAT table describes which things (e.g. which areas of memory) are in which NUMA domain; and ACPI's SLIT table describes the performance implications of that.

    • ACPI's SRAT table also describes which things (e.g. which areas of memory) are "hot plug removable" and reserved for "hot insert".

    • the CPU's CPUID instruction will tell you "physical address size in bits". This is useful to know if/when you're trying to find a suitable area of the physical address space to use for a memory mapped PCI device's BARs, because the memory maps you get are too silly to tell you the difference between "not usable by memory mapped PCI devices", "usable by memory mapped PCI devices" and "used by memory mapped PCI devices".

    • parsing (or configuring) PCI configuration space (in conjunction with IOMMUs if necessary) tells you which areas of the physical address space are currently used by which PCI devices

    • parsing "System Management BIOS" tables can (with a lot of work and "heuristical fumbling") tell you which areas of the physical address space correspond to which RAM chips on the motherboard and what the details of those RAM chips are (type, speed, etc).

    • various ACPI tables (e.g. MADT/APIC and HPET) can be used to determine the location of various special devices (local APICs, IO APICs, HPET).

    • you can assume that (part of) the area ending at physical address 0xFFFFFFFF will be the firmware's ROM; and (with some more "heuristical fumbling" to subtract any special devices from the area reported as "reserved" by the firmware's memory map) you can determine the size of this area.

    If you do all of this you'll have a reasonably complete map describing everything in the physical address space.