Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
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.
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.
---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.
Last edited by michaellangford on Thu Aug 18, 2016 10:22 am, edited 1 time in total.
"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!)
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:
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.
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.
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?
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.
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!)
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