summaryrefslogtreecommitdiff
path: root/src/arch/amd64/boot.S
blob: 6482d796167ec99f192afb2789b4ab0c6661d8ce (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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
global start
global kernel_pml4
global kernel_pdpt_0
global kernel_pd_0
global kernel_pt_0
global paging_pt
global bootstrap_pt
extern kmain
extern amd64_shim
bits 32

section .multiboot
align 8
mb_start:
; header
dd 0xe85250d6
dd 0
dd mb_end - mb_start
dd 0x100000000 - (0xe85250d6 + (mb_end - mb_start))
; null tag
dw 0
dw 0
dd 8
;
mb_end:

section .bss
align 4096
kernel_pml4:			; reserve memory for initial 512 pml4 entires
	resb 4096
kernel_pdpt_0:			; reserve memory for initial 512 pdpt entires
	resb 4096
kernel_pd_0:			; reserve memory for initial 512 pd entries
	resb 4096
kernel_pt_0:			; reserve memory for initial 512 pt entries
	resb 4096
paging_pt:				; reserve pages for pager mappings
	resb 4096
bootstrap_pt:			; reserve pages to bootstrap pager
	resb 4096

align 16
stack_start:
	resb 16384
stack_end:

section .rodata
align 16
; Access bits
PRESENT        equ 1 << 7
NOT_SYS        equ 1 << 4
EXEC           equ 1 << 3
DC             equ 1 << 2
RW             equ 1 << 1
ACCESSED       equ 1 << 0
 
; Flags bits
GRAN_4K       equ 1 << 7
SZ_32         equ 1 << 6
LONG_MODE     equ 1 << 5
 
GDT:
    .Null: equ $ - GDT
        dq 0
    .Code: equ $ - GDT
        dd 0xFFFF                                   ; Limit & Base (low, bits 0-15)
        db 0                                        ; Base (mid, bits 16-23)
        db PRESENT | NOT_SYS | EXEC | RW            ; Access
        db GRAN_4K | LONG_MODE | 0xF                ; Flags & Limit (high, bits 16-19)
        db 0                                        ; Base (high, bits 24-31)
    .Data: equ $ - GDT
        dd 0xFFFF                                   ; Limit & Base (low, bits 0-15)
        db 0                                        ; Base (mid, bits 16-23)
        db PRESENT | NOT_SYS | RW                   ; Access
        db GRAN_4K | SZ_32 | 0xF                    ; Flags & Limit (high, bits 16-19)
        db 0                                        ; Base (high, bits 24-31)
    .TSS: equ $ - GDT
        dd 0x00000068
        dd 0x00CF8900
    .Pointer:
        dw $ - GDT - 1
        dq GDT

section .text
align 8
start:
	cli
	mov esp, stack_end
	mov ebp, stack_end

	push DWORD 0
	push ebx

	mov edi, 0x1000
	mov cr3, edi
	xor eax, eax
	mov ecx, 4096
	rep stosd
	mov edi, cr3

	mov DWORD [edi], kernel_pdpt_0 + 3      ; Set the uint32_t at the destination index to 0x2003.
	mov edi, kernel_pdpt_0                  ; Add 0x1000 to the destination index.
	mov DWORD [edi], kernel_pd_0 + 3        ; Set the uint32_t at the destination index to 0x3003.
	mov edi, kernel_pd_0                    ; Add 0x1000 to the destination index.
	mov DWORD [edi], kernel_pt_0 + 3        ; Set the uint32_t at the destination index to 0x4003.
	mov edi, kernel_pt_0                    ; Add 0x1000 to the destination index.

	mov ebx, 0x00000003          ; Set the B-register to 0x00000003.
	mov ecx, 512                 ; Set the C-register to 512.
 
.SetEntry:
	mov DWORD [edi], ebx         ; Set the uint32_t at the destination index to the B-register.
	add ebx, 0x1000              ; Add 0x1000 to the B-register.
	add edi, 8                   ; Add eight to the destination index.
	loop .SetEntry               ; Set the next entry.

	;push ebx                ; Call our function to set up basic paging
	;call amd64_shim


	mov eax, cr4            ; Enable the PAE bit
	or eax, 1 << 5
	mov cr4, eax

	mov ecx, 0xC0000080     ; Enable long mode
	rdmsr
	or eax, 1 << 8
	wrmsr

	mov eax, cr0            ; Enable paging
	or eax, 1 << 31
	mov cr0, eax

	lgdt [GDT.Pointer]
	jmp GDT.Code:code64

	bits 64
code64:
	pop rdi
	call amd64_shim
	mov rdi, rax
	call kmain
	cli
halt:
	hlt
	jmp halt