Page 1 of 1

Incorrect data in case of upper memory detect

Posted: Tue Dec 10, 2019 10:22 am
by mrjbom
Hello.

I'm trying using GRUB to get the total RAM size.

Code: Select all

size_t ram_len;

while(memory_map < MBI->mmap_addr + MBI->mmap_length) {
	memory_map = (multiboot_memory_map_t*)((unsigned int)memory_map + memory_map->size + sizeof(memory_map->size));
        ram_len += memory_map->len;
        char* str_result;
        itoa(memory_map->addr, str_result, 16);
        write_serial_str("addr of section = ");
        write_serial_str(str_result);
        write_serial('\n');
    }
As a result, I get incorrect addresses(I expect to see such as in this table) and incorrect memory size.

Here is the output:

Code: Select all

addr of section = 9fc00
addr of section = f0000
addr of section = 100000
addr of section = 7fe0000
addr of section = -40000
addr of section = 0
mem_lower = 639
mem_upper = 129920
ram_len = 133497856
Link to the repository.

Re: Incorrect data in case of upper memory detect

Posted: Tue Dec 10, 2019 10:41 am
by Octocontrabass

Code: Select all

while(memory_map < MBI->mmap_addr + MBI->mmap_length) {
	memory_map = (multiboot_memory_map_t*)((unsigned int)memory_map + memory_map->size + sizeof(memory_map->size));
You are skipping the first entry of the memory map, and reading past the end of the memory map.

Code: Select all

        char* str_result;
You are declaring a null pointer for your temporary variable. You should declare an array instead. Make sure the array is large enough to store the entire string, including the null terminator.

Code: Select all

        itoa(memory_map->addr, str_result, 16);
Your itoa() function prints signed integers, but the address is an unsigned integer. Your itoa() function handles 32 bits, but the values you want to print are 64 bits.

There may be other problems with your code as well; these are only the ones I spotted after a quick look.

Re: Incorrect data in case of upper memory detect

Posted: Tue Dec 10, 2019 11:26 am
by mrjbom
Octocontrabass wrote:

Code: Select all

while(memory_map < MBI->mmap_addr + MBI->mmap_length) {
	memory_map = (multiboot_memory_map_t*)((unsigned int)memory_map + memory_map->size + sizeof(memory_map->size));
You are skipping the first entry of the memory map, and reading past the end of the memory map.
How do I fix this? This is the code from the wiki and I didn't think it was a mistake.

Re: Incorrect data in case of upper memory detect

Posted: Tue Dec 10, 2019 12:00 pm
by Octocontrabass
mrjbom wrote:How do I fix this? This is the code from the wiki and I didn't think it was a mistake.
The code in the wiki uses "..." to indicate where you are supposed to insert your own code.

Re: Incorrect data in case of upper memory detect

Posted: Tue Dec 10, 2019 12:32 pm
by mrjbom
Octocontrabass wrote:
mrjbom wrote:How do I fix this? This is the code from the wiki and I didn't think it was a mistake.
The code in the wiki uses "..." to indicate where you are supposed to insert your own code.
Have I forgotten something? What is it?

Re: Incorrect data in case of upper memory detect

Posted: Tue Dec 10, 2019 12:54 pm
by Octocontrabass
I'm not sure how else to explain it. The wiki example code uses "..." to show you where you should insert your code. You did not follow those directions, so the example doesn't work.

Not all entries in the memory map are RAM. You will need to check the entry type to see if it should count towards the total RAM.

Your code doesn't handle odd cases like overlapping memory ranges or ranges that aren't aligned to page boundaries, but those are rare.