From: acevest Date: Sun, 4 Jun 2023 11:00:52 +0000 (+0800) Subject: do_fork eflags逻辑修正; 返回用户空间的逻辑流用新的方式 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=ca7411a0105283bfa4d28c6b1e6033d37fee30be;p=kernel.git do_fork eflags逻辑修正; 返回用户空间的逻辑流用新的方式 --- diff --git a/kernel/fork.c b/kernel/fork.c index d600f73..27b7037 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -29,6 +29,16 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { memcpy(tsk, current, sizeof(task_union)); + assert(tsk->magic == TASK_MAGIC); + + tsk->state = TASK_INITING; + + INIT_LIST_HEAD(&tsk->list); + unsigned long iflags; + irq_save(iflags); + list_add(&tsk->list, &all_tasks); + irq_restore(iflags); + tsk->cr3 = va2pa((unsigned long)alloc_one_page(0)); assert(tsk->cr3 != 0); @@ -83,6 +93,21 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { #endif } + pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1; + + // printd("child regs: %x %x\n", child_regs, regs); + memcpy(child_regs, regs, sizeof(*regs)); + + if (flags & FORK_KRNL) { + strcpy(tsk->name, (char *)(child_regs->eax)); + child_regs->eax = 0; + } else { + child_regs->eip = *((unsigned long *)&&fork_child); + } + + // 这一句已经不需要了,通过fork_child已经能给子进程返回0了 + // child_regs->eax = 0; + tsk->pid = get_next_pid(); tsk->ppid = current->pid; tsk->priority = current->priority; @@ -91,37 +116,20 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { tsk->need_resched = 0; tsk->sched_cnt = 0; tsk->sched_keep_cnt = 0; - assert(tsk->magic == TASK_MAGIC); - pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1; - - printd("child regs: %x %x\n", child_regs, regs); - memcpy(child_regs, regs, sizeof(*regs)); - - tsk->esp0 = TASK_SIZE + (unsigned long)tsk; + // for switch_to + tsk->eip = child_regs->eip; tsk->esp = (unsigned long)child_regs; - tsk->eip = (unsigned long)ret_from_fork_user; - if (flags & FORK_KRNL) { - strcpy(tsk->name, (char *)(child_regs->eax)); - tsk->eip = (unsigned long)ret_from_fork_krnl; - } - - child_regs->eax = 0; - child_regs->eflags |= 0x200; // enable IF + tsk->esp0 = TASK_SIZE + (unsigned long)tsk; printd("task %08x child_regs esp %08x esp0 %08x\n", tsk, tsk->esp, tsk->esp0); - tsk->state = TASK_INITING; - - INIT_LIST_HEAD(&tsk->list); - unsigned long iflags; - irq_save(iflags); - list_add(&tsk->list, &all_tasks); - irq_restore(iflags); - tsk->state = TASK_READY; return (int)tsk->pid; + +fork_child: + return 0; } int sysc_fork(pt_regs_t regs) { return do_fork(®s, 0); } diff --git a/kernel/syscall.S b/kernel/syscall.S index d922719..6f204cf 100644 --- a/kernel/syscall.S +++ b/kernel/syscall.S @@ -1,19 +1,19 @@ /* *-------------------------------------------------------------------------- * File Name: syscall.S - * + * * Description: none - * - * + * + * * Author: Zhao Yanbai [zhaoyanbai@126.com] - * + * * Version: 1.0 * Create Date: Tue Feb 10 13:20:33 2009 * Version: 2.0 * Last Update: Wed Feb 10 23:36:34 2010 * Version: 3.0 * Last Update: Fri May 2 00:21:37 2014 - * + * *-------------------------------------------------------------------------- */ @@ -25,16 +25,15 @@ .code32 .text .global syscall_entry -.global ret_from_fork_user .global ret_from_fork_krnl .extern reenter //.global syscall_exit syscall_entry: #if FIX_SYSENTER_ESP_MODE - movl (%esp),%esp + movl (%esp),%esp #endif - + // sysenter have cleared IF, and sysexit will not set IF. sti @@ -75,7 +74,6 @@ syscall_entry: // 保存返回值 movl %eax, PT_REGS_EAX(%esp) -ret_from_fork_user: RESTORE_REGS @@ -93,18 +91,19 @@ ret_from_fork_user: // 内核线程fork出路 ret_from_fork_krnl: RESTORE_REGS - addl $12, %esp - popfl - addl $8, %esp + addl $12, %esp // 0 EIP CS + popfl // EFLAGS + addl $8, %esp // ESP SS call *%edx - addl $4, %esp - # 还没有实现do_exit - #call do_exit + addl $4, %esp // CALL PUSH EIP + + // TODO + // add exit here + + - - # this routine should be load align by PAGE_SIZE # this page is shared by the kernel and userspace @@ -117,4 +116,4 @@ sysexit: popl %ebp; popl %edx; popl %ecx; - ret \ No newline at end of file + ret diff --git a/kernel/task_root.c b/kernel/task_root.c index 898196d..5c0c700 100644 --- a/kernel/task_root.c +++ b/kernel/task_root.c @@ -23,6 +23,8 @@ int do_fork(pt_regs_t *regs, unsigned long flags); int sysc_wait(uint32_t ticks); +#define get_eflags(x) __asm__ __volatile__("pushfl; popl %0;" : "=g"(x)::"memory") + void kernel_task(char *name, void *entry) { pt_regs_t regs; @@ -43,6 +45,7 @@ void kernel_task(char *name, void *entry) { regs.ss = SELECTOR_KRNL_DS; regs.fs = SELECTOR_KRNL_DS; regs.gs = SELECTOR_KRNL_DS; + get_eflags(regs.eflags); int pid = do_fork(®s, FORK_KRNL);