summaryrefslogtreecommitdiff
path: root/src/bootloader/enter_kernel_backup
blob: 7631f20df1d89390716b7916b56f40a932538088 (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
81
82
83
84
85
86
87
[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, 0x3000 ; this is where our page tables will be
mov cr3, edi     
mov eax, 0      ; what we'll be putting there
mov ecx, 4096   ; how many times we'll put it there
rep stosd       ; kinda like memset(&edi, ecx, edi)
mov edi, cr3

mov DWORD [edi], 0x4003 ; pml4e[0] = pdpe
add edi, 0x1000
mov DWORD [edi], 0x5003 ; pdpe[0] = pde
add edi, 0x1000
mov DWORD [edi], 0x6003 ; pde[0] = pte
add edi, 0x1000

mov ebx, 0x00000003 ; the flags
mov ecx, 512; the loop counter, will map 2 mib

.idmap_pte_loop:
mov DWORD [edi], ebx
add ebx, 0x1000 ; physical address. Should leave us at 0x7000
add edi, 8      ; position in page table
loop .idmap_pte_loop

mov eax, cr4         
or eax, 1 << 5     
mov cr4, eax         

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