Merge branch 'interrupt-rework' into prog-loader
authorMinep <zelong56@gmail.com>
Wed, 4 Jan 2023 16:12:56 +0000 (16:12 +0000)
committerMinep <zelong56@gmail.com>
Wed, 4 Jan 2023 16:12:56 +0000 (16:12 +0000)
14 files changed:
lunaix-os/config/make-cc
lunaix-os/debug/bg_lsdbg.c
lunaix-os/debug/gdbstub.c
lunaix-os/debug/sdbg.c
lunaix-os/hal/ahci/io_event.c
lunaix-os/includes/arch/x86/interrupts.h
lunaix-os/includes/lunaix/process.h
lunaix-os/kernel/asm/x86/interrupt.S
lunaix-os/kernel/asm/x86/interrupts.c
lunaix-os/kernel/asm/x86/intr_routines.c
lunaix-os/kernel/asm/x86/pfault.c
lunaix-os/kernel/asm/x86/syscall.S
lunaix-os/kernel/k_init.c
lunaix-os/kernel/process/sched.c

index 6fd8494c4d81902ebe74313e95be918fdef59236..7915afe89a0949d305ea569d5c9664564b9c3e52 100644 (file)
@@ -17,7 +17,10 @@ OFLAGS := -fno-gcse\
                  -fno-cse-follow-jumps\
                  -fno-cse-skip-blocks\
                  -fno-optimize-strlen\
-                 -fno-tree-builtin-call-dce 
+                 -fno-inline-functions-called-once \
+                 -fno-inline-functions \
+                 -fno-inline-small-functions \
+                 -fno-indirect-inlining
 
 CFLAGS := -std=gnu99 -ffreestanding $(O) $(OFLAGS) $(W) $(ARCH_OPT)
 LDFLAGS := -ffreestanding $(O) -nostdlib -lgcc
