From: acevest Date: Tue, 2 Nov 2021 16:25:44 +0000 (+0800) Subject: fix memcpy param in do_fork X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=6979bb7885e5af76e8e1ae7d63f37756148f5e2f;p=kernel.git fix memcpy param in do_fork --- diff --git a/.bochsrc b/.bochsrc index 9c88cd2..a2e7855 100644 --- a/.bochsrc +++ b/.bochsrc @@ -1243,7 +1243,7 @@ speaker: enabled=1, mode=sound, volume=15 # Example: # magic_break: enabled=1 #======================================================================= -#magic_break: enabled=1 +magic_break: enabled=1 #======================================================================= # DEBUG_SYMBOLS: diff --git a/kernel/fork.c b/kernel/fork.c index 5caa1ca..77b8013 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -90,10 +90,13 @@ int do_fork(pt_regs_t *regs, unsigned long flags) { pt_regs_t *child_regs = ((pt_regs_t *)(TASK_SIZE + (unsigned long)tsk)) - 1; - *child_regs = *regs; + printk("child regs: %x %x %d\n", child_regs, regs, sizeof(regs)); + //*child_regs = *regs; + memcpy(child_regs, regs, sizeof(*regs)); + asm("xchg %bx, %bx"); child_regs->eax = 0; - child_regs->eflags |= 0x200; // enable IF + //child_regs->eflags |= 0x200; // enable IF tsk->esp0 = TASK_SIZE + (unsigned long)tsk; tsk->esp = (unsigned long)child_regs; diff --git a/kernel/init.c b/kernel/init.c index ede85d5..41cff0a 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -46,35 +46,33 @@ void init_task_entry() { } } -int kernel_fork() { - int pid = 0; - - pt_regs_t *regs = ((pt_regs_t *)(TASK_SIZE + ((unsigned long)current))) - 1; - unsigned long *pedx = &(regs->edx); - - asm volatile( - "movl $1f, %[pedx];" - "call do_fork;" - "1:" - : "=a"(pid) - : [pedx] "m"(pedx)); - - return pid; -} - -void kernel_task(void *entry) { +extern void ret_from_fork_krnl(); +void kernel_task(char *name, void *entry) { pt_regs_t regs; + memset((void *)®s, 0, sizeof(regs)); + + // 内核任务入口 regs.edx = (unsigned long)entry; - // int pid = do_fork(®s, FORK_KRNL); - // int pid = kernel_fork(); + + // 创建内核任务的时候就直接指定其在fork后走的路径 + // 就不用走sysexit那个路径了 + regs.eip = (unsigned long)ret_from_fork_krnl; + regs.cs = SELECTOR_KRNL_CS; + regs.ds = SELECTOR_KRNL_DS; + regs.es = SELECTOR_KRNL_DS; + regs.ss = SELECTOR_KRNL_DS; + regs.eflags = (1 << 9); // enable IF + int pid = do_fork(®s, FORK_KRNL); + printk("kernel task pid is %d\n", pid); + enable_irq(); } void root_task_entry() { - kernel_task(init_task_entry); + kernel_task("init", init_task_entry); // kernel_task(user_task_entry); // kernel_task(init_task_entry); diff --git a/kernel/syscall.S b/kernel/syscall.S index ff8617e..072f9a3 100644 --- a/kernel/syscall.S +++ b/kernel/syscall.S @@ -83,10 +83,14 @@ ret_from_fork_user: sti /* sysenter have cleared IF, and sysexit will not set IF. */ sysexit + +// 内核线程fork出路 ret_from_fork_krnl: - movl PT_REGS_EDX(%esp), %edx - sti + RESTORE_REGS + addl $24, %esp call *%edx + + # 还没有实现do_exit #call do_exit