gaf
User
 Platinum Osdever
| Posts: 153 |  | Karma: 10
|
Re: take ammount of ram with grub - 2005/10/30 09:35
Hello, the FAQ entry assumes that you're already using a kernel compatible with GRUB. In case that yours doesn't support the multiboot specifications you should thus first have a look at the BareBones tutorial the article links to. To get the memory map you first have to locate the multiboot structure whose address is stored in ebx when GRUB passes control to your operating system. The BareBone kernel pushes the contents of the register on the stack before calling main() so that the address of the multiboot info structure is supplied as a parameter to the kernel's entry procedure.
| Code: | main (multiboot_info_t* mbd, unsigned int magic); |
The multiboot_info_t structure is defined in multiboot.h (can also be found on in the FAQ) which has to be linked with your kernel. To read out the amount of system memory the FAQ describes two methodes. The first is to check if bit0 of mbr->flags is zero and then (provided that it is) to read out mbd->lower and mbr->upper to get conventional and extended memory size. The avantage of the approch is its simplicity but unfortunately it doesn't provide a way to detect memory holes. This means that the values only describe the memory up to the first hole and that there might be more after the hole that you just can't detect like that.
| Code: | main (multiboot_info_t* mbd, unsigned int magic)
{
long conventinal memory = 0, extended_memory = 0;
if(mbd->flags^1)
{
conventional_memory = mbd->lower_mem;
extended_memory = mbd->upper_mem;
}
else
{
printf("GRUB couldn't detect memory\\n");
if(!ProbeMemoryDirectly())
panic();
}
} |
The second approach is to use the GRUB memory map which is basically a table of structures that each describe an extend of memory. To use this methode one first has to make sure that GRUB was able to detect the BIOS memory map by checking if bit6 of mbd->flags is set. To access the map mbd->mmap_addr and mbr->mmap_length have to be used which define the start address and the size in bytes of the table. Each of the table's elements is a memory_map strucure as defined in multiboot.h whose size is (memory_map.size+4) as the size field is not considered to be a part of the structure. The code snipped at the end of the FAQ aricle shows how the memory map can be accessed by demonstrating how to calculate the overall memory size:
- The address of the buffer is stored in mbd->mmap_addr
- Each node has a size of (mbr->mmap_addr.size+4)
- There are (mbr->mmap_lenght/(mbr->mmap_addr.size+4)) nodes
regards,
gaf
|