Hi!
I've been trying to solve a problem with the RAM size values passed by GRUB in the Multiboot Info structure since last week, but I always get the same problem.
I get the "problem" only with real computer, so exclude Bochs, QEmu, etc...
I know that I have to multiply the upper memory value passed by GRUB by 1024 and then add 1MB. Though, when I convert it to MBs to show it in the console, I get 511MB for a machine with 512MB and 1023MB for a machine with a 1GB ram.
I checked the values before the division and I saw that GRUB "forgets" some KBs. I really hate this problem: it's very annoying!
Can someone help me, please?
Cheers,
falconfx
Strange Multiboot RAM problem
Re:Strange Multiboot RAM problem
I'm pretty sure that this isn't Grub's fault. The BIOS routines it uses report this. What those are reporting is available / reserved memory and that does not include the full amount (it always a bit short).
I think the more advanced BIOS functions (PNP, ACPI ?) may allow you to get the actual amount installed, but I'm not sure.
If it is for display purposes you could round it up to the nearest 1 or 4 MB or something? That might work.
I think the more advanced BIOS functions (PNP, ACPI ?) may allow you to get the actual amount installed, but I'm not sure.
If it is for display purposes you could round it up to the nearest 1 or 4 MB or something? That might work.
Re:Strange Multiboot RAM problem
Hi,
I'd also guess that your code does some truncating. Do you do "shr <bytes>, 20" to convert bytes into MB (or perhaps integer division, where the remainder is ignored)? If there's 511.875 MB, would your code round it down to display it?
In this case you could just add 512 KB to the value first, so that you'd be rounding it to the nearest 1 MB (instead of rounding it down). The means 511.875 or 511.5 would be displayed as 512 MB, and 511 or 511.499 would be displayed as 511 MB. Of course displaying digits after the decimal point might also help..
Cheers,
Brendan
Why aren't you using the system memory map passed by GRUB instead?falconfx wrote:I know that I have to multiply the upper memory value passed by GRUB by 1024 and then add 1MB. Though, when I convert it to MBs to show it in the console, I get 511MB for a machine with 512MB and 1023MB for a machine with a 1GB ram.
I have a feeling that GRUB gets the system memory map from the BIOS (Int 0x15, eax = 0xE820) and then converts this into "upper memory value". Normally the BIOS returns an area for ACPI non-volatile RAM and an ACPI reclaimable area just below the top of RAM, which would be where the "forgotten" KBs would have been.falconfx wrote:I checked the values before the division and I saw that GRUB "forgets" some KBs. I really hate this problem: it's very annoying!
I'd also guess that your code does some truncating. Do you do "shr <bytes>, 20" to convert bytes into MB (or perhaps integer division, where the remainder is ignored)? If there's 511.875 MB, would your code round it down to display it?
In this case you could just add 512 KB to the value first, so that you'd be rounding it to the nearest 1 MB (instead of rounding it down). The means 511.875 or 511.5 would be displayed as 512 MB, and 511 or 511.499 would be displayed as 511 MB. Of course displaying digits after the decimal point might also help..
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.
Re:Strange Multiboot RAM problem
What about this code:
I haven't tested this code, but it should work. Basically, it reads these two CMOS values and puts them together. I'm not sure about the asm commands, either, as I use this code before even first enable interrupts in my kernel.
Code: Select all
unsigned int memory_size()
{
// disable interrupts if needed, asm: cli
outportb(0x70,0x30);
unsigned int a = inportb(0x71);
outportb(0x70,0x31);
unsigned int b = inportb(0x71);
unsigned int s = (a << 8) ^ b;
// if you disabled interrupts, enable them again, asm: sti
return s;
}
Re:Strange Multiboot RAM problem
Hi,
Also (AFAIK) some BIOSs will limit this value to 15 MB (even when more is present), or in rare cases (if there's an ISA "hole") 14 MB.
This value won't include the ACPI areas though, so for a computer with 4 MB of RAM it will report 3 MB of extended memory (rather than 2.75 MB or something).
Cheers,
Brendan
What about computers that have more than 64 MB of RAM?Candamir wrote: What about this code:
Also (AFAIK) some BIOSs will limit this value to 15 MB (even when more is present), or in rare cases (if there's an ISA "hole") 14 MB.
This value won't include the ACPI areas though, so for a computer with 4 MB of RAM it will report 3 MB of extended memory (rather than 2.75 MB or something).
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.
Re:Strange Multiboot RAM problem
OK, if the CMOS won't help me with this, what can I do about this? I heard that there was a BIOS interrupt (15h), but I think it would be rather unpractical to switch between real and protected modes. Earlier in this post, you mentioned something about GRUB passing values; how is this done or where can I retrieve this info and what other useful information apart from the amount of RAM is stored there? I checked the GRUB manual, but there only was a FIXME comment...
Re:Strange Multiboot RAM problem
grub passes a structure -- directly coppied from the BIOS call: in0x15 -- 0xe820
this structure has a variable number of entries, and will tell you which addresses contain RAM (using any other method can be dangerous, esspecially with larger amounts of RAM -- some of the address space below top_of_RAM may contain mem-mapped hardware ports) parsing this structure, will also tell you about where holes in the memory are (including the 15MB hole), and which memory is usable -- up to the entire physical address-bus (most other memory return functions are limited to the 32bit 386 address-bus -- which was expanded with the P6 (the PPro, PII, PIII, PIV, athlon (all), and possably the later k6s (not sure when AMD implemented it)
don't know enough about grub to tell you exactly where to find the structure though (i use my own bootloader, and query the BIOS for it)
this structure has a variable number of entries, and will tell you which addresses contain RAM (using any other method can be dangerous, esspecially with larger amounts of RAM -- some of the address space below top_of_RAM may contain mem-mapped hardware ports) parsing this structure, will also tell you about where holes in the memory are (including the 15MB hole), and which memory is usable -- up to the entire physical address-bus (most other memory return functions are limited to the 32bit 386 address-bus -- which was expanded with the P6 (the PPro, PII, PIII, PIV, athlon (all), and possably the later k6s (not sure when AMD implemented it)
don't know enough about grub to tell you exactly where to find the structure though (i use my own bootloader, and query the BIOS for it)