Using GRUB's memory info
Using GRUB's memory info
After my Multiboot stub has been loaded by GRUB, I enable paging and map the first 4MB and the 4MB at 0xC0000000 both to physical page 0.
Now my question is, can I use the address in EBX (the Multiboot information structure passed by GRUB) after I have enabled paging?
In the Multiboot specification I can't find any information regarding _WHERE_ in physical memory this Multiboot information structure resides.
In my case, it's under the 1MB mark, but is that undefined behaviour of GRUB or isn't it?
Now my question is, can I use the address in EBX (the Multiboot information structure passed by GRUB) after I have enabled paging?
In the Multiboot specification I can't find any information regarding _WHERE_ in physical memory this Multiboot information structure resides.
In my case, it's under the 1MB mark, but is that undefined behaviour of GRUB or isn't it?
Yes, it can end up anywhere. GRUB seems to define it as a static variable within grub's 'stage2', which is usually loaded below 1MB, at least on x86.Multiboot Specification wrote:The Multiboot information structure and its related substructures may be placed anywhere in memory by the boot loader (with the exception of the memory reserved for the kernel and boot modules, of course).
This is also important - do not overwrite it with page tables and the like! For this reason, I recommend either copying it somewhere safe that you know the address of (e.g. somewhere defined in your kernel) or getting all the information you need from it early. It is possible to access it after enabling paging. As you've found out, its normally below 1MB so you can just assume its mapped in your first 4MB and access it at the address that was initially in ebx. You might want to check it is mapped, however, and if not create a page table and map it (without overwriting it of course).Multiboot Specification wrote:It is the operating system's responsibility to avoid overwriting this memory until it is done using it.
Regards,
John.
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
My kernel copies the Multiboot info to a buffer in the kernel's data area and patches up all the pointers. The thing that annoyed me about doing this was that there is no real upper bound on the size of the Multiboot structures. I just had to allocate a fixed amount of space (1KB I think, but I could have chosen anything) and panic if it gets full while copying. Not that it's likely that the Multiboot structures will get that large, but it annoys me when specifications have big holes like this.
Top three reasons why my OS project died:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
That works fine for each individual piece of the overall structure, but there is no reasonable limit on the number of records that the memmap can contain, for example (probably also true for the device map, etc.). In practice, this is not a problem, but it would be nice to have some upper bound on the size of the structure. Better yet, if they put it all in a known region of physical memory, that would work too (then we wouldn't even have to copy it).bughunter wrote:Hmm, you can make a typedef structure for the Multiboot information structure and use sizeof()? Or am I wrong?
Top three reasons why my OS project died:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
Its not just the multiboot header - its all the other tables it references. For example, how much space do you reserve for the string table? How many memory map sections do you account for?
My values are:
mbheader - size of header
mbelf - 20 * sizeof(elf header) = 20 * 40
mbstr - 1000
mbmods - 40 * sizeof(mb module) = 40 * 16
mbmmap - 96 * sizeof(mmap struct) = 96 * 20
But they are just chosen rather arbritrarily, and as Colonel Kernel says, you just have to hope they're enough.
edit: and he just beat me to it
Regards,
John.
My values are:
mbheader - size of header
mbelf - 20 * sizeof(elf header) = 20 * 40
mbstr - 1000
mbmods - 40 * sizeof(mb module) = 40 * 16
mbmmap - 96 * sizeof(mmap struct) = 96 * 20
But they are just chosen rather arbritrarily, and as Colonel Kernel says, you just have to hope they're enough.
edit: and he just beat me to it
Regards,
John.