summaryrefslogtreecommitdiff
path: root/src/asm/boot.asm
blob: ae68761eb037a8e1b3d5093ef41110470e0836ca (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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
[BITS 32]

; Declare constants for the multiboot header.
MBALIGN  equ  1 << 0            ; align loaded modules on page boundaries
MEMINFO  equ  1 << 1            ; provide memory map
MBFLAGS  equ  MBALIGN | MEMINFO ; this is the Multiboot 'flag' field
MAGIC    equ  0x1BADB002        ; 'magic number' lets bootloader find the header
CHECKSUM equ -(MAGIC + MBFLAGS)   ; checksum of above, to prove we are multiboot
 
; Declare a multiboot header that marks the program as a kernel. These are magic
; values that are documented in the multiboot standard. The bootloader will
; search for this signature in the first 8 KiB of the kernel file, aligned at a
; 32-bit boundary. The signature is in its own section so the header can be
; forced to be within the first 8 KiB of the kernel file.
section .multiboot
align 4
	dd MAGIC
	dd MBFLAGS
	dd CHECKSUM

section .bootstrap

present	equ 1 << 7
not_sys	equ 1 << 4
exec	equ 1 << 3
cd		equ 1 << 2
rw		equ 1 << 1
access	equ 1 << 0

gran_4k	equ 1 << 7
sz_32	equ 1 << 6
long_m	equ 1 << 5

global gdt.ptr
gdt:
.null: equ $ - gdt
	dq 0
.code: equ $ - gdt
	dd 0xffff
	db 0
	db present | not_sys | exec | rw
	db gran_4k | long_m | 0xf
	db 0
.data: equ $ - gdt
	dd 0xffff
	db 0
	db present | not_sys | rw
	db gran_4k | sz_32 | 0xf
	db 0
.ptr:
	dw $ - gdt - 1
	dq gdt

global bootstrap
bootstrap:

	mov dword [multiboot_magic], eax
	mov dword [multiboot_header], ebx

	mov eax, cr0
	and eax, ~(1 << 31)
	mov cr0, eax

	mov edi, pml4 ;0x1000
	mov cr3, edi
	xor eax, eax
	mov ecx, 1024
	rep stosd

	mov edi, 0x2000
	mov ecx, 4096
	rep stosd

	mov edi, cr3

	mov dword [edi], 0x2003
	mov edi, 0x2000
	mov dword [edi], 0x3003
	add edi, 0x1000
	mov dword [edi], 0x4003
	mov dword [edi + 8], 0x5003
	add edi, 0x1000

	mov ebx, 0x00000003
	mov ecx, 512

.set_entry:
	mov dword [edi], ebx
	add ebx, 0x1000
	add edi, 8
	loop .set_entry

	mov edi, 0x5000
	mov ecx, 512

.set_entry_2:
	mov dword [edi], ebx
	add ebx, 0x1000
	add edi, 8
	loop .set_entry_2

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

	mov ecx, 0xc0000080
	rdmsr
	or eax, 1 << 8 | 1 << 0
	wrmsr

	mov eax, cr0
	or eax, 1 << 31
	mov cr0, eax

	lgdt [gdt.ptr]

	mov ax, gdt.data
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ss, ax

	extern start
	jmp gdt.code:start

global set_pml4
set_pml4:
	mov ecx, 0xC000080
	rdmsr
	and eax, ~(1 << 8)
	wrmsr

	mov eax, cr0
	and eax, ~(1 << 31)
	mov cr0, eax

	mov cr3, edi

	mov ecx, 0xC000080
	rdmsr
	or eax, 1 << 8
	wrmsr

	mov eax, cr0
	or eax, 1 << 31
	mov cr0, eax

	retf

section .data
align 16
global multiboot_header
multiboot_header: dq 0
global multiboot_magic
multiboot_magic: dq 0

section .bss
global pml4
align 4096
pml4: resq 512