X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/48b4a227035048fdebcd32532deb7a857c6199ac..2e21eb2f39dd80aa166216381d5d402be943686e:/lunaix-os/kernel/k_init.c?ds=inline diff --git a/lunaix-os/kernel/k_init.c b/lunaix-os/kernel/k_init.c index bbd505d..c119676 100644 --- a/lunaix-os/kernel/k_init.c +++ b/lunaix-os/kernel/k_init.c @@ -39,6 +39,10 @@ extern uint8_t __init_hhk_end; // Set remotely by kernel/asm/x86/prologue.S multiboot_info_t* _k_init_mb_info; +x86_page_table* __kernel_ptd; + +struct proc_info tmp; + LOG_MODULE("BOOT"); extern void _lxinit_main(); @@ -62,6 +66,14 @@ _kernel_pre_init() { tty_init((void*)VGA_BUFFER_PADDR); tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_BLACK); + + __kernel_ptd = cpu_rcr3(); + + tmp = (struct proc_info) { + .page_table = __kernel_ptd + }; + + __current = &tmp; } void @@ -81,8 +93,6 @@ _kernel_init() { kprintf(KINFO "[MM] Allocated %d pages for stack start at %p\n", KSTACK_SIZE>>PG_SIZE_BITS, KSTACK_START); sched_init(); - - spawn_lxinit(); } /** @@ -91,32 +101,43 @@ _kernel_init() { */ void spawn_lxinit() { struct proc_info kinit; - uint32_t* kstack = (uint32_t*)KSTACK_TOP - 4 * 5; memset(&kinit, 0, sizeof(kinit)); - kinit.page_table = (void*) cpu_rcr3(); kinit.parent = -1; kinit.pid = 1; kinit.intr_ctx = (isr_param) { - .registers.esp = kstack, + .registers.esp = KSTACK_TOP - 20, .cs = KCODE_SEG, - .eip = (void*)_kernel_post_init, + .eip = (void*)_lxinit_main, .ss = KDATA_SEG, .eflags = cpu_reflags() }; - - /* - 因为schedule从设计上是需要在中断环境中执行的 - 可是我们需要在这里手动调用 schedule,从而使我们的init能够被执行。 - 所以需要模拟中断产生时的栈里内容。 - */ - kstack[2] = kinit.intr_ctx.eip; - kstack[3] = kinit.intr_ctx.cs; - kstack[4] = kinit.intr_ctx.eflags; - + kinit.page_table = dup_pagetable(kinit.pid); + + // 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); - - schedule(); + } void @@ -155,7 +176,7 @@ _kernel_post_init() { vmm_unmap_page(KERNEL_PID, (void*)(i << PG_SIZE_BITS)); } - _lxinit_main(); + spawn_lxinit(); spin(); }