Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Here today I successfully modified my old lower-half kernel og work in higher-half, using the Higher Half BareBones guide as a starting point. Everything is now working perfectly, besides the multiboot info structure. I don't know how to map it in memory, because It doesn't have static location. Can anybody help me with modifying this code to pass the info structure over correctly?:
What a coincidence... I was just about to start working on that. If I have time today, that is... I'll let you know what I come up with -- hopefully it will be generic enough to incorporate back into HigherHalfBareBones.
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
As far as I can see, the easy way would be to identity map the low 1MB until you're done with it, but as Solar would state, there is no guarantee that it is actually there or if it is, that it will remain there in all future versions (as it isn't written in stone in the spec).
A better way would be to simply use the kernel split initalisation method or an intermediate bootloader to parse the multiboot info into the kernel's internal structures before activating paging.
The last way I can currently think of is rather inelegant, basically you map the multiboot info then follow each of the pointers one after the other and map in the seperate structs/arrays individually.
Has anyone ever actually had problems with accessing the multiboot info?
I simply take the mbt pointer and add the kernel base to it.
ie + 0xc0000000 with the kernel loaded at 0xc0010000. Works on a Pentium 2 333 a Pentium 4 1.5Ghz and BOCHS.
I would be interested to know if mapping is needed at all as the memory map information is supposed to be fully available in real mode via segmentation etc.
The location of the multiboot info is not guaranteed by the specification and IIRC, it has no real mode support outlined either. The memory map does not exist in memory, it is created by the BIOS through the use of the Get Memory Map API, being a real mode API does mean that it will need to be put below 1MB BUT again, the specification doesn't guarantee that it will stay there.
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). It is the operating system's responsibility to avoid overwriting this memory until it is done using it.
Mapping the low 1MB is to make assumptions that that is where the multiboot info is when it could conceivably be anywhere. Basically, it's a case of correctness vs simplicity.
AR wrote:The last way I can currently think of is rather inelegant, basically you map the multiboot info then follow each of the pointers one after the other and map in the seperate structs/arrays individually.
I've decided to do it that way. Actually, I've decided to at least walk the multiboot structure to see if any parts of it go past the first 4MB of physical address space and panic if they do. I can implement it properly later, as long as the design can easily handle the change...
Also, I'm only going to worry about mapping the parts of the Multiboot structure that my own OS cares about. So, no generic higher-half multiboot mapping from me I'm afraid. I'm leaving it as an exercise for the reader unless someone else steps up...
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
I've been working on this lately, and have run into a stumbling block.
AR wrote:A better way would be to simply use the kernel split initalisation method or an intermediate bootloader to parse the multiboot info into the kernel's internal structures before activating paging.
If you were to create such an intermediate bootloader, how would you design the kernel's internal structure to hold the result of parsing the multiboot info (let's call it BootLoaderInfo for the sake of discussion)? I'm thinking in particular about the memory map. If you use a list of free regions like the multiboot info structure does, then you don't know ahead of time how big your BootLoaderInfo structure must be, whereas if you use a bitmap you do know how big it must (maximally) be, but that's maybe a little too big (over 128KB for a 4GB physical address space, worse if you're using PAE).
On the other hand, if the size of BootLoaderInfo is fixed at design time, it might be easier to find a place to put it in memory where it won't trip over things like GRUB modules (including the kernel itself), and hypothetically at least, random chunks of the multiboot info structure itself. I really wish the Multiboot spec would say where the multiboot info structure can and cannot go in memory... it's making things pretty difficult when trying to design an algorithm to allocate memory for BootLoaderInfo (which must happen before there is even a physical memory manager running).
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
I was thinking along the lines of using the BSS for things you know will be a certain size, convert the rest of the multiboot info into internal formats then locate the memory map array. Once you know where the array is you can pick anywhere else to put the converted map data (avoiding the modules, of course).
There's a reasonably simple way to find a free region to put the memory info:
Sort modules list into ascending order
Look for sufficient space before and after modules
If not found then examine the gaps inbetween each module for sufficient space
If not found then try to rearrange the modules to create a large enough space
If that fails then panic, insufficient memory
(Be sure to include the memory map array, low 1MB and the loader itself as "fake modules" in the calculations [but you will want to ensure that the code doesn't try to move them on you])
Depending on your implementation, the rearranging may actually come first (to make space for the kernel image which would have been loaded as a module) which would allow you to just push that code a little further to create the additional required space.