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;
typedef unsigned int sigset_t;
typedef void (*sighandler_t)(int);
-void
-signal_dispatch();
-
#endif /* __LUNAIX_SIGNAL_H */
#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
void
lock_reserved_memory();
+// #define ENABLE_USER_MODE
+
/**
* @brief LunaixOS的零号进程,该进程永远为可执行。
*
__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"
"i"(USTACK_TOP & ~0xf),
"i"(UCODE_SEG),
"r"(&&usr));
+#endif
usr:
if (!fork()) {
asm("jmp _lxinit_main");
// 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
// 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 =
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 =
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)