Page 1 of 1
Using GRUB's memory info
Posted: Sun Jun 03, 2007 8:04 am
by Bughunter
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?
Posted: Sun Jun 03, 2007 10:11 am
by jnc100
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).
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:It is the operating system's responsibility to avoid overwriting this memory until it is done using it.
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).
Regards,
John.
Posted: Sun Jun 03, 2007 10:28 am
by Bughunter
I don't like to rely on undefined behaviour and I'm not going to assume it's loaded under 1MB. I think I'm going to copy it, even if it takes up 0.0000000234 seconds (or whatever)
![Smile :)](./images/smilies/icon_smile.gif)
Posted: Sun Jun 03, 2007 10:35 am
by jnc100
bughunter wrote:I think I'm going to copy it
The one thing you have to remember if you do that is to patch up the pointers, which I just noticed I forgot to do for the mmap_addr entry
Quickly changes it...
Posted: Sun Jun 03, 2007 11:16 am
by Bughunter
I don't yet use the mmap, but yep of course it needs to be changed too, easy to forget yep
I made an unfinished starter kernel in ASM but I'm much more using C lately and I am now spending some free hours on building a C kernel
![Wink :wink:](./images/smilies/icon_wink.gif)
Posted: Sun Jun 03, 2007 12:19 pm
by Colonel Kernel
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.
![Mad :x](./images/smilies/icon_mad.gif)
Posted: Sun Jun 03, 2007 12:25 pm
by Bughunter
Hmm, you can make a typedef structure for the Multiboot information structure and use sizeof()? Or am I wrong?
Posted: Sun Jun 03, 2007 12:31 pm
by Colonel Kernel
bughunter wrote:Hmm, you can make a typedef structure for the Multiboot information structure and use sizeof()? Or am I wrong?
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).
Posted: Sun Jun 03, 2007 12:32 pm
by jnc100
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.
Posted: Sun Jun 03, 2007 12:48 pm
by Bughunter
Ah I see, sorry I didn't look that close yet at each individual field in the structure.
I'd be proponent of having the whole thing at a known physical address.