int 15h/e820h map again.

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
stonedzealot

int 15h/e820h map again.

Post by stonedzealot »

I think I understand how this 15h/e820h BIOS call works, but where do you execute it? It requires 32 bit registers to be set (edx = 'SMAP'), but you have to still use the BIOS. Does that mean you have to switch to 32 bit real mode to make the call or just that you have to make sure that you're running a 32 bit system before you call it. Where do those BIOS functions cut out, anyway?
Curufir

Re:int 15h/e820h map again.

Post by Curufir »

Easiest way is to just run it before making the switch to PMode and store the information at some known address. You're perfectly entitled to use the full 32-bit registers in Real Mode.
Where do those BIOS functions cut out, anyway?
Essentially you're limited to using them in Real (Along with the Unreal hacks, etc) mode and VM86 mode. Once in PMode the processor is expecting 32-bit code (All the BIOS interrupts are written in 16-bit code) and is using the IDT not the IVT.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:int 15h/e820h map again.

Post by Candy »

Curufir wrote:
Where do those BIOS functions cut out, anyway?
Essentially you're limited to using them in Real (Along with the Unreal hacks, etc) mode and VM86 mode. Once in PMode the processor is expecting 32-bit code (All the BIOS interrupts are written in 16-bit code) and is using the IDT not the IVT.
Then what about 16-bit protected mode? If the BIOS is written with care, that could work?
Karig

Re:int 15h/e820h map again.

Post by Karig »

I believe that INT 15h, EAX=E820h has to be called from real mode (16-bit protected mode MIGHT work, but I can't vouch for that). The function almost certainly uses only 16-bit code, but it passes around 32-bit data so that it can deal with arbitrary addresses anywhere in the x86's four-gigabyte address space.
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:int 15h/e820h map again.

Post by Neo »

my friends system(about 4yrs old) intially had 32MB RAM a year back he bought another 128MB. My problem is that the int15 map shows all memory as Type1(i.e usable RAM).how can this be? what about BIOS-ROM etc.. The int15 function however on my computer(about a year old) as well as another friends computer (both having 128MB only) works fine showing the following,
|----------------------------------
| Base??? |???Length??? | Type |
|---------- | ------------ | ------|
| 0x0??? |???0x9FC00??? |???1 |
| 0x9FCOO |???0x400??? |???2 |
| 0xE0000 |???0x20000??? |???2 |
| 0x100000 |???0x7DF0000 |???1 |
| 0x7EF0000 | ???0x8000??? |???3 |
| 0x7EF8000 |???0x8000??? |???4 |
| 0x7F00000 |???0x100000 |???2 |
-----------------------------------
so i guess the function is right. does anyone have any idea why this happens? how an i be sure of getting the real memory map.
Only Human
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:int 15h/e820h map again.

Post by Candy »

Neo wrote: so i guess the function is right. does anyone have any idea why this happens? how an i be sure of getting the real memory map.
Why? Some BIOS programmer that doesn't know his standards. How to fix? Ignore all references that say 0xA0000-0xFFFFF is available, and possibly add the EBDA and BDA (and IVT) to that. Aside from that, you cannot help overwriting ACPI structs or things like that, the system is simply plain buggy.

I would try to find a BIOS update for those things.
stonedzealot

Re:int 15h/e820h map again.

Post by stonedzealot »

Okay, so I finally got working and managed to generate something that looks like a memory map. My question is...when the map is generated, it looks something like this for the first entry:

Code: Select all

OFFSET: CONTENT
0 (BASE QWORD):        0x0000000000000000
8 (LENGTH QWORD):  0x0009FC0000000000
16 (TYPE DWORD):      0x0000000000000001
Now. This makes sense...except for that Length. I'm fairly certain that it's not 9FC0000000000 bytes of RAM (which is an insanely large number). Instead the first DWORD makes sense (0x9FC00 bytes, about 639k of RAM). But if the BIOS says it's a QWORD, why isn't it 0x000000000009FC00?
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:int 15h/e820h map again.

Post by Candy »

wangpeng wrote: Now. This makes sense...except for that Length. I'm fairly certain that it's not 9FC0000000000 bytes of RAM (which is an insanely large number). Instead the first DWORD makes sense (0x9FC00 bytes, about 639k of RAM). But if the BIOS says it's a QWORD, why isn't it 0x000000000009FC00?
Because it's stored little-endian. That means, the small end is first, so you should place the 0009FC00 AFTER the 00000000. Not the other way around. Using a long long in C/C++ "converts" this automatically. So, for use in C, use something like this:

Code: Select all

struct e820_map {
  long long offset;
  long long size;
  int type;
};
and the problem's gone.
stonedzealot

Re:int 15h/e820h map again.

Post by stonedzealot »

I see. That makes perfect sense. Unfortunately, I don't think of numbers in endians unless I'm seeing them in binary. Thanks alot.
Post Reply