1 #include <lunaix/process.h>
2 #include <lunaix/mm/vmm.h>
3 #include <lunaix/clock.h>
4 #include <lunaix/syslog.h>
5 #include <lunaix/common.h>
9 void* __dup_pagetable(pid_t pid, uintptr_t mount_point) {
10 void* ptd_pp = pmm_alloc_page(pid, PP_FGPERSIST);
11 x86_page_table* ptd = vmm_fmap_page(pid, PG_MOUNT_1, ptd_pp, PG_PREM_RW);
12 x86_page_table* pptd = (x86_page_table*) (mount_point | (0x3FF << 12));
14 for (size_t i = 0; i < PG_MAX_ENTRIES - 1; i++)
16 x86_pte_t ptde = pptd->entry[i];
17 if (!ptde || !(ptde & PG_PRESENT)) {
22 x86_page_table* ppt = (x86_page_table*) (mount_point | (i << 12));
23 void* pt_pp = pmm_alloc_page(pid, PP_FGPERSIST);
24 x86_page_table* pt = vmm_fmap_page(pid, PG_MOUNT_2, pt_pp, PG_PREM_RW);
26 for (size_t j = 0; j < PG_MAX_ENTRIES; j++)
28 uintptr_t va = ((i << 10) | j) << 12;
29 x86_pte_t ppte = ppt->entry[j];
30 if (!ppte || !(ppte & PG_PRESENT)) {
35 // FIXME: 根据 mm_region 将读共享的页(如堆)标为只读,而私有的页(如栈),则复制;而写共享的页则无需更改flags
36 if (va >= KSTACK_START) {
37 void* ppa = vmm_dup_page(pid, PG_ENTRY_ADDR(ppte));
38 ppte = ppte & 0xfff | (uintptr_t)ppa;
41 // ppte = ppte & ~PG_WRITE;
42 // pt->entry[j] = ppte;
43 // ppt->entry[j] = ppte;
46 ptd->entry[i] = (uintptr_t)pt_pp | PG_PREM_RW;
49 ptd->entry[PG_MAX_ENTRIES - 1] = NEW_L1_ENTRY(T_SELF_REF_PERM, ptd_pp);
54 void* dup_pagetable(pid_t pid) {
55 return __dup_pagetable(pid, L2_BASE_VADDR);
59 pid_t pid = alloc_pid();
62 FIXME: Problematic! It should mount the page table of process then copy it.
63 The current implementation copy the CURRENTLY loaded pgt.
64 However, dup_pagetable is designed to copy current loaded pgt.
68 void* mnt_pt = vmm_mount_pd(__current->page_table);
70 void* pg = __dup_pagetable(pid, mnt_pt);
74 struct proc_info pcb = (struct proc_info) {
75 .created = clock_systime(),
79 .intr_ctx = __current->intr_ctx,
80 .parent_created = __current->created
84 pcb.intr_ctx.registers.eax = 0;
85 __current->intr_ctx.registers.eax = pid;