]> Zhao Yanbai Git Server - kernel.git/commitdiff
do_fork eflags逻辑修正; 返回用户空间的逻辑流用新的方式
authoracevest <zhaoyanbai@126.com>
Sun, 4 Jun 2023 11:00:52 +0000 (19:00 +0800)
committeracevest <zhaoyanbai@126.com>
Sun, 4 Jun 2023 11:00:52 +0000 (19:00 +0800)
kernel/fork.c
kernel/syscall.S
kernel/task_root.c

index d600f7320e9ccfb6d36992690aad0191ca92fd03..27b7037d082ed6c1a7383a197ab20c09607c6442 100644 (file)
@@ -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(&regs, 0); }
index d9227194ccc2c0972f9aa495567af6f3485af1fe..6f204cf6593ba1a268e6d0cee3c9c5eac266cb41 100644 (file)
@@ -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
- * 
+ *
  *--------------------------------------------------------------------------
  */
 
 .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
index 898196db3b1129ff94cd4895b86efe28a4cba589..5c0c700e96735676a8af6a97324cd15779188d58 100644 (file)
@@ -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(&regs, FORK_KRNL);