+ struct exec_param* execp =
+ (struct exec_param*)(KSTACK_TOP - sizeof(struct exec_param));
+ isr_param* isrp = (isr_param*)((ptr_t)execp - sizeof(isr_param));
+
+ *execp = (struct exec_param){ .cs = KCODE_SEG,
+ .eip = (ptr_t)__proc0,
+ .ss = KDATA_SEG,
+ .eflags = cpu_reflags() };
+ *isrp = (isr_param){ .registers = { .ds = KDATA_SEG,
+ .es = KDATA_SEG,
+ .fs = KDATA_SEG,
+ .gs = KDATA_SEG },
+ .execp = execp };
+
+ proc0->intr_ctx = isrp;
+
+ // 加载x87默认配置
+ asm volatile("fninit\n"
+ "fxsave (%%eax)" ::"a"(proc0->fxstate)
+ : "memory");
+
+ // 向调度器注册进程。
+ commit_process(proc0);
+
+ // 由于时钟中断与APIC未就绪,我们需要手动进行第一次调度。这里也会同时隐式地恢复我们的eflags.IF位
+ proc0->state = PS_RUNNING;
+ asm volatile("pushl %0\n"
+ "jmp switch_to\n" ::"r"(proc0));
+
+ /* Should not return */
+ assert_msg(0, "Unexpected Return");