-
Notifications
You must be signed in to change notification settings - Fork 0
/
boot.s
275 lines (237 loc) · 4.96 KB
/
boot.s
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
.equiv MAGIC, 0xE85250D6
.section .multiboot
.global multiboot_header
.align 4
header_start:
.long MAGIC
.long 0
.long header_end - header_start
.long 0x100000000 - (MAGIC + 0 + (header_end - header_start))
multiboot_header:
tag_info_start:
.short 1
.short 0
.long tag_info_end - tag_info_start
.long 1
.long 2
.long 6
tag_info_end:
.align 8
console_tag_start:
.short 4
.short 0
.long console_tag_end - console_tag_start
.long 3 # means we support EGA/VGA console (if available)
console_tag_end:
.align 8
fb_tag_start:
.short 5
.short 1
.long fb_tag_end - fb_tag_start
.long 800 # width
.long 600 # height
.long 32 # bpp
fb_tag_end:
.align 8
end_tag:
.short 0
.short 0
.long header_end - end_tag
header_end:
.section .bootstrap_stack, "aw", @nobits
.align 0x1000
stack_bottom:
.skip 0x4000
stack_top:
.section .bootstrap_bss ,"aw", @nobits
.align 0x1000
paging_data_start:
pml4_table:
.skip 0x1000
boot_pdp:
.skip 0x1000
boot_page_directory:
.skip 0x1000
kernel_heap:
.skip 0x1000
kernel_pages:
.skip 0x1000
kernel_temp_pages:
.skip 0x1000
fb_pages:
.skip 0x4000
paging_data_end:
mbi_data:
.skip 0x1000
.code32
.section .bootstrap_text
.global bootstrap
.type bootstrap, @function
.align 8
bootstrap:
mov $stack_top, %esp
mov %esp, %ebp
call copy_mbi
call amd64_setup
ljmp $0x08, $_start_amd64
cli
1:
hlt
jmp 1b
.align 8
amd64_setup:
movl $boot_pdp, %eax
orl $0x3, %eax
movl $pml4_table, %edi
movl %eax, (%edi)
movl $0, 4(%edi)
movl $boot_page_directory, %eax
orl $0x3, %eax
movl $boot_pdp, %edi
movl %eax, (%edi)
movl $0, 4(%edi)
####################################################
# We can choose to map the 1st 1 GB to itself
# from here, but since it is not recommended,
# then I guess we better follow the suggestions.
#
# Because we decided to load the kernel at 0x100000,
# then using only 2 pages is enough for temporary
# identity mapping.
####################################################
mov $boot_page_directory, %edi
mov $0, %esi
mov $0, %ecx
1:
mov %esi, %eax
or $0x83, %eax
movl %eax, (%edi)
movl $0, 4(%edi)
add $0x200000, %esi
add $8, %edi
inc %ecx
cmp $2, %ecx
jne 1b
##########################################################
# Map Kernel Heap from 0xFFFFFFFF80000000 -> 0x0
# 1 GB
##########################################################
movl $kernel_heap, %eax
or $0x3, %eax
movl $(pml4_table + 511 * 8), %edi
movl %eax, (%edi)
movl $0, 4(%edi)
movl $kernel_pages, %eax
or $0x3, %eax
movl $(kernel_heap + 510 * 8), %edi
movl %eax, (%edi)
movl $0, 4(%edi)
movl $kernel_pages, %edi
movl $0, %esi
movl $0, %ecx
2:
movl %esi, %eax
orl $0x83, %eax
movl %eax, (%edi)
movl $0, 4(%edi)
add $8, %edi
add $0x200000, %esi
inc %ecx
cmp $512, %ecx
jne 2b
##########################################################
# Initialize a set of pages at even higher address space
# For kernel misc usage, but these are not initialized,
# the values are all 'not present'.
##########################################################
movl $kernel_temp_pages, %eax
or $0x3, %eax
movl $(kernel_heap + 511 * 8), %edi
movl %eax, (%edi)
movl $0, 4(%edi)
movl $pml4_table, %eax
movl %eax, %cr3
movl %cr4, %eax
orl $(1 << 5), %eax
movl %eax, %cr4
movl $0xc0000080, %ecx
rdmsr
or $(1 << 8), %eax
wrmsr
#########################################
# The most critical state.
# We actually enable paging, after this
# we can get crashed if some code above
# miscalculated.
#########################################
mov %cr0, %ecx
or $(1 << 31), %ecx
mov %ecx, %cr0
####################################################
# If everything was okay, then we should be able to
# load our gdt from here, then back to the caller,
# who will make the far jump into amd64 code.
####################################################
lgdt gdt_ptr
ret
.align 8
gdt64:
.quad 0 # always 0
gdt_code:
.short 0
.short 0
.byte 0
.byte 0b10011000
.byte 0b00100000
.byte 0
gdt_data:
.short 0
.short 0
.byte 0
.byte 0b10010010
.byte 0b00000000
.byte 0
gdt_ptr:
.short . - gdt64 - 1
.quad gdt64
.align 8
copy_mbi:
push %ebx
mov $mbi_data, %edi
mov %ebx, %eax
movl (%eax), %ecx
mov %eax, %esi
repnz movsb
xorl %eax, %eax
movl $4, %ecx
rep stosl
pop %ebx
ret
.code64
.extern kmain
.extern _bss
.extern kernel_vma
_start_amd64:
mov $0x10, %ax
mov %ax, %ss
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
################################################################
# Initialize AMD64 Kernel Stack to the correct virtual address
# don't use old Bootstrap's BSS anymore.
################################################################
movq $_bss, %rsp
movq %rsp, %rbp
################################################################
# Point mbi_data to correct map location, so the kernel use
# correct addressing for all variables.
################################################################
mov $mbi_data, %rdi
add $kernel_vma, %rdi
call kmain
cli
1:
hlt
jmp 1b