memory amount
memory amount
i don't understand how to get the mem amount of a compuer? the information from grub are not exact: 64mb instead of 320mb
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
- Brynet-Inc
- Member
- Posts: 2426
- Joined: Tue Oct 17, 2006 9:29 pm
- Libera.chat IRC: brynet
- Location: Canada
- Contact:
You're wrong.. GRUB actually does attempt to use three BIOS methods of memory detection..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
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?
Hi,
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
I think the answer to this in in the original question: "i don't understand how to get the mem amount of a compuer?"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?
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
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.
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:
And this is the code I use to print the full memory map:
Can anyone point out what am I doing wrong?
Thanks!
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;
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);
}
}
Thanks!
- Attachments
-
- Multiboot info on Bochs.
- bochs.png (21.34 KiB) Viewed 2662 times
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.
edit: the rest looks perfect.
The cake is a lie | rackbits.com
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.
hack alert: you could always change the loop so it stops when region->start + region-> size - 1 == 0xFFFFFFFF.
Last edited by ucosty on Sun Jan 13, 2008 3:08 pm, edited 1 time in total.
The cake is a lie | rackbits.com
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?
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?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
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.
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.