summaryrefslogtreecommitdiff
path: root/src/bootloader/enter_kernel.asm
blob: c9991e352243c0c1080b82fb8fb8a2cf174d5bfb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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