Setting up x86-64 Higher Half Kernel
Posted: Fri May 26, 2017 10:20 am
Hi!
I am currently trying to put my kernel into virtual higher half. When i am trying to jump from the lower half into the higher half, i get a tripple fault exactly after the jump.
The base address for the kernel should be 0xFFFF FF00 0000 0000 (=HVMA). The PML4 is located at 0x7E0 0000 (+ HVMA).
Because i don't want to paste all of the connected code pieces, it is online at https://github.com/MathiLpHD/MOS/ in the folder system/kernel/
The main files are makefile, linker.ld and src/init/boot.asm
Also, what does -mcmodel=kernel do? And how can i change the datamodel to allow 64-Bit addresses? Or would it be better to move ctors and so on into the text section?
The main Codepieces in boot.asm are:
and:
I am currently trying to put my kernel into virtual higher half. When i am trying to jump from the lower half into the higher half, i get a tripple fault exactly after the jump.
The base address for the kernel should be 0xFFFF FF00 0000 0000 (=HVMA). The PML4 is located at 0x7E0 0000 (+ HVMA).
Because i don't want to paste all of the connected code pieces, it is online at https://github.com/MathiLpHD/MOS/ in the folder system/kernel/
The main files are makefile, linker.ld and src/init/boot.asm
Also, what does -mcmodel=kernel do? And how can i change the datamodel to allow 64-Bit addresses? Or would it be better to move ctors and so on into the text section?
The main Codepieces in boot.asm are:
Code: Select all
mov edi, 0x7E00000 ; Set the destination index to 0x7E00000.
mov cr3, edi ; Set control register 3 to the destination index.
xor eax, eax ; Nullify the A-register.
mov ecx, 4096 ; Set the C-register to 4096.
rep stosd ; Clear the memory.
mov edi, cr3 ; Set the destination index to control register 3.
mov DWORD [edi], 0x7E01003 ; Set the uint32_t at the destination index to 0x7E01003.
mov ebx, 0x00000083 ; Set the B-register to 0x000000083. 0x83 = PS = 1 (=> 1GiB Page) R/W = 1, P = 1
add edi, 0x1000 ; Add 0x1000 to the destination index.
mov DWORD [edi], ebx ; Set the uint32_t at the destination index to the B-register.
mov edi, 0x7FFE000 ; Set the destination index to 0x1000.
mov DWORD [edi], 0x7E01003 ; Set the uint32_t at the destination index to 0x7E01003. This is for HVMA
add edi, 0x1000 ; Add 0x1000 to the destination index.
mov DWORD [edi], 0x7E00003 ; Set the uint32_t at the destination index to 0x7E00003. This is for recrusive mapping
Code: Select all
lgdt [GDT64.Pointer] ; Load the 64-bit global descriptor table.
mov ax, 0x10
mov ss, ax
mov ax, 0x0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
jmp GDT64.Code:.trampoline ; Set the code segment and enter 64-bit long mode.
.NoLongMode:
cli
hlt
[BITS 64]
.trampoline:
; enter the higher half
mov rax, QWORD .Realm64
jmp rax
[section .inith]
.Realm64:
cli ; Clear the interrupt flag.
mov rax, [GDT64.Pointer + 2]
mov rbx, HVMA
add rax, rbx
mov [GDT64.Pointer + 2], rax
mov rax, GDT64.Pointer + HVMA
lgdt [rax]