Nessphoro wrote:
But I think you did something wrong - or using old grub.
I was indeed using a 2 years old version of qemu (qemu -kernel kernel.bin). I updated and it solved my problem, thank you
However I can't get my kernel to jump on the higher-half. I know you guys don't like these "find my bug" requests, but I'm a bit desperate and I've run out of ideas on how to debug.
Identity mapping seems OK since I don't crash after enabling paging, but a triple-fault is raised at the next jump. I suspect my higher-half mapping is wrong, but I went over it dozens of times and it seems correct to me.
Code: Select all
; multiboot
MBOOT_FLAG_MEMALIGN equ (1<<0) ; load kernel on a page boundary
MBOOT_FLAG_MEMINFO equ (1<<1) ; provide memory information
MBOOT_HDR_MAGIC equ 0x1BADB002
MBOOT_HDR_FLAGS equ (MBOOT_FLAG_MEMALIGN|MBOOT_FLAG_MEMINFO)
MBOOT_HDR_CHECKSUM equ -(MBOOT_HDR_MAGIC + MBOOT_HDR_FLAGS)
[BITS 32]
[GLOBAL mboot]
[GLOBAL start]
SECTION .text.multiboot
ALIGN 4
multiboot_header:
dd MBOOT_HDR_MAGIC
dd MBOOT_HDR_FLAGS
dd MBOOT_HDR_CHECKSUM
KERNEL_VMA_BASE equ 0xc0000000
[EXTERN __kernel_start]
[EXTERN __kernel_end]
SECTION .text.start
start:
cli
; Enable PSE
mov eax, cr4
or eax, 0x10
mov cr4, eax
; Identity mapping with PSE
mov eax, 0|0x83 ; PSE + present + rw
mov [pagedirectory - KERNEL_VMA_BASE], eax
; Higher half mapping
mov eax, 0x03 + pagetable0 - KERNEL_VMA_BASE
mov [pagedirectory - KERNEL_VMA_BASE + (0xc0100000 >> 22)], eax
; Map the kernel
mov eax, pagetable0 - KERNEL_VMA_BASE ; virtual address
mov ebx, __kernel_start
mov ecx, __kernel_end
mov esi, KERNEL_VMA_BASE
.mapkernel:
mov edx, ebx ; physical address
sub edx, esi
or edx, 0x03
mov [eax], edx
add eax, 0x04
add ebx, 0x1000
cmp ebx, ecx
jne .mapkernel
; Install page-directory
mov eax, pagedirectory - KERNEL_VMA_BASE
mov cr3, eax
; Enable paging
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
; OK here
mov eax, callmain
jmp eax ; <-- KO
[EXTERN kmain]
callmain:
jmp $
SECTION .bss nobits
[GLOBAL pagedirectory]
pagedirectory: resb 0x1000
pagetable0: resb 0x1000
Code: Select all
ENTRY (start)
KERNEL_VMA_BASE = 0xc0000000;
SECTIONS
{
. = 0x00100000;
. += KERNEL_VMA_BASE;
__kernel_start = ALIGN(0x1000);
.text ALIGN(0x1000) : AT(ADDR(.text) - KERNEL_VMA_BASE)
{
*(.text.multiboot)
*(.text.start)
*(.text)
}
.rodata ALIGN (0x1000) : AT(ADDR(.rodata) - KERNEL_VMA_BASE)
{
*(.rodata)
}
.data ALIGN(0x1000) : AT(ADDR(.data) - KERNEL_VMA_BASE)
{
*(.data)
}
.bss ALIGN(0x1000) : AT(ADDR(.bss) - KERNEL_VMA_BASE)
{
*(.bss)
}
__kernel_end = ALIGN (0x1000);
}
It is meant to do the same thing as described here:
http://wiki.osdev.org/Higher_Half_Kerne ... Bootloader except that I used PSE to identity map.