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.
I am trying to convert my current kernel into a higher half kernel, following the page from the OS-FAQ. Although when I try to use the multiboot info struct members, my kernel page faults. I think this could be a problem with my start.asm, but I am not sure. Below is a copy of my start.asm, any help would be appreciated.
IIRC, the Multiboot specification states that EAX will contain the magic number (whatever), EBX will contain a pointer to the Multiboot info structure and the other registers are undefined.
I assume you're talking about the structure pointed to by EBX. In that case, some things you'd like to check are:
Are you pushing the arguments to kernel_main in the right order? When passing arguments to a C/C++ function, you must start by the last (rightmost) argument. So if you do [tt]push eax[/tt] and then [tt]push ebx[/tt], your kernel_main function should be like this: [tt]void kernel_main(MultibootInfo* mbinfo, uint32_t mbmagic)[/tt], where MultibootInfo is your info struct.
EBX contains a pointer to the Multiboot structure. GRUB does not know how are you managing paging, so the pointer it gives you uses a physical address. You are removing identity mapping with [tt]mov dword [bootpagedirectory], 0[/tt], so you need to offset the pointer. An [tt]add ebx, KERNEL_VIRTUAL_BASE[/tt] before pushing ebx will do the trick.
By the way, you have to offset all other pointers within the structure if you want to use them, but that I let to the C code.
Habbit wrote:EBX contains a pointer to the Multiboot structure. GRUB does not know how are you managing paging, so the pointer it gives you uses a physical address. You are removing identity mapping with [tt]mov dword [bootpagedirectory], 0[/tt], so you need to offset the pointer. An [tt]add ebx, KERNEL_VIRTUAL_BASE[/tt] before pushing ebx will do the trick.
By the way, you have to offset all other pointers within the structure if you want to use them, but that I let to the C code.
In fact, there is a warning about this in the tutorial code:
; pass Multiboot info structure -- WARNING: This is a physical address and may not be
; in the first 4MB!
push ebx
In my own kernel, I ended up solving this by copying the structure into a known location in the kernel's .bss and updating all the pointers in the structure accordingly.
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
EBX contains a pointer to the Multiboot structure. GRUB does not know how are you managing paging, so the pointer it gives you uses a physical address. You are removing identity mapping with [tt]mov dword [bootpagedirectory], 0[/tt], so you need to offset the pointer. An [tt]add ebx, KERNEL_VIRTUAL_BASE[/tt] before pushing ebx will do the trick.
Thanks this is the one which solved my problem, this problem had me banging my head against the desk for a couple of days. Thanks again.