refactor: keep in mind the stack layout is crucial. Move context switching & signal...
authorMinep <zelong56@gmail.com>
Fri, 17 Jun 2022 15:44:15 +0000 (16:44 +0100)
committerMinep <zelong56@gmail.com>
Fri, 17 Jun 2022 15:44:15 +0000 (16:44 +0100)
lunaix-os/includes/lunaix/process.h
lunaix-os/includes/lunaix/signal.h
lunaix-os/kernel/asm/x86/interrupt.S
lunaix-os/kernel/proc0.c
lunaix-os/kernel/sched.c
lunaix-os/kernel/signal.c

index 28cb76b97a797089cdceacac9a3323c373c0760a..0b743d39c3058fff0d1d61b702ff149ae3a67d78 100644 (file)
@@ -42,11 +42,11 @@ struct proc_info
     struct proc_info* parent;
     isr_param intr_ctx; // size=76
     uintptr_t ustack_top;
     struct proc_info* parent;
     isr_param intr_ctx; // size=76
     uintptr_t ustack_top;
+    void* page_table;
     struct llist_header siblings;
     struct llist_header children;
     struct llist_header grp_member;
     struct proc_mm mm;
     struct llist_header siblings;
     struct llist_header children;
     struct llist_header grp_member;
     struct proc_mm mm;
-    void* page_table;
     time_t created;
     uint8_t state;
     int32_t exit_code;
     time_t created;
     uint8_t state;
     int32_t exit_code;
index c98441a230aff851849791fcab184673eb259c94..4a4cf0b725234ba2f65ad2fc3276f3fecc1a4041 100644 (file)
@@ -23,7 +23,4 @@
 typedef unsigned int sigset_t;
 typedef void (*sighandler_t)(int);
 
 typedef unsigned int sigset_t;
 typedef void (*sighandler_t)(int);
 
-void
-signal_dispatch();
-
 #endif /* __LUNAIX_SIGNAL_H */
 #endif /* __LUNAIX_SIGNAL_H */
index 27bdc4c4cab8a0fcac2d8813bacf81b81f057d9d..cd3f547a10dd7522e9b47cff3b3e090d42940df7 100644 (file)
 #endif
         iret
 
 #endif
         iret
 
+    .global switch_to
+    switch_to:
+        # 约定
+        # arg1: 目标进程PCB地址 (next)
+        popl %ecx               # next
+
+        call signal_dispatch    # kernel/signal.c
+        movl %eax, %edx
+
+        movl __current, %eax    
+        movl 88(%eax), %ebx     # __current->pagetable
+        movl 88(%ecx), %eax     # next->pagetable
+        
+        cmpl %ebx, %eax         # if(next->pagtable != __current->pagetable) {
+        jz 1f
+        movl %eax, %cr3         #   cpu_lcr3(next->pagetable)
+                                # }
+    1:
+        movl %ecx, __current    # __current = next
+
+        test %edx, %edx         # do we have signal to handle?
+        jz 1f
+        movl %edx, %eax
+        jmp handle_signal
+    1:
+        leal 8(%ecx), %eax
+        jmp soft_iret
+
+    .global handle_signal
     handle_signal:
         # 注意1:任何对proc_sig的布局改动,都须及时的保证这里的一致性!
         # 注意2:handle_signal在调用之前,须确保proc_sig已经写入用户栈!
     handle_signal:
         # 注意1:任何对proc_sig的布局改动,都须及时的保证这里的一致性!
         # 注意2:handle_signal在调用之前,须确保proc_sig已经写入用户栈!
-        popl %eax               # arg1: addr of proc_sig structure in user stack
-        leal 8(%eax), %ebx
+        leal 8(%eax), %ebx      # arg1 in %eax: addr of proc_sig structure in user stack
 
         pushl 72(%ebx)          # proc_sig->prev_context.ss
         pushl %eax              # esp
 
         pushl 72(%ebx)          # proc_sig->prev_context.ss
         pushl %eax              # esp
index 074bcd9347c40cdf070e97c26c3127eddbc2b3b0..6e941b0218506c79ce07fa275fa70eddca712256 100644 (file)
@@ -24,6 +24,8 @@ init_platform();
 void
 lock_reserved_memory();
 
 void
 lock_reserved_memory();
 
