- setup_proc_mem(&proc0, PD_REFERENCED);
-
- // Ok... 首先fork进我们的零号进程,而后由那里,我们fork进init进程。
- /*
- 这里是一些栈的设置,因为我们将切换到一个新的地址空间里,并且使用一个全新的栈。
- 让iret满意!
- */
- asm volatile("movl %%cr3, %%eax\n"
- "movl %%esp, %%ebx\n"
- "movl %1, %%cr3\n"
- "movl %2, %%esp\n"
- "pushf\n"
- "pushl %3\n"
- "pushl %4\n"
- "pushl $0\n"
- "pushl $0\n"
- "movl %%esp, %0\n"
- "movl %%eax, %%cr3\n"
- "movl %%ebx, %%esp\n"
- : "=m"(proc0.intr_ctx.registers.esp)
- : "r"(proc0.page_table),
- "i"(KSTACK_TOP),
- "i"(KCODE_SEG),
- "r"(proc0.intr_ctx.eip)
- : "%eax", "%ebx", "memory");
+ /* Ok... 首先fork进我们的零号进程,而后由那里,我们fork进init进程。 */
+
+ // 把当前虚拟地址空间(内核)复制一份。
+ proc0->page_table = vmm_dup_vmspace(proc0->pid);
+
+ // 直接切换到新的拷贝,进行配置。
+ cpu_lcr3(proc0->page_table);
+
+ // 为内核创建一个专属栈空间。
+ for (size_t i = 0; i < (KSTACK_SIZE >> PG_SIZE_BITS); i++) {
+ ptr_t pa = pmm_alloc_page(KERNEL_PID, 0);
+ vmm_set_mapping(VMS_SELF,
+ KSTACK_START + (i << PG_SIZE_BITS),
+ pa,
+ PG_PREM_RW,
+ VMAP_NULL);
+ }
+
+ struct exec_param* execp =
+ (struct exec_param*)(KSTACK_TOP - sizeof(struct exec_param));
+
+ *execp = (struct exec_param){ .cs = KCODE_SEG,
+ .eip = (ptr_t)__proc0,
+ .ss = KDATA_SEG,
+ .eflags = cpu_reflags() };
+ proc0->intr_ctx.execp = execp;
+
+ // 加载x87默认配置
+ asm volatile("fninit\n"
+ "fxsave (%%eax)" ::"a"(proc0->fxstate)
+ : "memory");