summaryrefslogtreecommitdiff
path: root/src/bootloader/enter_kernel.asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootloader/enter_kernel.asm')
-rw-r--r--src/bootloader/enter_kernel.asm80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/bootloader/enter_kernel.asm b/src/bootloader/enter_kernel.asm
new file mode 100644
index 0000000..c9991e3
--- /dev/null
+++ b/src/bootloader/enter_kernel.asm
@@ -0,0 +1,80 @@
+[extern main]
+[extern _kernel_stack_loc]
+enter_longmode:
+cli
+
+; TODO check if a20 is already set
+mov al, 0x92
+or al, 2
+out 0x92, al
+
+lgdt [protected_gdt.descriptor]
+mov eax, cr0
+or eax, 0x1
+mov cr0, eax
+
+mov eax, 0x8
+mov ds, eax
+
+jmp 0x8:init_longmode
+
+bits 32
+init_longmode:
+mov ebp, 0xffff
+mov esp, ebp
+mov ax, PROTECTED_DATA_SEGMENT
+mov ds, ax
+mov ss, ax
+mov es, ax
+mov fs, ax
+mov gs, ax
+
+mov edi, 0x4000 ; 0x3000
+mov cr3, edi
+mov eax, 0
+mov ecx, 0xc00 ; 0x1000
+rep stosd
+mov edi, cr3
+
+
+mov DWORD [edi], 0x5003 ; pml4e[0] = pdpe
+add edi, 0x1000
+mov DWORD [edi], 0x6003 ; pdpe[0] = pde
+add edi, 0x1000
+mov DWORD [edi], 0x83 ; pde[0] = pte
+
+mov eax, cr4
+or eax, 1 << 5
+mov cr4, eax
+
+;end of setting up pages
+
+mov ecx, 0xc0000080
+rdmsr
+or eax, 1 << 8
+wrmsr
+
+mov eax, cr0
+or eax, 1 << 31 | 1 << 0 ; this is where we set paging and protected mode (respectively)!
+mov cr0, eax
+
+
+mov ecx, 0xc0000080
+rdmsr
+or eax, 1 << 8
+wrmsr
+
+mov eax, cr0
+or eax, 1 << 31
+mov cr0, eax
+
+lgdt [long_gdt.descriptor]
+
+jmp LONG_CODE_SEGMENT:enter_kernel
+enter_kernel:
+bits 64
+mov rbp, _kernel_stack_loc
+mov rsp, _kernel_stack_loc
+call main ; where we actually call the kernel
+jmp $
+ret