55STACKSIZE: equ 65536
66
77; 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+
913MAX_MEM: equ 512
1014
1115; be careful with the extern and exported symbols when mapping a higher-half
@@ -23,8 +27,8 @@ MAX_MEM: equ 512
2327[GLOBAL mb_info_addr]
2428; functions from other parts of rustubs
2529[EXTERN _entry]
26- [EXTERN ___BSS_START__ ]
27- [EXTERN ___BSS_END__ ]
30+ [EXTERN ___BSS_PM_START__ ]
31+ [EXTERN ___BSS_PM_END__ ]
2832
2933[SECTION .text]
3034
@@ -68,16 +72,16 @@ setup_paging:
6872 ; zero out the initial page tables (2 pages in total)
6973 mov edi , pml4
7074clear_pt:
71- mov byte [ edi ], 0
72- inc edi
75+ mov dword [ edi ], 0
76+ add edi , 4
7377 cmp edi , pt_end
74- jne clear_pt
78+ jl clear_pt
7579
7680 ; Provisional identical page mapping, using 1G huge page, therefore only 2
7781 ; table levels needed. see docs/x86_paging.txt
7882
7983 ; PML4 (Page Map Level 4 / 1st level)
80- mov eax , pdp
84+ mov eax , pdp0
8185 or eax , 0xf
8286 mov dword [ pml4 + 0 ], eax
8387 mov dword [ pml4 + 4 ], 0
@@ -89,8 +93,8 @@ fill_tables2:
8993 ; fill one single PDP table, with 1G pages, 512 PDPE maps to 512 GB
9094 cmp ecx , MAX_MEM
9195 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
9498 add eax , 0x40000000 ; 1G per page
9599 adc ebx , 0 ; overflow? -> increment higher-order half of the address
96100 inc ecx
@@ -115,32 +119,74 @@ activate_long_mode:
115119 ; jump to 64-bit code segment -> full activation of Long Mode
116120 jmp 2 * 0x8 : longmode_start
117121
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+
118130[BITS 64]
119- ; system start, part 2 (in 64-bit Long Mode)
120131longmode_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__
122168clear_bss:
123169 mov byte [ rdi ], 0
124170 inc rdi
125- cmp rdi , ___BSS_END__
171+ cmp rdi , ___BSS_PM_END__
126172 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
142183 hlt
143184
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+
144190[SECTION .data]
145191
146192gdt:
@@ -195,12 +241,21 @@ init_stack:
195241
196242[SECTION .global_pagetable]
197243
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
199249pml4:
200250 resb 4096
201251 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:
204259 resb 4096
205260 alignb 4096
206261pt_end:
0 commit comments