+ return ptd_pp;
+}
+
+void __del_pagetable(pid_t pid, uintptr_t mount_point) {
+ x86_page_table* pptd = (x86_page_table*) (mount_point | (0x3FF << 12));
+
+ for (size_t i = 0; i < PG_MAX_ENTRIES - 1; i++)
+ {
+ x86_pte_t ptde = pptd->entry[i];
+ if (!ptde || !(ptde & PG_PRESENT)) {
+ continue;
+ }
+
+ x86_page_table* ppt = (x86_page_table*) (mount_point | (i << 12));
+
+ for (size_t j = 0; j < PG_MAX_ENTRIES; j++)
+ {
+ x86_pte_t pte = ppt->entry[j];
+ // free the 4KB data page
+ if ((pte & PG_PRESENT)) {
+ pmm_free_page(pid,PG_ENTRY_ADDR(pte));
+ }
+ }
+ // free the L2 page table
+ pmm_free_page(pid, PG_ENTRY_ADDR(ptde));
+ }
+ // free the L1 directory
+ pmm_free_page(pid, PG_ENTRY_ADDR(pptd->entry[PG_MAX_ENTRIES - 1]));
+}
+
+void* dup_pagetable(pid_t pid) {
+ return __dup_pagetable(pid, PD_REFERENCED);
+}
+
+__DEFINE_LXSYSCALL(pid_t, fork) {
+ return dup_proc();
+}
+
+__DEFINE_LXSYSCALL(pid_t, getpid) {
+ return __current->pid;
+}
+
+__DEFINE_LXSYSCALL(pid_t, getppid) {
+ return __current->parent->pid;
+}
+
+void init_proc(struct proc_info *pcb) {
+ memset(pcb, 0, sizeof(*pcb));
+
+ pcb->pid = alloc_pid();
+ pcb->created = clock_systime();
+ pcb->state = PROC_CREATED;
+}
+
+pid_t dup_proc() {
+ struct proc_info pcb;
+ init_proc(&pcb);
+ pcb.mm = __current->mm;
+ pcb.intr_ctx = __current->intr_ctx;
+ pcb.parent = __current;
+
+#ifdef USE_KERNEL_PG
+ setup_proc_mem(&pcb, PD_MOUNT_1); //挂载点#1是当前进程的页表
+#else
+ setup_proc_mem(&pcb, PD_REFERENCED);
+#endif