LOG_MODULE("PROC")
-void dup_proc() {
- pid_t pid = alloc_pid();
-
+void* __dup_pagetable(pid_t pid, uintptr_t mount_point) {
void* ptd_pp = pmm_alloc_page(pid, PP_FGPERSIST);
x86_page_table* ptd = vmm_fmap_page(pid, PG_MOUNT_1, ptd_pp, PG_PREM_RW);
- x86_page_table* pptd = (x86_page_table*) L1_BASE_VADDR;
+ x86_page_table* pptd = (x86_page_table*) (mount_point | (0x3FF << 12));
for (size_t i = 0; i < PG_MAX_ENTRIES - 1; i++)
{
continue;
}
- x86_page_table* ppt = (x86_page_table*) L2_VADDR(i);
+ x86_page_table* ppt = (x86_page_table*) (mount_point | (i << 12));
void* pt_pp = pmm_alloc_page(pid, PP_FGPERSIST);
x86_page_table* pt = vmm_fmap_page(pid, PG_MOUNT_2, pt_pp, PG_PREM_RW);
// FIXME: 根据 mm_region 将读共享的页(如堆)标为只读,而私有的页(如栈),则复制;而写共享的页则无需更改flags
if (va >= KSTACK_START) {
- void* ppa = vmm_dup_page(va);
+ void* ppa = vmm_dup_page(pid, PG_ENTRY_ADDR(ppte));
ppte = ppte & 0xfff | (uintptr_t)ppa;
}
pt->entry[j] = ppte;
ptd->entry[PG_MAX_ENTRIES - 1] = NEW_L1_ENTRY(T_SELF_REF_PERM, ptd_pp);
+ return ptd_pp;
+}
+
+void* dup_pagetable(pid_t pid) {
+ return __dup_pagetable(pid, L2_BASE_VADDR);
+}
+
+void dup_proc() {
+ pid_t pid = alloc_pid();
+
+ /*
+ FIXME: Problematic! It should mount the page table of process then copy it.
+ The current implementation copy the CURRENTLY loaded pgt.
+ However, dup_pagetable is designed to copy current loaded pgt.
+
+ */
+
+ void* mnt_pt = vmm_mount_pd(__current->page_table);
+
+ void* pg = __dup_pagetable(pid, mnt_pt);
+
+ vmm_unmount_pd();
+
struct proc_info pcb = (struct proc_info) {
.created = clock_systime(),
.pid = pid,
.mm = __current->mm,
- .page_table = ptd_pp,
+ .page_table = pg,
.intr_ctx = __current->intr_ctx,
.parent_created = __current->created
};
- // 正如同fork一样,返回两次。
+ // 正如同fork,返回两次。
pcb.intr_ctx.registers.eax = 0;
__current->intr_ctx.registers.eax = pid;