+// #define ENABLE_USER_MODE
+
 /**
  * @brief LunaixOS的零号进程,该进程永远为可执行。
  *
 /**
  * @brief LunaixOS的零号进程,该进程永远为可执行。
  *
@@ -36,11 +38,12 @@ void
 __proc0()
 {
     init_platform();
 __proc0()
 {
     init_platform();
-    asm volatile("movw %0, %ax\n"
-                 "movw %ax, %es\n"
-                 "movw %ax, %ds\n"
-                 "movw %ax, %fs\n"
-                 "movw %ax, %gs\n"
+#ifdef ENABLE_USER_MODE
+    asm volatile("movw %0, %%ax\n"
+                 "movw %%ax, %%es\n"
+                 "movw %%ax, %%ds\n"
+                 "movw %%ax, %%fs\n"
+                 "movw %%ax, %%gs\n"
                  "pushl %0\n"
                  "pushl %1\n"
                  "pushl %2\n"
                  "pushl %0\n"
                  "pushl %1\n"
                  "pushl %2\n"
@@ -49,6 +52,7 @@ __proc0()
                  "i"(USTACK_TOP & ~0xf),
                  "i"(UCODE_SEG),
                  "r"(&&usr));
                  "i"(USTACK_TOP & ~0xf),
                  "i"(UCODE_SEG),
                  "r"(&&usr));
+#endif
 usr:
     if (!fork()) {
         asm("jmp _lxinit_main");
 usr:
     if (!fork()) {
         asm("jmp _lxinit_main");
index 026fb515a8dbfbc34410e868de18ccad40b7b308..0a7250caa6c8818f12a5b3e66fba4f3291c5a9eb 100644 (file)
@@ -49,22 +49,10 @@ run(struct proc_info* proc)
 
     // FIXME: 这里还是得再考虑一下。
     // tss_update_esp(__current->intr_ctx.esp);
 
     // FIXME: 这里还是得再考虑一下。
     // tss_update_esp(__current->intr_ctx.esp);
-
-    if (__current->page_table != proc->page_table) {
-        __current = proc;
-        cpu_lcr3(__current->page_table);
-        // from now on, the we are in the kstack of another process
-    } else {
-        __current = proc;
-    }
-
     apic_done_servicing();
 
     apic_done_servicing();
 
-    signal_dispatch();
-
-    asm volatile("movl %0, %%eax\n"
-                 "jmp soft_iret\n" ::"r"(&__current->intr_ctx)
-                 : "eax", "memory");
+    asm volatile("pushl %0\n"
+                 "jmp switch_to\n" ::"r"(proc)); // kernel/asm/x86/interrupt.S
 }
 
 void
 }
 
 void
index 3edb2f4fea2cba2fb820d2b700e825bf9f4e9fcd..4c0bb56ad27b307c1e1b44641d47e28db1b88799 100644 (file)
@@ -9,17 +9,18 @@ void* default_handlers[_SIG_NUM] = {
     // TODO: 添加默认handler
 };
 
     // TODO: 添加默认handler
 };
 
-void
+// Referenced in kernel/asm/x86/interrupt.S
+void*
 signal_dispatch()
 {
     // if (!(SEL_RPL(__current->intr_ctx.cs))) {
     //     // 同特权级间调度不进行信号处理
 signal_dispatch()
 {
     // if (!(SEL_RPL(__current->intr_ctx.cs))) {
     //     // 同特权级间调度不进行信号处理
-    //     return;
+    //     return 0;
     // }
 
     if (!__current->sig_pending) {
         // 没有待处理信号
     // }
 
     if (!__current->sig_pending) {
         // 没有待处理信号
-        return;
+        return 0;
     }
 
     int sig_selected =
     }
 
     int sig_selected =
@@ -30,14 +31,14 @@ signal_dispatch()
     if (!__current->sig_handler[sig_selected] &&
         !default_handlers[sig_selected]) {
         // 如果该信号没有handler,则忽略
     if (!__current->sig_handler[sig_selected] &&
         !default_handlers[sig_selected]) {
         // 如果该信号没有handler,则忽略
-        return;
+        return 0;
     }
 
     uintptr_t ustack = __current->ustack_top;
 
     if ((int)(ustack - USTACK_END) < (int)sizeof(struct proc_sig)) {
         // 用户栈没有空间存放信号上下文
     }
 
     uintptr_t ustack = __current->ustack_top;
 
     if ((int)(ustack - USTACK_END) < (int)sizeof(struct proc_sig)) {
         // 用户栈没有空间存放信号上下文
-        return;
+        return 0;
     }
 
     struct proc_sig* sig_ctx =
     }
 
     struct proc_sig* sig_ctx =
@@ -52,8 +53,7 @@ signal_dispatch()
         sig_ctx->signal_handler = default_handlers[sig_selected];
     }
 
         sig_ctx->signal_handler = default_handlers[sig_selected];
     }
 
-    asm volatile("pushl %0\n"
-                 "jmp handle_signal" ::"r"(sig_ctx));
+    return sig_ctx;
 }
 
 __DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx)
 }
 
 __DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx)