Here is the process I use in my kernel (note that this is 32bit). In my bootstrap assembly file, I tell GRUB to provide me with a memory map:
.set MEMINFO, 1 << 1 # Get memory map from GRUB
Then, GRUB loads the address of the multiboot info structure into ebx
for you (this structure contains the address of the memory map). Then I call into C code to handle the actual iteration and processing of the memory map. I do something like this to iterate over the map:
/* Macro to get next entry in memory map */
#define MMAP_NEXT(m) \
(multiboot_memory_map_t*)((uint32_t)m + m->size + sizeof(uint32_t))
void read_mmap(multiboot_info_t* mbt){
multiboot_memory_map_t* mmap = (multiboot_memory_map_t*) mbt->mmap_addr;
/* Iterate over memory map */
while((uint32_t)mmap < mbt->mmap_addr + mbt->mmap_length) {
// process the current memory map entry
mmap = MMAP_NEXT(mmap);
}
}
where multiboot_info_t
and multiboot_memory_map_t
are defined as in the Gnu multiboot.h file. As Andrew Medico posted in the comments, here is a great link for getting started with this.