+
+ return pcb.pid;
+}
+
+extern void __kernel_end;
+
+void setup_proc_mem(struct proc_info* proc, uintptr_t usedMnt) {
+ // copy the entire kernel page table
+ pid_t pid = proc->pid;
+ void* pt_copy = __dup_pagetable(pid, usedMnt);
+
+ vmm_mount_pd(PD_MOUNT_2, pt_copy); // 将新进程的页表挂载到挂载点#2
+
+ // copy the kernel stack
+ for (size_t i = KSTACK_START >> 12; i <= KSTACK_TOP >> 12; i++)
+ {
+ volatile x86_pte_t *ppte = &PTE_MOUNTED(PD_MOUNT_2, i);
+
+ /*
+ This is a fucking nightmare, the TLB caching keep the rewrite to PTE from updating.
+ Even the Nightmare Moon the Evil is far less nasty than this.
+ It took me hours of debugging to figure this out.
+
+ In the name of Celestia our glorious goddess, I will fucking HATE the TLB for the rest of my LIFE!
+ */
+ cpu_invplg(ppte);
+
+ x86_pte_t p = *ppte;
+ void* ppa = vmm_dup_page(pid, PG_ENTRY_ADDR(p));
+ *ppte = (p & 0xfff) | (uintptr_t)ppa;
+ }
+
+ // 我们不需要分配内核的区域,因为所有的内核代码和数据段只能通过系统调用来访问,任何非法的访问
+ // 都会导致eip落在区域外面,从而segmentation fault.