OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 16, 2024 9:40 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: GRUB memory map
PostPosted: Sat Aug 13, 2016 4:09 pm 
Offline

Joined: Thu Nov 08, 2012 2:59 am
Posts: 15
I'm having a problem figuring out how to get the GRUB memory map. I understand the basics, but there has always been something confusing with it. Namely the offset for the memory map entries.

http://wiki.osdev.org/Detecting_Memory_(x86)#Getting_a_GRUB_Memory_Map
Quote:
Declare the appropriate structure, get the pointer to the first instance, grab whatever address and length information you want, and finally skip to the next memory map instance by adding size+4 to the pointer, tacking on the 4 to account for GRUB treating base_addr_low as offset 0 in the structure


Can anyone explain how the whole -4 offset is handled, because it keeps me from moving forward.


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Tue Aug 16, 2016 8:32 am 
Offline
User avatar

Joined: Tue Jun 21, 2016 6:41 am
Posts: 21
Not sure exactly what you mean, but I hope this helps:

This is how I import the memory map slots:

Code:
  memory_slots = mboot_header->mmap_length / sizeof(mboot_memmap_t);
 
  mem_map_start = (uint32_t)mboot_header->mmap_addr;
  mem_map_size  = (uint32_t)mboot_header->mmap_length;
  mem_map_end = (uint32_t)mboot_header->mmap_addr + (uint32_t)mboot_header->mmap_length;
 
  mboot_memmap_t mmap_entries[memory_slots];
  memcpy((char*)&mmap_entries, (char*)mboot_header->mmap_addr, mboot_header->mmap_length);
 


This is my header file for multiboot definitions, and structs:

Code:
#ifndef MULTIBOOT_H
#define MULTIBOOT_H

#define MULTIBOOT_KERNEL_MAGIC      0x2BADB002
#define MULTIBOOT_HEADER_MAGIC      0x1BADB002

#define MULTIBOOT_MMAP_FREE_MEMORY  1
#define MULTIBOOT_MMAP_RESERVED     2
#define MULTIBOOT_MMAP_ACPI         3
#define MULTIBOOT_MMAP_HIBERNATION  4
#define MULTIBOOT_MMAP_BAD_CELL     5

struct multiboot_header {
  uint32_t flags;
   uint32_t mem_lower;
   uint32_t mem_upper;
   uint32_t boot_device;
   uint32_t cmdline;
   uint32_t mods_count;
   uint32_t mods_addr;
   uint32_t num;
   uint32_t size;
   uint32_t addr;
   uint32_t shndx;
   uint32_t mmap_length;
   uint32_t mmap_addr;
   uint32_t drives_length;
   uint32_t drives_addr;
   uint32_t config_table;
   uint32_t boot_loader_name;
   uint32_t apm_table;
   uint32_t vbe_control_info;
   uint32_t vbe_mode_info;
   uint32_t vbe_mode;
   uint32_t vbe_interface_seg;
   uint32_t vbe_interface_off;
   uint32_t vbe_interface_len;
} __attribute__ ((packed));

typedef struct {
   uint16_t attributes;
   uint8_t  winA, winB;
   uint16_t granularity;
   uint16_t winsize;
   uint16_t segmentA, segmentB;
   uint32_t realFctPtr;
   uint16_t pitch;

   uint16_t Xres, Yres;
   uint8_t  Wchar, Ychar, planes, bpp, banks;
   uint8_t  memory_model, bank_size, image_pages;
   uint8_t  reserved0;

   uint8_t  red_mask, red_position;
   uint8_t  green_mask, green_position;
   uint8_t  blue_mask, blue_position;
   uint8_t  rsv_mask, rsv_position;
   uint8_t  directcolor_attributes;

   uint32_t physbase;
   uint32_t reserved1;
   uint16_t reserved2;
} __attribute__ ((packed)) vbe_info_t;

typedef struct {
   uint32_t size;
   uint64_t base_addr;
   uint64_t length;
   uint32_t type;
} __attribute__ ((packed)) mboot_memmap_t;

_________________
"Out of memory: Please memorize the following numbers and type them back in when asked for page number 42". - linguofreak

"Quote me in your forum signature" - Sortie (Check!)


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Tue Aug 16, 2016 8:36 am 
Offline
User avatar

Joined: Tue Jun 21, 2016 6:41 am
Posts: 21
---I think I see what you mean. I just memcpy the entire map directly into my array. I know the GRUB2 specs say that it is possible for a map entry to be a different size, but in my experience, it's impossible. The offset of 4 only matters to you if you are going through each entry one by one. I don't know how I would go about doing that - Like I said, I just copy the whole thing directly into an array.

