Higher Half Kernel Problems

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.
Post Reply
tombee

Higher Half Kernel Problems

Post 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
Habbit

Re:Higher Half Kernel Problems

Post 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.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Re:Higher Half Kernel Problems

Post 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.
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
tombee

Re:Higher Half Kernel Problems

Post 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.
Post Reply