+/**
+ * @brief 创建并运行init进程
+ *
+ */
+void spawn_lxinit() {
+ struct proc_info kinit;
+
+ memset(&kinit, 0, sizeof(kinit));
+ kinit.parent = (void*)0;
+ kinit.pid = 1;
+ kinit.intr_ctx = (isr_param) {
+ .registers.esp = KSTACK_TOP - 20,
+ .cs = KCODE_SEG,
+ .eip = (void*)_lxinit_main,
+ .ss = KDATA_SEG,
+ .eflags = cpu_reflags()
+ };
+
+ setup_proc_mem(&kinit, PD_REFERENCED);
+
+ // Ok... 准备fork进我们的init进程
+ /*
+ 这里是一些栈的设置,因为我们将切换到一个新的地址空间里,并且使用一个全新的栈。
+ 让iret满意!
+ */
+ asm volatile(
+ "movl %%cr3, %%eax\n"
+ "movl %%esp, %%ebx\n"
+ "movl %0, %%cr3\n"
+ "movl %1, %%esp\n"
+ "pushf\n"
+ "pushl %2\n"
+ "pushl %3\n"
+ "pushl $0\n"
+ "pushl $0\n"
+ "movl %%eax, %%cr3\n"
+ "movl %%ebx, %%esp\n"
+ ::"r"(kinit.page_table), "i"(KSTACK_TOP), "i"(KCODE_SEG), "r"(kinit.intr_ctx.eip)
+ :"%eax", "%ebx", "memory"
+ );
+
+ // 向调度器注册进程,然后这里阻塞等待调度器调度就好了。
+ push_process(&kinit);