Page 1 of 2
memory amount
Posted: Sat May 26, 2007 2:48 pm
by jtlb
i don't understand how to get the mem amount of a compuer? the information from grub are not exact: 64mb instead of 320mb
Posted: Sat May 26, 2007 3:57 pm
by xsix
GRUB maybe uses CMOS, or BIOS function which returns MAX of 64mb or ram(16bit number). Use BIOS AX=E801h INT=15h BIOS function to return all the size of memory or write your own routine which writes and then reads values from memory and handles fault when data is written into not present memory address
Posted: Sat May 26, 2007 5:02 pm
by Brynet-Inc
xsix wrote:GRUB maybe uses CMOS, or BIOS function which returns MAX of 64mb or ram(16bit number). Use BIOS AX=E801h INT=15h BIOS function to return all the size of memory or write your own routine which writes and then reads values from memory and handles fault when data is written into not present memory address
You're wrong.. GRUB actually does attempt to use three BIOS methods of memory detection..
INT 15H, AX=E820h
INT 15H, AX=E801h
INT 15H, AX=88h (
Max 16MB detection IIRC..)
GRUB also switches into protected mode before loading the kernel as well..
Not sure why it isn't successfully detecting the RAM in your system though.. Not properly reading the value from the Multiboot structure?
Posted: Sat May 26, 2007 11:41 pm
by Brendan
Hi,
Brynet-Inc wrote:Not sure why it isn't successfully detecting the RAM in your system though.. Not properly reading the value from the Multiboot structure?
I think the answer to this in in the original question: "
i don't understand how to get the mem amount of a compuer?"
The "mem amount" is probably the "mem_lower" and "mem_upper " fields of the multiboot information structure, that should only be used if the memory map isn't present.
The memory map (derived from BIOS Int 0x15, eax = 0xE820") is accessed via. the "mmap_length" and "mmap_addr " fields of the multiboot information structure.
Cheers,
Brendan
Posted: Tue May 29, 2007 2:30 am
by jtlb
I understoodhow to get the meme amount correctly from grub, it works in qemu, some real computerbut not mine??
in fact it does "see" only my first memory chip of 64mb, and i have onother one of 256mb.
Posted: Tue May 29, 2007 2:38 am
by Combuster
Have you tried displaying the entire memory map provided by grub so that you could verify that everything works?
Posted: Tue May 29, 2007 7:39 am
by jtlb
no. i did'nt understand how it works.
Posted: Tue May 29, 2007 10:38 am
by Combuster
hmm so the question becomes:
How can I parse grub's memory map.
rather than
Grub's memory map is inexact.
Assuming that you have read the GRUB manual in excess of 3 times, what is it that you don't understand of it?
Posted: Sun Jan 13, 2008 1:16 pm
by marcio
I've read the GRUB Manual and Multiboot Specification and I still can't get the memory map to be printed properly.
What happens is that all, but the last, memory regions seem to contain correct values; the last one contains garbage. Looking at what happens in Bochs (see attached screenshot), the last "offset" value in ASCII is "kern" so I'm sure there's a problem in my code. I even copy/pasted the
Multiboot example but the problem remains.
Here's the struct I use for the memory region:
Code: Select all
typedef dword_t MB_Memory_Region_Type;
enum {
// (All other values indicate reserved memory.)
TYPE_AVAILABLE = 1,
};
typedef struct {
dword_t next_offset; // (In bytes.)
qword_t start; // (Offset 0 of this structure.)
qword_t size; // (In bytes.)
MB_Memory_Region_Type type;
}
MB_Memory_Region;
And this is the code I use to print the full memory map:
Code: Select all
if (BIT_IS_SET(info->flags, 6)) {
MB_Memory_Region* region;
log_info("- Memory map: size={i} B", info->memory_map_size);
for (region = info->memory_map;
region < (info->memory_map + info->memory_map_size);
region = (MB_Memory_Region*) ((byte_t*) region + region->next_offset + sizeof(region->next_offset)))
{
log_info(" - Region: offset={i} B; start={iuh}h; "
"length={iuh}h; type={i}", region->next_offset,
(dword_t) region->start, (dword_t) region->size, region->type);
}
}
Can anyone point out what am I doing wrong?
Thanks!
Posted: Sun Jan 13, 2008 1:21 pm
by ucosty
You are counting too far. The second last entry has the offset 0xFFFC0000 and the length 0x40000. Add that together and you have reached the end of the 32-bit addressable space (0xFFFFFFFF). No more memory map after that.
edit: the rest looks perfect.
Posted: Sun Jan 13, 2008 2:11 pm
by marcio
Thanks for such a fast reply
Are you sure I should do that check? Shouldn't the "for" loop take care of that? Because if that's not the case then the example given by the Multiboot specification is wrong... which seems very unlikely.
Posted: Sun Jan 13, 2008 2:49 pm
by ucosty
Your for loop is exactly the same as mine (not surprising since there is only so many ways it can be coded).
hack alert: you could always change the loop so it stops when region->start + region-> size - 1 == 0xFFFFFFFF.
Posted: Sun Jan 13, 2008 2:57 pm
by bewing
I don't see how you are intending (in C) to test whether you have overflowed a 32bit variable, using a 32bit test?
Posted: Sun Jan 13, 2008 2:57 pm
by marcio
Ok, suppose I put a check to stop when 0xFFFFFFFF. Then it wouldn't work with a Multiboot compliant bootloader on 64-bit machines... that's why I'm so reluctant to add that check.
My question remains: shouldn't the loop take care of that automatically because that's exactly how the example from the Multiboot specification has it?
Posted: Sun Jan 13, 2008 4:32 pm
by Combuster
You've been misinterpreting the spec. The memory map array consists of 24-byte entries. The size does not include the size field itself.
The net result is that you get (120 bytes in table)/(20 bytes per entry) = 6 entries while there's actually 120/24 = 5 entries. Looking at your shot you can see that there are 5 meaningful entries.