Page 1 of 1

Higher Half Kernel Problems

Posted: Wed Aug 30, 2006 10:17 am
by tombee
Hey,

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.

Code: Select all

[BITS 32]

global start

MULTIBOOT_PAGE_ALIGN   equ 1 << 0
MULTIBOOT_MEMORY_INFO  equ 1 << 1
MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO
MULTIBOOT_HEADER_MAGIC equ 0x1badb002
MULTIBOOT_CHECKSUM     equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

KERNEL_VIRTUAL_BASE    equ 0xc0000000
KERNEL_PAGE_NUMBER     equ (KERNEL_VIRTUAL_BASE >> 22)

section .data
align 0x1000

bootpagedirectory:
   dd 0x00000083
   times (KERNEL_PAGE_NUMBER - 1) dd 0

   dd 0x00000083
   times (1024 - KERNEL_PAGE_NUMBER - 1) dd 0

section .text
align 0x1000
multibootheader:
   dd MULTIBOOT_HEADER_MAGIC
   dd MULTIBOOT_HEADER_FLAGS
   dd MULTIBOOT_CHECKSUM

STACKSIZE equ 0x4000

start:
   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, [startinhigherhalf]
   jmp ecx

startinhigherhalf:
   mov dword [bootpagedirectory], 0
   invlpg [0]

   mov esp, _sys_stack + STACKSIZE

   push eax
   push ebx

   extern kernel_main
   call kernel_main
   hlt

section .bss
align 0x8000
   resb STACKSIZE
_sys_stack:
Thanks, TomB

Re:Higher Half Kernel Problems

Posted: Wed Aug 30, 2006 10:56 am
by Habbit
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.

Re:Higher Half Kernel Problems

Posted: Wed Aug 30, 2006 12:04 pm
by Colonel Kernel
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:

Code: Select all

    ; 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.

Re:Higher Half Kernel Problems

Posted: Wed Aug 30, 2006 3:40 pm
by tombee
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.
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.