Getting and using GRUB memory map

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
amfournda

Getting and using GRUB memory map

Post by amfournda »

so im working on the beginnings of a memory manager and I said to myself: "I need to get a picutre of how memory is right now before I can start managing it." So I decided I wanted to get my memory info from GRUB. Its fast, its easy. However I dont think im getting this correctly. Is there some sort of "expected" value that an inital memory map from grub is going to give me on an x86? im using the following code with mbd being the full multiboot info struct that grub passes. I actually dont have an intelligent printf() solution coded as of yet, so pardon my lots of puts, also my puts doesnt handle numbers well so far, so I have a long2char() function that does guess what?

Code: Select all

unsigned long p = mbd->mmap_addr;

while(p < mbd->mmap_addr + mbd->mmap_length) {
      memory_map_t *temptable = &p;
      puts("0x");
      puts(long2char(temptable->size));
      puts("  0x");
      puts(long2char(temptable->base_addr_low));
      puts(" 0x");
      puts(long2char(temptable->base_addr_high));
      puts(" 0x");
      puts(long2char(temptable->length_low));
      puts("  0x");
      puts(long2char(temptable->length_high));
      puts("    0x");
      puts(long2char(temptable->type));
      puts("\n");
      p += sizeof(memory_map_t);
   }
This code seems to give me bogus output, any clue what im doing wrong?
amfournda

Re:Getting and using GRUB memory map

Post by amfournda »

revamped it some more:

Code: Select all

puts("Memory Table found at: 0x");
puts(long2char(mbd->mmap_addr));
puts("\n");
unsigned long p = mbd->mmap_addr;

puts("BASE                LENGTH                 TYPE\n"); 

while(p < mbd->mmap_addr + mbd->mmap_length) {
   memory_map_t *temptable = &p;
   puts("0x");
   puts(long2char(temptable->base_addr_high));
   puts(long2char(temptable->base_addr_low));
   puts("    0x");
   puts(long2char(temptable->length_high));
   puts(long2char(temptable->length_low));
   puts("        0x");
   puts(long2char(temptable->type));
   puts("\n");
   p += temptable->size;
}
just gives me one entry

just to allieviate some confusion my memory map looks like this:

Code: Select all

typedef struct memory_map {
   unsigned long size;
   unsigned long base_addr_low;
   unsigned long base_addr_high;
   unsigned long length_low;
   unsigned long length_high;
   unsigned long type;
} memory_map_t;
Kemp

Re:Getting and using GRUB memory map

Post by Kemp »

And what output do you get? "Bogus" could mean the output is incorrect, but it could also mean it is correct but in a way you didn't expect.
amfournda

Re:Getting and using GRUB memory map

Post by amfournda »

the memory map I get doesnt match the memory map that grub prints out when I go into the grub console at boot time and type "displaymem".
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Getting and using GRUB memory map

Post by Pype.Clicker »

Code: Select all

 memory_map_t *temptable = &p;   // >_<
I'd say you should read a bit more about pointers and the like. casting your memory_map into a void* to safely advance by "entry->size" is okay. casting it into an int (or unsigned, or long, or whatever) is weird, and extracting the int's address rather than casting the void* back into a memory_map_t* is just wrong.
amfournda

Re:Getting and using GRUB memory map

Post by amfournda »

yeah, I realized that now, thanks
amfournda

Re:Getting and using GRUB memory map

Post by amfournda »

I hope this is more reasonable, it still gives me output that differs from what grub says.

Code: Select all

void memory_manager_init(multiboot_info_t* mbd) {

   memory_map_t *mmap;
   
   puts("Memory Table found at: 0x");
   puts(decimal2hex(mbd->mmap_addr));
   puts("\n");
   puts("BASE\t\t\tLENGTH\t\t\tTYPE\n"); 

   mmap = (memory_map_t *) (mbd->mmap_addr);
   while((unsigned long) mmap < mbd->mmap_addr + mbd->mmap_length) {
      puts("0x");
      puts(decimal2hex(mmap->base_addr_high));
      puts(decimal2hex(mmap->base_addr_low));
      puts("\t0x");
      puts(decimal2hex(mmap->length_high));
      puts(decimal2hex(mmap->length_low));
      puts("\t0x");
      puts(decimal2hex(mmap->type));
      puts("\n");
      mmap = (memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof (mmap->size));
   }
}
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Getting and using GRUB memory map

Post by Pype.Clicker »

well, i'd say use the bochs with debugger, set a breakpoint on your function (hint: use objdump -drS to find its address in your elf file), check the address you receive and inspect memory content over there to make sure it looks like what GRUB reported.

Then check you actually read the correct values with your code and that what's printed correspond to what's to be printed (e.g. have you debugged hex_to_str yet?)
Post Reply