\ No newline at end of file
index 0f0496de4681dc506fa65b28e45eb16847fc7c94..9c428b2755c11877e1fc989cfcc3d94db310f011 100644 (file)
@@ -29,9 +29,11 @@ lunaix_sdbg_loop(isr_param* param)
     char c;
 
     if (sdbg_state == SDBG_STATE_WAIT_BRK) {
-        (param)->eflags &= ~(1 << 8);
+        (param)->execp->eflags &= ~(1 << 8);
         sdbg_state = SDBG_STATE_INSESSION;
-        sdbg_printf("[%p:%p] Break point reached.\n", param->cs, param->eip);
+        sdbg_printf("[%p:%p] Break point reached.\n",
+                    param->execp->cs,
+                    param->execp->eip);
     }
 
     while (1) {
@@ -44,12 +46,14 @@ lunaix_sdbg_loop(isr_param* param)
         switch (c) {
             case SDBG_CLNT_HI:
                 if (sdbg_state == SDBG_STATE_START) {
-                    sdbg_printf(
-                      "[%p:%p] Session started.\n", param->cs, param->eip);
+                    sdbg_printf("[%p:%p] Session started.\n",
+                                param->execp->cs,
+                                param->execp->eip);
                     sdbg_state = SDBG_STATE_INSESSION;
                 } else {
-                    sdbg_printf(
-                      "[%p:%p] Session resumed.\n", param->cs, param->eip);
+                    sdbg_printf("[%p:%p] Session resumed.\n",
+                                param->execp->cs,
+                                param->execp->eip);
                 }
                 break;
             case SDBG_CLNT_RREG:
@@ -57,7 +61,7 @@ lunaix_sdbg_loop(isr_param* param)
                 serial_tx_buffer(SERIAL_COM1, (char*)param, sizeof(isr_param));
                 break;
             case SDBG_CLNT_STEP:
-                ((isr_param*)param)->eflags |= (1 << 8); // set TF flags
+                ((isr_param*)param)->execp->eflags |= (1 << 8); // set TF flags
                 sdbg_state = SDBG_STATE_WAIT_BRK;
                 return;
             case SDBG_CLNT_BRKP:
index 9546b85800693788888f181892fc75494e98f551..d87db19fa33cc46ad519da0f74287cd2a0eb8c41 100644 (file)
@@ -1211,7 +1211,7 @@ void
 gdbstub_loop(isr_param* param)
 {
     /* Translate vector to signal */
-    switch (param->vector) {
+    switch (param->execp->vector) {
         case 1:
             gdb_state.signum = 5;
             break;
@@ -1227,14 +1227,14 @@ gdbstub_loop(isr_param* param)
     gdb_state.registers[GDB_CPU_I386_REG_ECX] = param->registers.ecx;
     gdb_state.registers[GDB_CPU_I386_REG_EDX] = param->registers.edx;
     gdb_state.registers[GDB_CPU_I386_REG_EBX] = param->registers.ebx;
-    gdb_state.registers[GDB_CPU_I386_REG_ESP] = param->registers.esp;
+    gdb_state.registers[GDB_CPU_I386_REG_ESP] = param->esp;
     gdb_state.registers[GDB_CPU_I386_REG_EBP] = param->registers.ebp;
     gdb_state.registers[GDB_CPU_I386_REG_ESI] = param->registers.esi;
     gdb_state.registers[GDB_CPU_I386_REG_EDI] = param->registers.edi;
-    gdb_state.registers[GDB_CPU_I386_REG_PC] = param->eip;
-    gdb_state.registers[GDB_CPU_I386_REG_CS] = param->cs;
-    gdb_state.registers[GDB_CPU_I386_REG_PS] = param->eflags;
-    gdb_state.registers[GDB_CPU_I386_REG_SS] = param->ss;
+    gdb_state.registers[GDB_CPU_I386_REG_PC] = param->execp->eip;
+    gdb_state.registers[GDB_CPU_I386_REG_CS] = param->execp->cs;
+    gdb_state.registers[GDB_CPU_I386_REG_PS] = param->execp->eflags;
+    gdb_state.registers[GDB_CPU_I386_REG_SS] = param->execp->ss;
     gdb_state.registers[GDB_CPU_I386_REG_DS] = param->registers.ds;
     gdb_state.registers[GDB_CPU_I386_REG_ES] = param->registers.es;
     gdb_state.registers[GDB_CPU_I386_REG_FS] = param->registers.fs;
@@ -1247,14 +1247,14 @@ gdbstub_loop(isr_param* param)
     param->registers.ecx = gdb_state.registers[GDB_CPU_I386_REG_ECX];
     param->registers.edx = gdb_state.registers[GDB_CPU_I386_REG_EDX];
     param->registers.ebx = gdb_state.registers[GDB_CPU_I386_REG_EBX];
-    param->registers.esp = gdb_state.registers[GDB_CPU_I386_REG_ESP];
+    param->esp = gdb_state.registers[GDB_CPU_I386_REG_ESP];
     param->registers.ebp = gdb_state.registers[GDB_CPU_I386_REG_EBP];
     param->registers.esi = gdb_state.registers[GDB_CPU_I386_REG_ESI];
     param->registers.edi = gdb_state.registers[GDB_CPU_I386_REG_EDI];
-    param->eip = gdb_state.registers[GDB_CPU_I386_REG_PC];
-    param->cs = gdb_state.registers[GDB_CPU_I386_REG_CS];
-    param->eflags = gdb_state.registers[GDB_CPU_I386_REG_PS];
-    param->ss = gdb_state.registers[GDB_CPU_I386_REG_SS];
+    param->execp->eip = gdb_state.registers[GDB_CPU_I386_REG_PC];
+    param->execp->cs = gdb_state.registers[GDB_CPU_I386_REG_CS];
+    param->execp->eflags = gdb_state.registers[GDB_CPU_I386_REG_PS];
+    param->execp->ss = gdb_state.registers[GDB_CPU_I386_REG_SS];
     param->registers.ds = gdb_state.registers[GDB_CPU_I386_REG_DS];
     param->registers.es = gdb_state.registers[GDB_CPU_I386_REG_ES];
     param->registers.fs = gdb_state.registers[GDB_CPU_I386_REG_FS];
index 3cc23cf29d388068ec7668b89ab6955d749acd04..60a89f360a40cffc3b4e1fe91fd790ff802a16e7 100644 (file)
@@ -22,7 +22,8 @@ sdbg_loop(const isr_param* param)
     // synchronized way. And we don't want these irq queue up at our APIC and
     // confuse the CPU after ACK with APIC.
     serial_disable_irq(SERIAL_COM1);
-    if (param->vector == 1 || param->vector == 3) {
+    struct exec_param* execp = param->execp;
+    if (execp->vector == 1 || execp->vector == 3) {
         goto cont;
     }
 
@@ -74,10 +75,11 @@ done:
 void
 sdbg_imm(const isr_param* param)
 {
+    struct exec_param* execp = param->execp;
     kprintf(KDEBUG "Quick debug mode\n");
     kprintf(KDEBUG "cs=%p eip=%p eax=%p ebx=%p\n",
-            param->cs,
-            param->eip,
+            execp->cs,
+            execp->eip,
             param->registers.eax,
             param->registers.ebx);
     kprintf(KDEBUG "ecx=%p edx=%p edi=%p esi=%p\n",
@@ -86,12 +88,12 @@ sdbg_imm(const isr_param* param)
             param->registers.edi,
             param->registers.esi);
     kprintf(KDEBUG "u.esp=%p k.esp=%p ebp=%p ps=%p\n",
-            param->registers.esp,
             param->esp,
+            execp->esp,
             param->registers.ebp,
-            param->eflags);
+            execp->eflags);
     kprintf(KDEBUG "ss=%p ds=%p es=%p fs=%p gs=%p\n",
-            param->ss,
+            execp->ss,
             param->registers.ds,
             param->registers.es,
             param->registers.fs,
index e11016a3b5a1165208e1a78b40fef4465226d819..c1bd6a5ad2f2cc9465aac2ab52beec962314c99c 100644 (file)
@@ -15,7 +15,7 @@ __ahci_hba_isr(const isr_param* param)
     struct ahci_driver *pos, *n;
     llist_for_each(pos, n, &ahcis, ahci_drvs)
     {
-        if (pos->id == param->vector) {
+        if (pos->id == param->execp->vector) {
             hba = &pos->hba;
             goto proceed;
         }
index d25fbe3b68d9e931b7062d559b7f9cbf6ad411ed..f1684a8ad1398d52919a4a28d41c01457ecfb886 100644 (file)
@@ -5,8 +5,12 @@
 
 #ifndef __ASM__
 #include <hal/cpu.h>
+
+struct exec_param;
+
 typedef struct
 {
+    unsigned int depth;
     struct
     {
         reg32 eax;
@@ -20,9 +24,18 @@ typedef struct
         reg32 es;
         reg32 fs;
         reg32 gs;
-        reg32 esp;
     } __attribute__((packed)) registers;
 
+    union
+    {
+        reg32 esp;
+        volatile struct exec_param* execp;
+    };
+} __attribute__((packed)) isr_param;
+
+struct exec_param
+{
+    isr_param saved_prev_ctx;
     unsigned int vector;
     unsigned int err_code;
     unsigned int eip;
@@ -30,7 +43,9 @@ typedef struct
     unsigned int eflags;
     unsigned int esp;
     unsigned int ss;
-} __attribute__((packed)) isr_param;
+} __attribute__((packed));
+
+#define ISR_PARAM_SIZE sizeof(isr_param)
 
 void
 intr_handler(isr_param* param);
index 0029e363d759a4366d1b684351341145ce388f7f..27137a103db53763d07f7c28d02b5f9a5107df29 100644 (file)
@@ -52,9 +52,9 @@ struct proc_info
     pid_t pid;                // offset = 0
     struct proc_info* parent; // offset = 4
     isr_param intr_ctx;       // offset = 8
-    uintptr_t ustack_top;     // offset = 84
-    void* page_table;         // offset = 88
-    void* fxstate;            // offset = 92
+    uintptr_t ustack_top;     // offset = 84 -> 56 -> 60
+    void* page_table;         // offset = 88 -> 60 -> 64
+    void* fxstate;            // offset = 92 -> 64 -> 68
 
     /* ---- critical section end ---- */
 
index 2961f3b7d89f50a8f01677abbf1d452bc972b323..c869db0ede48fda280d41beb6c59c2cfba7f4216 100644 (file)
@@ -9,6 +9,8 @@
     .global debug_resv
     debug_resv:
         .skip 16
+    tmp_store:
+        .skip 4
 #endif
 
 .section .bss
     interrupt_wrapper:
         /*
          Stack layout (layout of struct isr_param)
-    msa:   [ss]
-           [esp]
-           eflags     > offset = 48 + 16 = 64
-           cs
-           eip
-           err_code   
-           vector     > offset = 28 + 16 + 4 = 48
+    msa:   [ss]             > 76
+           [esp]            > 72
+           eflags           > 68
+           cs               > 64
+           eip              > 60
+           err_code         > 56
+           vector           > offset = 52
+           [saved_prev_ctx] > offset = 0
+           ---
            esp
            gs
            fs
            es
-           ds         > offset = 7 * 4 = 28
+           ds         > offset = 7 * 4 = 28 + 4
            esi
            ebp
            edi
            edx
            ecx
            ebx
-    lsa:   eax        > offset = 0
+           eax
+    lsa:   depth       > offset = 0
 
             las: Least Significant Address
             msa: Most Significant Address
         */
         cld
+
+        subl $52, %esp
         pushl %esp
 
         subl $16, %esp
         pushl %ebx
         pushl %eax
 
-        movl 60(%esp), %eax   /* 取出 %cs */
+        movl __current, %eax
+        movl 8(%eax), %eax
+        incl %eax
+        pushl %eax          # nested intr: current depth
+
+        movl 116(%esp), %eax   /* 取出 %cs */
         andl $0x3, %eax          /* 判断 RPL */
         jz 1f
 
 
         # 保存用户栈顶指针。这是因为我们允许系统调用内进行上下文切换,而这样一来,我们就失去了用户栈的信息,
         # 这样一来,就无法设置信号上下文。这主要是为了实现了pause()而做的准备
-        movl (__current), %eax
+        movl __current, %eax
 
         # 保存x87FPU的状态
-        movl 92(%eax), %ebx
+        movl 68(%eax), %ebx
         fxsave (%ebx)
 
-        movl 68(%esp), %ebx     # 取出esp
-        movl %ebx, 84(%eax)     # 存入__current->ustack_top
+        movl 124(%esp), %ebx     # 取出esp
+        movl %ebx, 60(%eax)     # 存入__current->ustack_top
 
     1:
         movl %esp, %eax
 
 #ifdef __ASM_INTR_DIAGNOSIS
         movl %eax, (debug_resv + 8)
-        movl 56(%esp), %eax
-        movl %eax, (debug_resv + 4)
+        movl 48(%esp), %eax
+        movl 60(%eax), %eax
+        movl %eax, (debug_resv + 4) # eip
 #endif
-        movl (__current), %eax
-        movl 92(%eax), %eax
+        movl __current, %eax
+        movl 68(%eax), %eax
         
         test %eax, %eax     # do we have stored x87 context?
         jz 1f 
         fxrstor (%eax)      
 1:
+        popl %eax   # discard isr_param::depth
         popl %eax
         popl %ebx
         popl %ecx
 
         movl 16(%esp), %esp
 
+        movl %eax, tmp_store
+        movl __current, %eax
+        # nested intr: restore saved context
+        popl 8(%eax)       # depth
+        popl 12(%eax)      # eax
+        popl 16(%eax)      # ebx
+        popl 20(%eax)      # ecx
+        popl 24(%eax)      # edx
+        popl 28(%eax)      # edi
+        popl 32(%eax)      # ebp
+        popl 36(%eax)      # esi
+        popl 40(%eax)      # ds
+        popl 44(%eax)      # es
+        popl 48(%eax)      # fs
+        popl 52(%eax)      # gs
+        popl 56(%eax)      # esp
+
         addl $8, %esp
 
-        pushl %eax
 #ifdef __ASM_INTR_DIAGNOSIS
-        movl 4(%esp), %eax
+        movl (%esp), %eax
         movl %eax, debug_resv
 #endif
         # 处理TSS.ESP的一些边界条件。如果是正常iret(即从内核模式*优雅地*退出)
         # 那么TSS.ESP0应该为iret进行弹栈后,%esp的值。
         # 所以这里的边界条件是:如返回用户模式,iret会额外弹出8个字节(ss,esp)
-        movl 8(%esp), %eax
+        movl 4(%esp), %eax
         andl $3, %eax
         setnz %al
         shll $3, %eax
-        addl $16, %eax
+        addl $12, %eax
         addl %esp, %eax
         movl %eax, (_tss + 4)
-        popl %eax
+        movl tmp_store, %eax
         iret
 
     .global switch_to
 
         popl %ebx               # next
         movl __current, %eax    
-        movl 88(%eax), %ecx     # __current->pagetable
-        movl 88(%ebx), %eax     # next->pagetable
+        movl 64(%eax), %ecx     # __current->pagetable
+        movl 64(%ebx), %eax     # next->pagetable
         
         cmpl %ecx, %eax         # if(next->pagtable != __current->pagetable) {
         jz 1f
 
         pushl $UDATA_SEG        # proc_sig->prev_context.proc_regs.ss
         pushl %eax              # esp
-        pushl 64(%ebx)          # proc_sig->prev_context.proc_regs.eflags
+        movl 48(%ebx), %ebx
+        pushl 68(%ebx)          # proc_sig->prev_context.proc_regs.execp->eflags
         pushl $UCODE_SEG        # cs
         pushl $sig_wrapper      # eip for sig wrapper
 
         pushl %eax              # Addr to proc_sig structure 
         pushl 4(%eax)           # proc_sig->sig_num     ---- 16 bytes aligned
 
-        call (%eax)             # invoke signal handler
+        call *(%eax)             # invoke signal handler
 
         # invoke the sigreturn syscall to exit the signal wrapper
         movl $__SYSCALL_sigreturn, %eax
index 25b3791e7415f73af0d632d3702e020ced94a9a3..3fb24cbc054eab3d955078da2a27d42d35ee00e7 100644 (file)
@@ -19,26 +19,27 @@ extern x86_page_table* __kernel_ptd;
 void
 intr_handler(isr_param* param)
 {
+    param->execp->saved_prev_ctx = __current->intr_ctx;
     __current->intr_ctx = *param;
 
-    isr_param* lparam = &__current->intr_ctx;
+    volatile struct exec_param* execp = __current->intr_ctx.execp;
 
-    if (lparam->vector <= 255) {
-        isr_cb subscriber = isrm_get(lparam->vector);
+    if (execp->vector <= 255) {
+        isr_cb subscriber = isrm_get(execp->vector);
         subscriber(param);
         goto done;
     }
 
     kprint_panic("INT %u: (%x) [%p: %p] Unknown",
-                 lparam->vector,
-                 lparam->err_code,
-                 lparam->cs,
-                 lparam->eip);
+                 execp->vector,
+                 execp->err_code,
+                 execp->cs,
+                 execp->eip);
 
 done:
     // for all external interrupts except the spurious interrupt
     //  this is required by Intel Manual Vol.3A, section 10.8.1 & 10.8.5
-    if (lparam->vector >= IV_EX && lparam->vector != APIC_SPIV_IV) {
+    if (execp->vector >= IV_EX && execp->vector != APIC_SPIV_IV) {
         apic_done_servicing();
     }
 
index 97903cffebfdc5c1e3e145485e71825605527e90..f4bebae4159490173e9df5c693421ed503890121 100644 (file)
@@ -22,11 +22,12 @@ extern u32_t debug_resv;
 void
 __print_panic_msg(const char* msg, const isr_param* param)
 {
+    struct exec_param* execp = param->execp;
     kprint_panic("  INT %u: (%x) [%p: %p] %s",
-                 param->vector,
-                 param->err_code,
-                 param->cs,
-                 param->eip,
+                 execp->vector,
+                 execp->err_code,
+                 execp->cs,
+                 execp->eip,
                  msg);
 }
 
index f6c4355a1c0fabc58fc745b315bd4d74d0c604c6..2b0a8f1a4e81c234dbb09002fc82bab54126b2c6 100644 (file)
@@ -38,7 +38,7 @@ intr_routine_page_fault(const isr_param* param)
         goto segv_term;
     }
 
-    if (!SEL_RPL(param->cs)) {
+    if (!SEL_RPL(param->execp->cs)) {
         // 如果是内核页错误……
         if (do_kernel(&mapping)) {
             return;
@@ -130,8 +130,8 @@ segv_term:
     kprintf(KERROR "(pid: %d) Segmentation fault on %p (%p:%p)\n",
             __current->pid,
             ptr,
-            param->cs,
-            param->eip);
+            param->execp->cs,
+            param->execp->eip);
     __SIGSET(__current->sig_pending, _SIGSEGV);
     schedule();
     // should not reach
index bde7f36d9d79b6a0f2e59736be6fd5e4ad191fdc..62e07212264d300aed2a80d7aaee2c0d0267d635 100644 (file)
 .section .text
     syscall_hndlr:
         pushl %ebp
-        movl 8(%esp), %ebp
+        movl 8(%esp), %ebp          // isr_param*
 
-        movl  (%ebp), %eax          /* eax: call code as well as the return value from syscall */
-        cmpl  $__SYSCALL_MAX, %eax
+        addl $4, %ebp
+        movl (%ebp), %eax          /* eax: call code as well as the return value from syscall */
+        cmpl $__SYSCALL_MAX, %eax
         jae 2f
 
         shll $2, %eax
index e98be8883cd3bbeb3ca161ed8071fd016a594c52..a2edf1a9d5c66007b5ada75b4e93aa0e80ad92cb 100644 (file)
@@ -127,11 +127,7 @@ spawn_proc0()
     proc0->intr_ctx = (isr_param){ .registers = { .ds = KDATA_SEG,
                                                   .es = KDATA_SEG,
                                                   .fs = KDATA_SEG,
-                                                  .gs = KDATA_SEG },
-                                   .cs = KCODE_SEG,
-                                   .eip = (void*)__proc0,
-                                   .ss = KDATA_SEG,
-                                   .eflags = cpu_reflags() };
+                                                  .gs = KDATA_SEG } };
     proc0->parent = proc0;
 
     // 方案1:必须在读取eflags之后禁用。否则当进程被调度时,中断依然是关闭的!
@@ -155,19 +151,14 @@ spawn_proc0()
                         VMAP_NULL);
     }
 
-    // 手动设置进程上下文:用于第一次调度
-    asm volatile("movl %%esp, %%ebx\n"
-                 "movl %1, %%esp\n"
-                 "pushf\n"
-                 "pushl %2\n"
-                 "pushl %3\n"
-                 "pushl $0\n"
-                 "pushl $0\n"
-                 "movl %%esp, %0\n"
-                 "movl %%ebx, %%esp\n"
-                 : "=m"(proc0->intr_ctx.registers.esp)
-                 : "i"(KSTACK_TOP), "i"(KCODE_SEG), "r"(proc0->intr_ctx.eip)
-                 : "%ebx", "memory");
+    struct exec_param* execp =
+      (struct exec_param*)(KSTACK_TOP - sizeof(struct exec_param));
+
+    *execp = (struct exec_param){ .cs = KCODE_SEG,
+                                  .eip = (void*)__proc0,
+                                  .ss = KDATA_SEG,
+                                  .eflags = cpu_reflags() };
+    proc0->intr_ctx.execp = execp;
 
     // 加载x87默认配置
     asm volatile("fninit\n"
index 19a31c7a7626438839f142bccf9f7c30f20fb656..ade13b31c6414f4e1e1588b26645f255475f2c6c 100644 (file)
@@ -60,23 +60,23 @@ sched_init_dummy()
     extern void my_dummy();
     static char dummy_stack[DUMMY_STACK_SIZE] __attribute__((aligned(16)));
 
-    // memset to 0
-    dummy_proc = (struct proc_info){};
-    dummy_proc.intr_ctx = (isr_param){
-        .registers = { .ds = KDATA_SEG,
-                       .es = KDATA_SEG,
-                       .fs = KDATA_SEG,
-                       .gs = KDATA_SEG,
-                       .esp = (void*)dummy_stack + DUMMY_STACK_SIZE - 20 },
+    struct exec_param* execp =
+      (void*)dummy_stack + DUMMY_STACK_SIZE - sizeof(struct exec_param);
+
+    *execp = (struct exec_param){
         .cs = KCODE_SEG,
+        .eflags = cpu_reflags() | 0x0200,
         .eip = (void*)my_dummy,
         .ss = KDATA_SEG,
-        .eflags = cpu_reflags() | 0x0200
     };
 
-    *(u32_t*)(&dummy_stack[DUMMY_STACK_SIZE - 4]) = dummy_proc.intr_ctx.eflags;
-    *(u32_t*)(&dummy_stack[DUMMY_STACK_SIZE - 8]) = KCODE_SEG;
-    *(u32_t*)(&dummy_stack[DUMMY_STACK_SIZE - 12]) = dummy_proc.intr_ctx.eip;
+    // memset to 0
+    dummy_proc = (struct proc_info){};
+    dummy_proc.intr_ctx = (isr_param){ .registers = { .ds = KDATA_SEG,
+                                                      .es = KDATA_SEG,
+                                                      .fs = KDATA_SEG,
+                                                      .gs = KDATA_SEG },
+                                       .execp = execp };
 
     dummy_proc.page_table = cpu_rcr3();
     dummy_proc.state = PS_READY;
@@ -99,7 +99,7 @@ run(struct proc_info* proc)
         由于这中间没有进行地址空间的交换,所以第二次跳转使用的是同一个内核栈,而之前默认tss.esp0的值是永远指向最顶部
         这样一来就有可能会覆盖更早的上下文信息(比如嵌套的信号捕获函数)
     */
-    tss_update_esp(proc->intr_ctx.registers.esp);
+    tss_update_esp(proc->intr_ctx.esp);
 
     apic_done_servicing();