5
5
STACKSIZE: equ 65536
6
6
7
7
; 512 GB maximum RAM size for page table
8
- ; DON'T MODIFY THIS UNLESS YOU UPDATE THE setup_paging accordingly
8
+ ; DON'T MODIFY THIS UNLESS YOU UPDATE THE setup_paging accordingly.
9
+ ; IMPORTANT! regardless of the initial mapping size, we limit the phy memory to
10
+ ; 64GB in the actual paging, so that all kernel VMAs could fit into one pml4
11
+ ; entry and one pdp (level 3) table. See docs/mem_layout.txt
12
+
9
13
MAX_MEM: equ 512
10
14
11
15
; be careful with the extern and exported symbols when mapping a higher-half
@@ -23,8 +27,8 @@ MAX_MEM: equ 512
23
27
[GLOBAL mb_info_addr]
24
28
; functions from other parts of rustubs
25
29
[EXTERN _entry]
26
- [EXTERN ___BSS_START__ ]
27
- [EXTERN ___BSS_END__ ]
30
+ [EXTERN ___BSS_PM_START__ ]
31
+ [EXTERN ___BSS_PM_END__ ]
28
32
29
33
[SECTION .text]
30
34
@@ -68,16 +72,16 @@ setup_paging:
68
72
; zero out the initial page tables (2 pages in total)
69
73
mov edi , pml4
70
74
clear_pt:
71
- mov byte [ edi ], 0
72
- inc edi
75
+ mov dword [ edi ], 0
76
+ add edi , 4
73
77
cmp edi , pt_end
74
- jne clear_pt
78
+ jl clear_pt
75
79
76
80
; Provisional identical page mapping, using 1G huge page, therefore only 2
77
81
; table levels needed. see docs/x86_paging.txt
78
82
79
83
; PML4 (Page Map Level 4 / 1st level)
80
- mov eax , pdp
84
+ mov eax , pdp0
81
85
or eax , 0xf
82
86
mov dword [ pml4 + 0 ], eax
83
87
mov dword [ pml4 + 4 ], 0
@@ -89,8 +93,8 @@ fill_tables2:
89
93
; fill one single PDP table, with 1G pages, 512 PDPE maps to 512 GB
90
94
cmp ecx , MAX_MEM
91
95
je fill_tables2_done
92
- mov dword [ pdp + 8 * ecx + 0 ], eax ; low bytes
93
- mov dword [ pdp + 8 * ecx + 4 ], ebx ; high bytes
96
+ mov dword [ pdp0 + 8 * ecx + 0 ], eax ; low bytes
97
+ mov dword [ pdp0 + 8 * ecx + 4 ], ebx ; high bytes
94
98
add eax , 0x40000000 ; 1G per page
95
99
adc ebx , 0 ; overflow? -> increment higher-order half of the address
96
100
inc ecx
@@ -115,32 +119,74 @@ activate_long_mode:
115
119
; jump to 64-bit code segment -> full activation of Long Mode
116
120
jmp 2 * 0x8 : longmode_start
117
121
122
+
123
+ ; =====================================================================
124
+ ; MUST NOT USE ANY 64 BIT SYMBOLS BEFORE THIS POINT!
125
+ ; may include:
126
+ ; - symbols defined in 64 bit code below, if mapped to higher memory (VA)
127
+ ; - all symbols exported from rust code or linker script
128
+ ; =====================================================================
129
+
118
130
[BITS 64]
119
- ; system start, part 2 (in 64-bit Long Mode)
120
131
longmode_start:
121
- mov rdi , ___BSS_START__
132
+ ; now we set the pagetables for higher half memory
133
+ ; since we have Provisional paging now, why not using 64bit code?
134
+ mov eax , pdp1
135
+ or eax , 0xf
136
+ mov dword [ pml4 + 256 ], eax
137
+ mov dword [ pml4 + 256 + 4 ], 0
138
+ ; PDPE flags, see above
139
+
140
+ ; entry 0~63 is an identical mapping with offset 0x8000_0000_0000
141
+ ; clear the BSS section before going to rust code
142
+ ; TODO this should not be executable
143
+ mov rax , 0x0
144
+ or rax , 0x87
145
+ mov rdi , 0
146
+ fill_kvma1:
147
+ mov qword [ pdp1 + 8 * rdi ], rax
148
+ inc rdi
149
+ add rax , 0x40000000
150
+ cmp rdi , 64
151
+ jne fill_kvma1
152
+
153
+ ; entry 64~127 is a hole (also some sort of protection)
154
+ ; entry 128~191 are mapping of the kernel image itself
155
+ mov rax , 0x0
156
+ or rax , 0x87
157
+ mov rdi , 128
158
+ fill_kvma2:
159
+ mov qword [ pdp1 + 8 * rdi ], rax
160
+ inc rdi
161
+ add rax , 0x40000000
162
+ cmp rdi , 192
163
+ jne fill_kvma2
164
+ ; done :-)
165
+
166
+ ; clear BSS section for the rust code.
167
+ mov rdi , ___BSS_PM_START__
122
168
clear_bss:
123
169
mov byte [ rdi ], 0
124
170
inc rdi
125
- cmp rdi , ___BSS_END__
171
+ cmp rdi , ___BSS_PM_END__
126
172
jne clear_bss
127
- fninit ; activate FPU
128
-
129
- init_sse:
130
- ; init SSE
131
- ; NOTE: must NOT use sse target features for rust compiler, if sse not enabled here.
132
- ;mov rax, cr0
133
- ;and rax, ~(1 << 2) ;clear coprocessor emulation CR0.EM
134
- ;or rax, 1 << 1 ;set coprocessor monitoring CR0.MP
135
- ;mov cr0, rax
136
- ;mov rax, cr4
137
- ;or rax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
138
- ;mov cr4, rax
139
-
140
- call _entry ; call the OS kernel's rust part.
141
- cli ; Usually we should not get here.
173
+ ; enable FPU
174
+ fninit
175
+
176
+ ; NOTE: must NOT use sse target features for rust compiler, if sse not
177
+ ; enabled here.
178
+
179
+ ; finally go to the rust code!
180
+ call _entry
181
+ ; should not reach below
182
+ cli
142
183
hlt
143
184
185
+ ; =====================================================================
186
+ ; data sections they should all have VAs identical to their PAs
187
+ ; so we map these symbols differently than those generated by rust code
188
+ ; =====================================================================
189
+
144
190
[SECTION .data]
145
191
146
192
gdt:
@@ -195,12 +241,21 @@ init_stack:
195
241
196
242
[SECTION .global_pagetable]
197
243
198
-
244
+ ; create initial page tables wrt. the memory layout
245
+ ; we use entry 0 and 256 of the PML4 table
246
+ ; the whole of the first first pdp table (512G)
247
+ ; and entry 0, 2 of the second pdp table
248
+ ; all pages here are 1 GiB huge pages
199
249
pml4:
200
250
resb 4096
201
251
alignb 4096
202
-
203
- pdp:
252
+ ; the first PDP covers the lower 512GiB memory
253
+ pdp0:
254
+ resb 4096
255
+ alignb 4096
256
+ ; pdp1 does the same but in higher half memory with offset
257
+ ; 0xffff_8000_0000_0000, i.e. the 256th entry of pml4
258
+ pdp1:
204
259
resb 4096
205
260
alignb 4096
206
261
pt_end:
0 commit comments