_________________
"Out of memory: Please memorize the following numbers and type them back in when asked for page number 42". - linguofreak

"Quote me in your forum signature" - Sortie (Check!)


Last edited by michaellangford on Thu Aug 18, 2016 10:22 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Tue Aug 16, 2016 2:29 pm 
Offline

Joined: Thu Nov 08, 2012 2:59 am
Posts: 15
but how do you get the number of entries. when I try, I keep getting an error saying that the size of the array is not constant. for the record, I am using c++.
here's my code:
Code:
mmap_t *getmmap(multiboot_info_t* mbt)
{
   uint32_t i = 0;                  // initialize an iterator for the memory map array
   mmap_t *mmap = (mmap_t *)mbt->mmap_addr;            // initialize a memory map structure pointer and point it at the memory map
   static mmap_t memMap[mbt->length/sizeof(mmap_t)];            // initialize a memory map container array with enough entries for the memory map.   
   uint32_t MapLim = mbt->mmap_addr + mbt->mmap_length;   // defines the limit of the memory map
   while((uint32_t)mmap < MapLim)               // loop until we reach the end of the memory map
   {
      memMap[i].size = mmap->size;
      memMap[i].addr = mmap->addr;
      memMap[i].len = mmap->len;
      memMap[i].type = mmap->type;         // fill the entry in memMap with the contents of mmap
      i++;                  // increment the iterator
      mmap = (mmap_t *)
         ((uint32_t)mmap + mmap->size +
         sizeof(uint32_t));         // increment the memory map to the next entry.
   }
   return (mmap_t*)&memMap;               // returns the memory map.
}


I had to initialize the array to only 20 entries just to compile it.
the memcpy idea works well though. I'll have to adopt that.


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Tue Aug 16, 2016 3:59 pm 
Offline
Member
Member

Joined: Sat Nov 07, 2015 3:12 pm
Posts: 145
Please do not return references to things declared in a function.
Your error is simple: you cannot statically allocate something which size is dynamically known. You have no choice : declare a global map storage somewhere and make it big enough for all the entries.


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Tue Aug 16, 2016 8:49 pm 
Offline

Joined: Thu Nov 08, 2012 2:59 am
Posts: 15
got it to work. declared the memory map array in main and passed a pointer to it.\

edit: I took a picture of my memory map output that was printed to screen and attached it below.
This was done on an x86 dell laptop that's about 7-8 years old.
can anyone tell me if my memory map is sane, and/or what to do about the overlapping areas?

Image


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Wed Aug 17, 2016 1:31 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5134
That memory map doesn't look sane. Are you sure you're displaying the right number of entries? Can you verify it against something else (e.g. Linux dmesg)?

Once you have a sane memory map, you may still have overlaps. Overlapping areas of the memory map should be counted as whichever memory type is the most restrictive. For example, when type 1 (usable) and type 2 (reserved by hardware) overlap, the overlapping area should be counted as type 2.


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Thu Aug 18, 2016 10:25 am 
Offline
User avatar

Joined: Tue Jun 21, 2016 6:41 am
Posts: 21
BringerOfShadows wrote:
but how do you get the number of entries. when I try, I keep getting an error saying that the size of the array is not constant.


I get the number of entries from the multiboot header, and then declare the array locally, later, when you have a memory manager, you can allocate space for a permanent container. Hope that helps!

_________________
"Out of memory: Please memorize the following numbers and type them back in when asked for page number 42". - linguofreak

"Quote me in your forum signature" - Sortie (Check!)


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Thu Aug 18, 2016 10:23 pm 
Offline

Joined: Thu Nov 08, 2012 2:59 am
Posts: 15
How did you get the number of entries from the multiboot header? Where is that?


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Fri Aug 19, 2016 12:54 am 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
BringerOfShadows wrote:
How did you get the number of entries from the multiboot header? Where is that?


If you want to get the number of entries just count the by hand. You cannot code that because you don't know if the compiler is going the add some padding or not. Why would you want to do that anyways? Just let GRUB parse the information to your structure instance and then get information from that instance. Like for example: "mboot->mem_upper", etc...

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: GRUB memory map
PostPosted: Fri Aug 19, 2016 2:12 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5134
BringerOfShadows wrote:
How did you get the number of entries from the multiboot header? Where is that?

It's not in the multiboot header. GRUB only tells you how big the memory map is, not how many entries there are.

octacone wrote:
Like for example: "mboot->mem_upper", etc...

You need the memory map to find all available RAM. This only reports contiguous RAM above 1MB, which can be a lot less than the total.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 169 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group