basic process support and some syscalls
[lunaix-os.git] / lunaix-os / kernel / process.c
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>
6
7 LOG_MODULE("PROC")
8
9 void dup_proc() {
10     pid_t pid = alloc_pid();
11
12     void* ptd_pp = pmm_alloc_page(pid, PP_FGPERSIST);
13     x86_page_table* ptd = vmm_fmap_page(pid, PG_MOUNT_1, ptd_pp, PG_PREM_RW);
14     x86_page_table* pptd = (x86_page_table*) L1_BASE_VADDR;
15
16     for (size_t i = 0; i < PG_MAX_ENTRIES - 1; i++)
17     {
18         x86_pte_t ptde = pptd->entry[i];
19         if (!ptde || !(ptde & PG_PRESENT)) {
20             ptd->entry[i] = ptde;
21             continue;
22         }
23         
24         x86_page_table* ppt = (x86_page_table*) L2_VADDR(i);
25         void* pt_pp = pmm_alloc_page(pid, PP_FGPERSIST);
26         x86_page_table* pt = vmm_fmap_page(pid, PG_MOUNT_2, pt_pp, PG_PREM_RW);
27
28         for (size_t j = 0; j < PG_MAX_ENTRIES; j++)
29         {
30             uintptr_t va = ((i << 10) | j) << 12;
31             x86_pte_t ppte = ppt->entry[j];
32             if (!ppte || !(ppte & PG_PRESENT)) {
33                 pt->entry[j] = ppte;
34                 continue;
35             }
36
37             // FIXME: 根据 mm_region 将读共享的页(如堆)标为只读,而私有的页(如栈),则复制;而写共享的页则无需更改flags
38             if (va >= KSTACK_START) {
39                 void* ppa = vmm_dup_page(va);
40                 ppte = ppte & 0xfff | (uintptr_t)ppa;
41             }
42             pt->entry[j] = ppte;
43             // ppte = ppte & ~PG_WRITE;
44             // pt->entry[j] = ppte;
45             // ppt->entry[j] = ppte;
46         }
47
48         ptd->entry[i] = (uintptr_t)pt_pp | PG_PREM_RW;
49     }
50     
51     ptd->entry[PG_MAX_ENTRIES - 1] = NEW_L1_ENTRY(T_SELF_REF_PERM, ptd_pp);
52
53     struct proc_info pcb = (struct proc_info) {
54         .created = clock_systime(),
55         .pid = pid,
56         .mm = __current->mm,
57         .page_table = ptd_pp,
58         .intr_ctx = __current->intr_ctx,
59         .parent_created = __current->created
60     };
61
62     // 正如同fork一样,返回两次。
63     pcb.intr_ctx.registers.eax = 0;
64     __current->intr_ctx.registers.eax = pid;
65
66     push_process(&pcb);
67     
68 }