From cd103ea1b3ff029cfc458b3913975b5600915341 Mon Sep 17 00:00:00 2001 From: Minep Date: Fri, 17 Jun 2022 16:44:15 +0100 Subject: [PATCH] refactor: keep in mind the stack layout is crucial. Move context switching & signal handling part into asm once for all. --- lunaix-os/includes/lunaix/process.h | 2 +- lunaix-os/includes/lunaix/signal.h | 3 --- lunaix-os/kernel/asm/x86/interrupt.S | 32 ++++++++++++++++++++++++++-- lunaix-os/kernel/proc0.c | 14 +++++++----- lunaix-os/kernel/sched.c | 16 ++------------ lunaix-os/kernel/signal.c | 14 ++++++------ 6 files changed, 49 insertions(+), 32 deletions(-) diff --git a/lunaix-os/includes/lunaix/process.h b/lunaix-os/includes/lunaix/process.h index 28cb76b..0b743d3 100644 --- a/lunaix-os/includes/lunaix/process.h +++ b/lunaix-os/includes/lunaix/process.h @@ -42,11 +42,11 @@ struct proc_info 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; - void* page_table; time_t created; uint8_t state; int32_t exit_code; diff --git a/lunaix-os/includes/lunaix/signal.h b/lunaix-os/includes/lunaix/signal.h index c98441a..4a4cf0b 100644 --- a/lunaix-os/includes/lunaix/signal.h +++ b/lunaix-os/includes/lunaix/signal.h @@ -23,7 +23,4 @@ typedef unsigned int sigset_t; typedef void (*sighandler_t)(int); -void -signal_dispatch(); - #endif /* __LUNAIX_SIGNAL_H */ diff --git a/lunaix-os/kernel/asm/x86/interrupt.S b/lunaix-os/kernel/asm/x86/interrupt.S index 27bdc4c..cd3f547 100644 --- a/lunaix-os/kernel/asm/x86/interrupt.S +++ b/lunaix-os/kernel/asm/x86/interrupt.S @@ -135,11 +135,39 @@ #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已经写入用户栈! - 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 diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index 074bcd9..6e941b0 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -24,6 +24,8 @@ init_platform(); void lock_reserved_memory(); +// #define ENABLE_USER_MODE + /** * @brief LunaixOS的零号进程,该进程永远为可执行。 * @@ -36,11 +38,12 @@ void __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" @@ -49,6 +52,7 @@ __proc0() "i"(USTACK_TOP & ~0xf), "i"(UCODE_SEG), "r"(&&usr)); +#endif usr: if (!fork()) { asm("jmp _lxinit_main"); diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index 026fb51..0a7250c 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -49,22 +49,10 @@ run(struct proc_info* proc) // 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(); - 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 diff --git a/lunaix-os/kernel/signal.c b/lunaix-os/kernel/signal.c index 3edb2f4..4c0bb56 100644 --- a/lunaix-os/kernel/signal.c +++ b/lunaix-os/kernel/signal.c @@ -9,17 +9,18 @@ void* default_handlers[_SIG_NUM] = { // TODO: 添加默认handler }; -void +// Referenced in kernel/asm/x86/interrupt.S +void* signal_dispatch() { // if (!(SEL_RPL(__current->intr_ctx.cs))) { // // 同特权级间调度不进行信号处理 - // return; + // return 0; // } if (!__current->sig_pending) { // 没有待处理信号 - return; + return 0; } int sig_selected = @@ -30,14 +31,14 @@ signal_dispatch() 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)) { // 用户栈没有空间存放信号上下文 - return; + return 0; } struct proc_sig* sig_ctx = @@ -52,8 +53,7 @@ signal_dispatch() 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) -- 2.27.0