A Question about ARDS (Address Range Descriptor Struct)

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
User avatar
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

A Question about ARDS (Address Range Descriptor Struct)

Post by Js2xxx »

Well, does anybody know the types of ARDS?
I've only known 01h and 02h.

If anybody knows a lot about any other knowledge of it, please teach me as well.

Thanks a lot.
Doing steadfastly, or doing nil.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by Brendan »

Hi,
XuQihang wrote:Well, does anybody know the types of ARDS?
I've only known 01h and 02h.

If anybody knows a lot about any other knowledge of it, please teach me as well.
Could you be a little more specific?

The nice thing about languages like C is that anyone can define a structure called ARDS and put anything they feel like in it. :roll:


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.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by alexfru »

INT 15h, AX=E820h: ES:DI Pointer to an Address Range Descriptor structure which the BIOS is to fill in.
User avatar
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by Js2xxx »

Brendan wrote:Hi,
XuQihang wrote:Well, does anybody know the types of ARDS?
I've only known 01h and 02h.

If anybody knows a lot about any other knowledge of it, please teach me as well.
Could you be a little more specific?

The nice thing about languages like C is that anyone can define a structure called ARDS and put anything they feel like in it. :roll:


Cheers,

Brendan
I means, I want to get memory information by calling BIOS (16 Bits Assembler). I've heard the way is 'mov ax, 0E820h' and 'int 15h'. Some book wrote after calling the pointer of ARDS is stored in 'es:di'. Now I can get ARDS, but I don't know the detailed structure of ARDS.
Can you help me? If you don't mind, I'll be very grateful.
Doing steadfastly, or doing nil.
User avatar
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by Js2xxx »

alexfru wrote:INT 15h, AX=E820h: ES:DI Pointer to an Address Range Descriptor structure which the BIOS is to fill in.
And after I got it, how to catch the information in it?
Thanks if you don't mind telling me about it.
Doing steadfastly, or doing nil.
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by BrightLight »

Code: Select all

struct e820_entry
{
	uint64_t base;
	uint64_t length;
	uint32_t type;
	uint32_t acpi3;
}__attribute__((packed))
base is the 64-bit physical address of the physical memory range.
length is the 64-bit length of the physical memory located at base.
type can be one of several values. 1 means "available" or usable RAM. 2 means hardware-reserved. 3 means hardware-reserved until you've saved the ACPI tables. 4 means ACPI memory that must be preserved during sleep states. 5 means the memory contains errors. All other values should be treated as type 2. You shouldn't allow your physical memory manager to allocate memory except those that are marked 1 or "free for use."
acpi3 may or may not be present. If the function returned 20 bytes, then this field is not present. If it returned 24 bytes, then it is present. It is a bitfield, but I'm not sure what exactly it contains. You can find out from the ACPI spec.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by Brendan »

Hi,
XuQihang wrote:
Brendan wrote:Could you be a little more specific?
I means, I want to get memory information by calling BIOS (16 Bits Assembler). I've heard the way is 'mov ax, 0E820h' and 'int 15h'. Some book wrote after calling the pointer of ARDS is stored in 'es:di'. Now I can get ARDS, but I don't know the detailed structure of ARDS.
Can you help me? If you don't mind, I'll be very grateful.
This is part of the ACPI specification now (since the first version of the ACPI specification); and the ACPI specification/s gives complete details (including the extension that increased the structure's size to 24 bytes and the flags that were added, and all the new types, etc). I'd recommend downloading at least the most recent version of the ACPI specification (and every version of the ACPI specification if you can, so you can figure out what was added when).

For old information (including information for computers that existed before the first version of ACPI) see the corresponding entry in Ralph Brown's Interrupt List.

Note that:
  • The raw data from "int 0x15, eax=0xE820" should be sanitised; including merging adjacent areas of the same type and attributes, handling areas that are misreported as overlapping, and possibly sorting it in a sane order.
  • The memory map you get from UEFI is quite different (different types, additional "cacheability" information, etc).
  • If you support very old computers (that don't support "int 0x15, eax=0xE820") it's possible to fabricate equivelent information from older BIOS functions (but takes some care).
  • None of the memory maps from firmware (from UEFI, from BIOS "int 0x15, eax=0xE820", or fabricated from older BIOS functions) include:
    • information about NUMA domains (can be obtained from ACPI's tables)
    • "hot-plug RAM" areas (can be obtained from ACPI's tables)
    • the physical address space size (can be obtained from CPUID)
    • which areas are/aren't usable for memory mapped PCI devices (can be derived from other information and "guesswork")
    • which areas are currently being used by memory mapped PCI devices (can be derived from PCI configuration space)
    • how physical memory areas relate to "motherboard RAM slots" and what type of RAM is involved and if it's ECC or not (can only be partially obtained from SMBIOS tables - you need a motherboard chipset to figure it out properly).
  • The memory maps from BIOS (from BIOS "int 0x15, eax=0xE820", or fabricated from older BIOS functions) don't include cacheability information (but the memory map from UEFI does). You could obtain this information on BIOS systems by extracting it directly from the CPU's MTRRs.
For these reasons I recommend inventing your own "memory map entry structure", and converting whatever the firmware gives you into your own format, and then merging all the other information (from other places) into that structure. If you do this right, you can end up with a "standard for your OS" memory map (regardless of what the firmware was) that contains all relevant information in one place.


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
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by Js2xxx »

Now I can successfully get the data in ARDS.
Then would you mind telling me how to calculate the memory size?
Attachments
The capture of my incomplete OS.
The capture of my incomplete OS.
capture.png (7.18 KiB) Viewed 3876 times
Doing steadfastly, or doing nil.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by alexfru »

XuQihang wrote:Now I can successfully get the data in ARDS.
Then would you mind telling me how to calculate the memory size?
Don't you have it now? It's in your picture.
User avatar
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by Js2xxx »

alexfru wrote: Don't you have it now? It's in your picture.
Well, I means, the total memory size.
I use VMware and I allocate 5 GB Memory for the vm, but the calculation result is greater than 5 GB.
I don't know what goes wrong.
Doing steadfastly, or doing nil.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by alexfru »

XuQihang wrote: I use VMware and I allocate 5 GB Memory for the vm, but the calculation result is greater than 5 GB.
I don't know what goes wrong.
I think you shouldn't be adding sizes of areas other than type 1. And also 1 GB probably means 1,073,741,824 and not 1,000,000,000.
User avatar
Js2xxx
Member
Member
Posts: 48
Joined: Sat Dec 31, 2016 1:43 am
Libera.chat IRC: wrgq
Location: China

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by Js2xxx »

alexfru wrote:
I think you shouldn't be adding sizes of areas other than type 1. And also 1 GB probably means 1,073,741,824 and not 1,000,000,000.
Well, I've done what you say. However, the result isn't 5 GB again.
5 GB is 1_4000_0000h, but the result is 1_3FF8_F800h. It's 7_0800h lower.
Doing steadfastly, or doing nil.
mikegonta
Member
Member
Posts: 229
Joined: Thu May 19, 2011 5:13 am
Contact:

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by mikegonta »

omarrx024 wrote:

Code: Select all

struct e820_entry
{
	uint64_t base;
	uint64_t length;
	uint32_t type;
	uint32_t acpi3;
}__attribute__((packed))
For best performance on x86 (and others) don't pack already "packed" structs.
Why you shouldn’t use __attribute__((packed))
Mike Gonta
look and see - many look but few see

https://mikegonta.com
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: A Question about ARDS (Address Range Descriptor Struct)

Post by Brendan »

Hi,
XuQihang wrote:Then would you mind telling me how to calculate the memory size?
That depends on which memory size you want:
  • For "amount of currently usable RAM", add up the lengths for each area reported as "type = 1"
  • For "amount of currently free and usable RAM", get the "amount of currently usable RAM" and subtract whatever your OS is already using and subtract the estimated size of the BIOS Data Area (e.g. "about 1.5 Kib" or maybe 4 KiB).
  • For "amount of total usable RAM", add up the lengths for each area reported as "type = 1" or "type = 3" (the ACPI reclaimable areas that become usable after you reclaim them).
  • For "amount of RAM installed", it's impossible to figure this out reliably from the memory map because the chipset and BIOS can steal RAM for various purposes (integrated video, memory for SMM, etc) and can also relocate areas (e.g. to make space for the "PCI hole" below 4 GiB). Instead, you need to get this information from the firmware's SMBIOS tables.
Note: Most of the above assumes that there are no overlapping areas. E.g. If the firmware is a little buggy and says there's three areas of RAM that are 1 GiB in size and that all start at the same address, then that counts as 1 GiB of RAM and not 3 GiB of RAM.


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