Page 1 of 1
Multiboot HigherHalfBareBones
Posted: Sun Oct 16, 2005 12:53 pm
by LasLego
Hi all,
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?:
Code: Select all
[BITS 32]
[GLOBAL entry]
[EXTERN _main]
MODULEALIGN equ 1<<0
MEMINFO equ 1<<1
FLAGS equ 0x10000
MAGIC equ 0x1BADB002
CHECKSUM equ -(MAGIC + FLAGS)
KERNEL_VIRTUAL_BASE equ 0xC0000000
KERNEL_PAGE_NUMBER equ (KERNEL_VIRTUAL_BASE >> 22)
[SECTION .data]
align 0x1000 ; Align to 4k
BootPageDirectory:
dd 0x00000083
times (KERNEL_PAGE_NUMBER - 1) dd 0
dd 0x00000083
times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0
[SECTION .text]
align 4
MultiBootHeader:
dd MAGIC
dd FLAGS
dd CHECKSUM
STACKSIZE equ 0x4000 ; That is 16k
entry:
mov ecx, (BootPageDirectory - KERNEL_VIRTUAL_BASE)
mov cr3, ecx
mov ecx, cr4
or ecx, 0x00000010
mov cr4, ecx
mov ecx, cr0
or ecx, 0x80000000
mov cr0, ecx
lea ecx, [HHStart]
jmp ecx
HHStart:
mov dword [BootPageDirectory], 0
invlpg [0]
mov esp, _sys_stack+STACKSIZE
push ebx
push eax
call _main
hlt
; Reserve the stack
[SECTION .bss]
resb 8192
_sys_stack:
My main function looks like this:
void main(unsigned int multiboot_check, LP_MULTIBOOT_INFO info)
LP_MULTIBOOT_INFO is a structure containing the multiboot info.
Thanks in advance!
Greetings
LasLego
Re:Multiboot HigherHalfBareBones
Posted: Sun Oct 16, 2005 2:06 pm
by Colonel Kernel
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.
Re:Multiboot HigherHalfBareBones
Posted: Sun Oct 16, 2005 5:40 pm
by AR
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.
Re:Multiboot HigherHalfBareBones
Posted: Sun Oct 16, 2005 7:03 pm
by Xardfir
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.
Re:Multiboot HigherHalfBareBones
Posted: Sun Oct 16, 2005 9:36 pm
by AR
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.
Re:Multiboot HigherHalfBareBones
Posted: Mon Oct 17, 2005 1:18 am
by Colonel Kernel
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...
Re:Multiboot HigherHalfBareBones
Posted: Sat Nov 05, 2005 2:10 am
by Colonel Kernel
/bump
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).
Re:Multiboot HigherHalfBareBones
Posted: Sat Nov 05, 2005 4:14 am
by AR
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.