Browse Source

signal相关数据结构&代码结构优化 (#84)

* 解决由于spinlock.h中包含preempt_enable()带来的循环include问题

* new: 初步实现signal的数据结构
login 2 years ago
parent
commit
cffd7144fb

+ 2 - 2
.vscode/settings.json

@@ -150,11 +150,11 @@
         "cfs.h": "c",
         "err.h": "c",
         "rtc.h": "c",
-        "wait_queue_head.h": "c",
         "list.h": "c",
         "compiler.h": "c",
         "completion.h": "c",
-        "fat32.h": "c"
+        "fat32.h": "c",
+        "irqflags.h": "c"
     },
     "C_Cpp.errorSquiggles": "Enabled",
     "esbonio.sphinx.confDir": "",

+ 2 - 8
docs/kernel/sched/waiting.md

@@ -9,13 +9,7 @@
   当您需要等待一个事件完成时,使用wait_queue机制能减少进程同步的开销。相比于滥用自旋锁以及信号量,或者是循环使用usleep(1000)这样的函数来完成同步,wait_queue是一个高效的解决方案。
 
 :::{warning}
-`wait_queue.h`中的等待队列的实现并没有把队列头独立出来,同时没有考虑为等待队列加锁。所以在后来的开发中加入了`wait_queue_head.h`的队列头实现,实质上就是链表+自旋锁。它与`wait_queue.h`中的队列是兼容的,当你使用`struct wait_queue_head`作为队列头时,你同样可以使用等待队列添加节点的函数。
-
-但是在之后的版本中可能会把两者合并,目前仍然没有进行,且存在头文件相互引用的问题: 
- - "spin_lock.h" 引用了 "wait_queue.h"
- - "wait_queue_head.h" 引用了 "spin_lock.h";
-
-所以在合并之前必须解决这个问题。
+`wait_queue.h`中的等待队列的实现并没有把队列头独立出来,同时没有考虑为等待队列加锁。所以在后来的开发中加入了`wait_queue_head_t`的队列头实现,实质上就是链表+自旋锁。它与`wait_queue.h`中的队列`wait_queue_node_t`是兼容的,当你使用`struct wait_queue_head`作为队列头时,你同样可以使用等待队列添加节点的函数。
 :::
 
 ### 简单用法
@@ -89,7 +83,7 @@ typedef struct
 
    等待队列头的使用逻辑与等待队列实际是一样的,因为他同样也是等待队列的节点(仅仅多了一把锁)。且wait_queue_head的函数基本上与wait_queue一致,只不过多了\*\*\*\_with\_node\_\*\*\*的字符串。
 
-   同时,wait_queue_head.h文件中提供了很多的宏,可以方便您的工作。
+   同时,wait_queue.h文件中提供了很多的宏,可以方便您的工作。
 
 ### 提供的宏 
 | 宏                               | 解释                                                          |

+ 2 - 0
kernel/build.rs

@@ -20,6 +20,8 @@ fn main() {
     {
         let bindings = bindgen::Builder::default()
             .clang_arg("-I./src")
+            .clang_arg("-I./src/include")
+            .clang_arg("-I./src/arch/x86_64/include")   // todo: 当引入多种架构之后,需要修改这里,对于不同的架构编译时,include不同的路径
             // The input header we would like to generate
             // bindings for.
             .header("src/include/bindings/wrapper.h")

+ 1 - 1
kernel/src/Makefile

@@ -10,7 +10,7 @@ LIB_FILES := $(foreach DIR,$(DIR_LIB),$(addprefix $(DIR)/,$(lib_patterns)))
 
 # 控制操作系统使用的中断控制器 _INTR_8259A_ _INTR_APIC_
 PIC := _INTR_APIC_
-CFLAGS = $(GLOBAL_CFLAGS) -D $(PIC) -I $(shell pwd)
+CFLAGS = $(GLOBAL_CFLAGS) -D $(PIC) -I $(shell pwd) -I $(shell pwd)/include -I $(shell pwd)/arch/x86_64/include
 
 export ASFLAGS := --64
 

+ 17 - 5
kernel/src/arch/x86_64/Makefile

@@ -1,10 +1,22 @@
+
 CFLAGS += -I .
 
-all: x86_64_ipi.o ia64_msi.o
+kernel_arch_x86_64_subdirs:= asm
+
+kernel_arch_x86_64_objs:= $(shell find ./*.c)
+
+ECHO:
+	@echo "$@"
+
+
+$(kernel_arch_x86_64_objs): ECHO
+	$(CC) $(CFLAGS) -c $@ -o [email protected]
+
+$(kernel_arch_x86_64_subdirs): ECHO
+	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
 
-x86_64_ipi.o: x86_64_ipi.c
-	$(CC) $(CFLAGS) -c x86_64_ipi.c -o x86_64_ipi.o
+all: $(kernel_arch_x86_64_objs) $(kernel_arch_x86_64_subdirs)
 
-ia64_msi.o: ia64_msi.c
-	$(CC) $(CFLAGS) -c ia64_msi.c -o ia64_msi.o
 
+clean:
+	echo "Done."

+ 22 - 0
kernel/src/arch/x86_64/asm/Makefile

@@ -0,0 +1,22 @@
+
+CFLAGS += -I .
+
+# kernel_arch_x86_64_asm_subdirs:= 
+
+kernel_arch_x86_64_asm_objs:= $(shell find ./*.c)
+
+ECHO:
+	@echo "$@"
+
+
+$(kernel_arch_x86_64_asm_objs): ECHO
+	$(CC) $(CFLAGS) -c $@ -o [email protected]
+
+# $(kernel_arch_x86_64_asm_subdirs): ECHO
+# 	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
+
+all: $(kernel_arch_x86_64_asm_objs)
+
+
+clean:
+	echo "Done."

+ 56 - 0
kernel/src/arch/x86_64/asm/spinlock.c

@@ -0,0 +1,56 @@
+#include <common/spinlock.h>
+#include <process/preempt.h>
+
+void __arch_spin_lock(spinlock_t *lock)
+{
+    __asm__ __volatile__("1:    \n\t"
+                         "lock decb %0   \n\t" // 尝试-1
+                         "jns 3f    \n\t"      // 加锁成功,跳转到步骤3
+                         "2:    \n\t"          // 加锁失败,稍后再试
+                         "pause \n\t"
+                         "cmpb $0, %0   \n\t"
+                         "jle   2b  \n\t" // 若锁被占用,则继续重试
+                         "jmp 1b    \n\t" // 尝试加锁
+                         "3:"
+                         : "=m"(lock->lock)::"memory");
+    preempt_disable();
+}
+
+void __arch_spin_unlock(spinlock_t *lock)
+{
+    preempt_enable();
+    __asm__ __volatile__("movb $1, %0   \n\t" : "=m"(lock->lock)::"memory");
+}
+
+void __arch_spin_lock_no_preempt(spinlock_t *lock)
+{
+    __asm__ __volatile__("1:    \n\t"
+                         "lock decb %0   \n\t" // 尝试-1
+                         "jns 3f    \n\t"      // 加锁成功,跳转到步骤3
+                         "2:    \n\t"          // 加锁失败,稍后再试
+                         "pause \n\t"
+                         "cmpb $0, %0   \n\t"
+                         "jle   2b  \n\t" // 若锁被占用,则继续重试
+                         "jmp 1b    \n\t" // 尝试加锁
+                         "3:"
+                         : "=m"(lock->lock)::"memory");
+}
+
+void __arch_spin_unlock_no_preempt(spinlock_t *lock)
+{
+    __asm__ __volatile__("movb $1, %0   \n\t" : "=m"(lock->lock)::"memory");
+}
+
+long __arch_spin_trylock(spinlock_t *lock)
+{
+    uint64_t tmp_val = 0;
+    preempt_disable();
+    // 交换tmp_val和lock的值,若tmp_val==1则证明加锁成功
+    asm volatile("lock xchg %%bx, %1  \n\t" // 确保只有1个进程能得到锁
+                 : "=q"(tmp_val), "=m"(lock->lock)
+                 : "b"(0)
+                 : "memory");
+    if (!tmp_val)
+        preempt_enable();
+    return tmp_val;
+}

+ 0 - 0
kernel/src/arch/x86_64/current.h → kernel/src/arch/x86_64/include/asm/current.h


+ 10 - 0
kernel/src/arch/x86_64/include/asm/irqflags.h

@@ -0,0 +1,10 @@
+#pragma once
+
+// 保存当前rflags的值到变量x内并关闭中断
+#define local_irq_save(x) __asm__ __volatile__("pushfq ; popq %0 ; cli" \
+                                               : "=g"(x)::"memory")
+// 恢复先前保存的rflags的值x
+#define local_irq_restore(x) __asm__ __volatile__("pushq %0 ; popfq" ::"g"(x) \
+                                                  : "memory")
+#define local_irq_disable() cli();
+#define local_irq_enable() sti();

+ 1 - 1
kernel/src/common/completion.h

@@ -1,5 +1,5 @@
 #include <common/spinlock.h>
-#include <common/wait_queue_head.h>
+#include <common/wait_queue.h>
 #include <process/process.h>
 #include <time/sleep.h>
 #include <time/timer.h>

+ 36 - 67
kernel/src/common/spinlock.h

@@ -9,8 +9,8 @@
  *
  */
 #pragma once
+#include <asm/irqflags.h>
 #include <common/glib.h>
-#include <process/preempt.h>
 #include <debug/bug.h>
 
 /**
@@ -22,6 +22,14 @@ typedef struct
     int8_t lock; // 1:unlocked 0:locked
 } spinlock_t;
 
+extern void __arch_spin_lock(spinlock_t *lock);
+extern void __arch_spin_unlock(spinlock_t *lock);
+
+extern void __arch_spin_lock_no_preempt(spinlock_t *lock);
+extern void __arch_spin_unlock_no_preempt(spinlock_t *lock);
+
+extern long __arch_spin_trylock(spinlock_t *lock);
+
 /**
  * @brief 自旋锁加锁
  *
@@ -29,17 +37,7 @@ typedef struct
  */
 void spin_lock(spinlock_t *lock)
 {
-    __asm__ __volatile__("1:    \n\t"
-                         "lock decb %0   \n\t" // 尝试-1
-                         "jns 3f    \n\t"      // 加锁成功,跳转到步骤3
-                         "2:    \n\t"          // 加锁失败,稍后再试
-                         "pause \n\t"
-                         "cmpb $0, %0   \n\t"
-                         "jle   2b  \n\t" // 若锁被占用,则继续重试
-                         "jmp 1b    \n\t" // 尝试加锁
-                         "3:"
-                         : "=m"(lock->lock)::"memory");
-    preempt_disable();
+    __arch_spin_lock(lock);
 }
 
 /**
@@ -49,9 +47,7 @@ void spin_lock(spinlock_t *lock)
  */
 void spin_unlock(spinlock_t *lock)
 {
-    preempt_enable();
-    __asm__ __volatile__("movb $1, %0   \n\t"
-                         : "=m"(lock->lock)::"memory");
+    __arch_spin_unlock(lock);
 }
 
 /**
@@ -73,17 +69,9 @@ void spin_init(spinlock_t *lock)
  */
 void spin_lock_no_preempt(spinlock_t *lock)
 {
-    __asm__ __volatile__("1:    \n\t"
-                         "lock decb %0   \n\t" // 尝试-1
-                         "jns 3f    \n\t"      // 加锁成功,跳转到步骤3
-                         "2:    \n\t"          // 加锁失败,稍后再试
-                         "pause \n\t"
-                         "cmpb $0, %0   \n\t"
-                         "jle   2b  \n\t" // 若锁被占用,则继续重试
-                         "jmp 1b    \n\t" // 尝试加锁
-                         "3:"
-                         : "=m"(lock->lock)::"memory");
+    __arch_spin_lock_no_preempt(lock);
 }
+
 /**
  * @brief 自旋锁解锁(不改变自旋锁持有计数)
  *
@@ -91,8 +79,7 @@ void spin_lock_no_preempt(spinlock_t *lock)
  */
 void spin_unlock_no_preempt(spinlock_t *lock)
 {
-    __asm__ __volatile__("movb $1, %0   \n\t"
-                         : "=m"(lock->lock)::"memory");
+    __arch_spin_unlock_no_preempt(lock);
 }
 
 /**
@@ -103,74 +90,56 @@ void spin_unlock_no_preempt(spinlock_t *lock)
  */
 long spin_trylock(spinlock_t *lock)
 {
-    uint64_t tmp_val = 0;
-    preempt_disable();
-    // 交换tmp_val和lock的值,若tmp_val==1则证明加锁成功
-    asm volatile("lock xchg %%bx, %1  \n\t" // 确保只有1个进程能得到锁
-                 : "=q"(tmp_val), "=m"(lock->lock)
-                 : "b"(0)
-                 : "memory");
-    if (!tmp_val)
-        preempt_enable();
-    return tmp_val;
+    return __arch_spin_trylock(lock);
 }
 
-// 保存当前rflags的值到变量x内并关闭中断
-#define local_irq_save(x) __asm__ __volatile__("pushfq ; popq %0 ; cli" \
-                                               : "=g"(x)::"memory")
-// 恢复先前保存的rflags的值x
-#define local_irq_restore(x) __asm__ __volatile__("pushq %0 ; popfq" ::"g"(x) \
-                                                  : "memory")
-#define local_irq_disable() cli();
-#define local_irq_enable() sti();
-
 /**
  * @brief 保存中断状态,关闭中断,并自旋锁加锁
  *
  */
-#define spin_lock_irqsave(lock, flags) \
-    do                                 \
-    {                                  \
-        local_irq_save(flags);         \
-        spin_lock(lock);               \
+#define spin_lock_irqsave(lock, flags)                                                                                 \
+    do                                                                                                                 \
+    {                                                                                                                  \
+        local_irq_save(flags);                                                                                         \
+        spin_lock(lock);                                                                                               \
     } while (0)
 
 /**
  * @brief 恢复rflags以及中断状态并解锁自旋锁
  *
  */
-#define spin_unlock_irqrestore(lock, flags) \
-    do                                      \
-    {                                       \
-        spin_unlock(lock);                  \
-        local_irq_restore(flags);           \
+#define spin_unlock_irqrestore(lock, flags)                                                                            \
+    do                                                                                                                 \
+    {                                                                                                                  \
+        spin_unlock(lock);                                                                                             \
+        local_irq_restore(flags);                                                                                      \
     } while (0)
 
 /**
  * @brief 关闭中断并加锁
  *
  */
-#define spin_lock_irq(lock)  \
-    do                       \
-    {                        \
-        local_irq_disable(); \
-        spin_lock(lock);     \
+#define spin_lock_irq(lock)                                                                                            \
+    do                                                                                                                 \
+    {                                                                                                                  \
+        local_irq_disable();                                                                                           \
+        spin_lock(lock);                                                                                               \
     } while (0)
 
 /**
  * @brief 解锁并开启中断
  *
  */
-#define spin_unlock_irq(lock) \
-    do                        \
-    {                         \
-        spin_unlock(lock);    \
-        local_irq_enable();   \
+#define spin_unlock_irq(lock)                                                                                          \
+    do                                                                                                                 \
+    {                                                                                                                  \
+        spin_unlock(lock);                                                                                             \
+        local_irq_enable();                                                                                            \
     } while (0)
 
 /**
  * @brief 判断自旋锁是否已经加锁
- * 
+ *
  * @param lock 待判断的自旋锁
  * @return true 已经加锁
  * @return false 尚未加锁

+ 1 - 1
kernel/src/common/sys/types.h

@@ -13,7 +13,7 @@ typedef uint32_t gid_t;
 typedef long long ssize_t;
 
 typedef int __pid_t;
-#define pid_t uint64_t
+#define pid_t int64_t
 typedef __SIZE_TYPE__ size_t;
 
 typedef char *caddr_t;

+ 72 - 3
kernel/src/common/wait_queue.h

@@ -1,5 +1,9 @@
 #pragma once
 #include <common/glib.h>
+#include <common/spinlock.h>
+struct process_control_block;
+
+// todo: 按照linux里面的样子,修正等待队列。也就是修正好wait_queue_node和wait_queue_head的意思。
 
 /**
  * @brief 信号量的等待队列
@@ -31,8 +35,7 @@ void wait_queue_sleep_on(wait_queue_node_t *wait_queue_head);
  *
  * @param wait_queue_head 队列头指针
  */
-void wait_queue_sleep_on_unlock(wait_queue_node_t *wait_queue_head,
-                                void *lock);
+void wait_queue_sleep_on_unlock(wait_queue_node_t *wait_queue_head, void *lock);
 /**
  * @brief 在等待队列上进行等待(允许中断)
  *
@@ -46,4 +49,70 @@ void wait_queue_sleep_on_interriptible(wait_queue_node_t *wait_queue_head);
  * @param wait_queue_head 队列头
  * @param state 要唤醒的进程的状态
  */
-void wait_queue_wakeup(wait_queue_node_t *wait_queue_head, int64_t state);
+void wait_queue_wakeup(wait_queue_node_t *wait_queue_head, int64_t state);
+
+typedef struct
+{
+    struct List wait_list;
+    spinlock_t lock; // 队列需要有一个自旋锁,虽然目前内部并没有使用,但是以后可能会用.[在completion内部使用]
+} wait_queue_head_t;
+
+#define DECLARE_WAIT_ON_STACK(name, pcb) \
+    wait_queue_node_t name = {0};        \
+    wait_queue_init(&(name), pcb);
+
+#define DECLARE_WAIT_ON_STACK_SELF(name) \
+    wait_queue_node_t name = {0};        \
+    wait_queue_init(&(name), current_pcb);
+
+#define DECLARE_WAIT_ALLOC(name, pcb)                                                     \
+    wait_queue_node_t *wait = (wait_queue_node_t *)kzalloc(sizeof(wait_queue_node_t), 0); \
+    wait_queue_init(&(name), pcb);
+
+#define DECLARE_WAIT_ALLOC_SELF(name)                                                     \
+    wait_queue_node_t *wait = (wait_queue_node_t *)kzalloc(sizeof(wait_queue_node_t), 0); \
+    wait_queue_init(&(name), current_pcb);
+
+#define DECLARE_WAIT_QUEUE_HEAD(name)    \
+    struct wait_queue_head_t name = {0}; \
+    wait_queue_head_init(&name);
+
+/**
+ * @brief 初始化wait_queue队列头
+ *
+ * @param wait_queue
+ */
+void wait_queue_head_init(wait_queue_head_t *wait_queue);
+
+/**
+ * @brief 在等待队列上进行等待, 但是你需要确保wait已经被init, 同时wakeup只能使用wake_up_on_stack函数。
+ *
+ * @param q 队列头指针
+ * @param wait wait节点
+ */
+void wait_queue_sleep_with_node(wait_queue_head_t *q, wait_queue_node_t *wait);
+
+/**
+ * @brief  在等待队列上进行等待,同时释放自旋锁, 但是你需要确保wait已经被init, 同时wakeup只能使用wake_up_on_stack函数。
+ *
+ * @param q  队列头指针
+ * @param wait wait节点
+ * @param lock
+ */
+void wait_queue_sleep_with_node_unlock(wait_queue_head_t *q, wait_queue_node_t *wait, void *lock);
+
+/**
+ * @brief 在等待队列上进行等待(允许中断), 但是你需要确保wait已经被init, 同时wakeup只能使用wake_up_on_stack函数。
+ *
+ * @param wait_queue_head 队列头指针
+ * @param wait wait节点
+ */
+void wait_queue_sleep_with_node_interriptible(wait_queue_head_t *q, wait_queue_node_t *wait);
+
+/**
+ * @brief 唤醒在等待队列的头部的进程, 但是不会free掉这个节点的空间(默认这个节点在栈上创建)
+ *
+ * @param wait_queue_head_t  q: 队列头
+ * @param state 要唤醒的进程的状态
+ */
+void wait_queue_wakeup_on_stack(wait_queue_head_t *q, int64_t state);

+ 0 - 68
kernel/src/common/wait_queue_head.h

@@ -1,68 +0,0 @@
-#include <common/spinlock.h>
-#include <common/wait_queue.h>
-
-typedef struct
-{
-    struct List wait_list;
-    spinlock_t lock; // 队列需要有一个自旋锁,虽然目前内部并没有使用,但是以后可能会用.[在completion内部使用]
-} wait_queue_head_t;
-
-#define DECLARE_WAIT_ON_STACK(name, pcb) \
-    wait_queue_node_t name = {0};        \
-    wait_queue_init(&(name), pcb);
-
-#define DECLARE_WAIT_ON_STACK_SELF(name) \
-    wait_queue_node_t name = {0};        \
-    wait_queue_init(&(name), current_pcb);
-
-#define DECLARE_WAIT_ALLOC(name, pcb)                                                     \
-    wait_queue_node_t *wait = (wait_queue_node_t *)kzalloc(sizeof(wait_queue_node_t), 0); \
-    wait_queue_init(&(name), pcb);
-
-#define DECLARE_WAIT_ALLOC_SELF(name)                                                     \
-    wait_queue_node_t *wait = (wait_queue_node_t *)kzalloc(sizeof(wait_queue_node_t), 0); \
-    wait_queue_init(&(name), current_pcb);
-
-#define DECLARE_WAIT_QUEUE_HEAD(name)    \
-    struct wait_queue_head_t name = {0}; \
-    wait_queue_head_init(&name);
-
-/**
- * @brief 初始化wait_queue队列头
- *
- * @param wait_queue
- */
-void wait_queue_head_init(wait_queue_head_t *wait_queue);
-
-/**
- * @brief 在等待队列上进行等待, 但是你需要确保wait已经被init, 同时wakeup只能使用wake_up_on_stack函数。
- *
- * @param q 队列头指针
- * @param wait wait节点
- */
-void wait_queue_sleep_with_node(wait_queue_head_t *q, wait_queue_node_t *wait);
-
-/**
- * @brief  在等待队列上进行等待,同时释放自旋锁, 但是你需要确保wait已经被init, 同时wakeup只能使用wake_up_on_stack函数。
- *
- * @param q  队列头指针
- * @param wait wait节点
- * @param lock
- */
-void wait_queue_sleep_with_node_unlock(wait_queue_head_t *q, wait_queue_node_t *wait, void *lock);
-
-/**
- * @brief 在等待队列上进行等待(允许中断), 但是你需要确保wait已经被init, 同时wakeup只能使用wake_up_on_stack函数。
- *
- * @param wait_queue_head 队列头指针
- * @param wait wait节点
- */
-void wait_queue_sleep_with_node_interriptible(wait_queue_head_t *q, wait_queue_node_t *wait);
-
-/**
- * @brief 唤醒在等待队列的头部的进程, 但是不会free掉这个节点的空间(默认这个节点在栈上创建)
- *
- * @param wait_queue_head_t  q: 队列头
- * @param state 要唤醒的进程的状态
- */
-void wait_queue_wakeup_on_stack(wait_queue_head_t *q, int64_t state);

+ 0 - 0
kernel/src/include/gfp.rs → kernel/src/include/DragonOS/gfp.rs


+ 3 - 0
kernel/src/include/DragonOS/mod.rs

@@ -0,0 +1,3 @@
+pub mod gfp;
+pub mod printk;
+pub mod signal;

+ 0 - 0
kernel/src/include/printk.rs → kernel/src/include/DragonOS/printk.rs


+ 6 - 0
kernel/src/include/DragonOS/refcount.h

@@ -0,0 +1,6 @@
+#pragma once
+#include <common/atomic.h>
+
+typedef struct refcount_struct {
+	atomic_t refs;
+} refcount_t;

+ 88 - 0
kernel/src/include/DragonOS/signal.h

@@ -0,0 +1,88 @@
+#pragma once
+#include <DragonOS/refcount.h>
+#include <common/atomic.h>
+#include <common/list.h>
+#include <common/spinlock.h>
+#include <common/sys/types.h>
+#include <common/wait_queue.h>
+
+// 系统最大支持的信号数量
+#define MAX_SIG_NUM 64
+
+typedef void __signalfn_t(int);
+typedef __signalfn_t *__sighandler_t;
+
+typedef uint64_t sigset_t;
+
+union __sifields {
+    /* kill() */
+    struct
+    {
+        pid_t _pid; /* 信号发送者的pid */
+    } _kill;
+};
+
+// 注意,该结构体最大大小为32字节
+#define __SIGINFO                                                                                                      \
+    struct                                                                                                             \
+    {                                                                                                                  \
+        int32_t si_signo; /* signal number */                                                                          \
+        int32_t code;                                                                                                  \
+        int32_t si_errno;                                                                                              \
+        union __sifields _sifields;                                                                                    \
+    }
+
+struct siginfo
+{
+    union {
+        __SIGINFO;
+        uint64_t padding[4]; // 让siginfo占用32字节大小
+    };
+};
+
+/**
+ * @brief 信号处理结构体
+ *
+ */
+struct sigaction
+{
+    // 信号处理函数的指针
+    union {
+        __sighandler_t _sa_handler;
+        void (*_sa_sigaction)(int sig, struct siginfo *sinfo, void *);
+    } _u;
+    uint64_t sa_flags;
+    sigset_t sa_mask;
+    void (*sa_restorer)(void); // 暂时未实现
+};
+
+/**
+ * 由于signal_struct总是和sighand_struct一起使用,并且信号处理的过程中必定会对sighand加锁,
+ * 因此signal_struct不用加锁
+ */
+struct signal_struct
+{
+    atomic_t sig_cnt;
+};
+
+/**
+ * @brief 信号处理结构体,位于pcb之中。
+ *
+ */
+struct sighand_struct
+{
+    spinlock_t siglock;
+    refcount_t count;
+    wait_queue_head_t signal_fd_wqh;
+    // 为每个信号注册的处理函数的结构体
+    struct sigaction action[MAX_SIG_NUM];
+};
+
+/**
+ * @brief 正在等待的信号的标志位
+ *
+ */
+struct sigpending
+{
+    sigset_t signal;
+};

+ 113 - 0
kernel/src/include/DragonOS/signal.rs

@@ -0,0 +1,113 @@
+#![allow(non_camel_case_types)]
+// 这是signal暴露给其他模块的公有的接口文件
+
+// todo: 将这里更换为手动编写的ffi绑定
+use crate::include::bindings::bindings::atomic_t;
+use crate::include::bindings::bindings::refcount_t;
+use crate::include::bindings::bindings::spinlock_t;
+use crate::include::bindings::bindings::wait_queue_head_t;
+
+pub type sigset_t = u64;
+pub type __signalfn_t = ::core::option::Option<unsafe extern "C" fn(arg1: ::core::ffi::c_int)>;
+pub type __sighandler_t = __signalfn_t;
+
+/// 由于signal_struct总是和sighand_struct一起使用,并且信号处理的过程中必定会对sighand加锁
+/// 因此signal_struct不用加锁
+/// **请将该结构体与`include/DragonOS/signal.h`中的保持同步**
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct signal_struct {
+    pub sig_cnt: atomic_t,
+}
+
+/**
+ * sigaction中的信号处理函数结构体
+ * 分为两种处理函数
+ */
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union sigaction__union_u {
+    pub _sa_handler: __sighandler_t, // 传统处理函数
+    pub _sa_sigaction: ::core::option::Option<
+        unsafe extern "C" fn(
+            sig: ::core::ffi::c_int,
+            sinfo: *mut siginfo,
+            arg1: *mut ::core::ffi::c_void,
+        ),
+    >,
+}
+
+/**
+ * @brief 信号处理结构体
+ */
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct sigaction {
+    pub _u: sigaction__union_u,
+    pub sa_flags: u64,
+    pub sa_mask: sigset_t,
+    pub sa_restorer: ::core::option::Option<unsafe extern "C" fn()>, // 暂时未实现该函数
+}
+
+/**
+ * 信号消息的结构体,作为参数传入sigaction结构体中指向的处理函数
+ */
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct siginfo {
+    pub _sinfo: __siginfo_union,
+}
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union __siginfo_union {
+    pub data: __siginfo_union_data,
+    pub padding: [u64; 4usize],
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct __siginfo_union_data {
+    pub si_signo: i32,
+    pub code: i32,
+    pub si_errno: i32,
+    pub _sifields: __sifields,
+}
+
+/**
+ * siginfo中,根据signal的来源不同,该union中对应了不同的数据
+ */
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub union __sifields {
+    pub _kill: __sifields__kill,
+}
+
+/**
+ * 来自kill命令的signal
+ */
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct __sifields__kill {
+    pub _pid: i64, /* 发起kill的进程的pid */
+}
+
+/**
+ * @brief 信号处理结构体,位于pcb之中
+ */
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct sighand_struct {
+    pub siglock: spinlock_t,
+    pub count: refcount_t,
+    pub signal_fd_wqh: wait_queue_head_t,
+    pub action: [sigaction; 64usize],
+}
+
+/**
+ * @brief 正在等待的信号的标志位
+ */
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct sigpending {
+    pub signal: sigset_t,
+}

+ 2 - 0
kernel/src/include/bindings/wrapper.h

@@ -23,6 +23,8 @@
 #include <common/spinlock.h>
 #include <common/unistd.h>
 #include <driver/uart/uart.h>
+#include <include/DragonOS/refcount.h>
+#include <include/DragonOS/signal.h>
 #include <mm/mm.h>
 #include <mm/slab.h>
 #include <sched/cfs.h>

+ 2 - 3
kernel/src/include/mod.rs

@@ -1,4 +1,3 @@
+#![allow(non_snake_case)]
 pub mod bindings;
-pub mod gfp;
-pub mod printk;
-
+pub mod DragonOS;

+ 1 - 0
kernel/src/ipc/mod.rs

@@ -0,0 +1 @@
+pub mod signal;

+ 0 - 0
kernel/src/ipc/signal.rs


+ 1 - 0
kernel/src/lib.rs

@@ -15,6 +15,7 @@ use core::panic::PanicInfo;
 mod mm;
 mod include;
 mod libs;
+mod ipc;
 
 extern crate alloc;
 

+ 1 - 1
kernel/src/libs/wait_queue_head.c

@@ -1,4 +1,4 @@
-#include <common/wait_queue_head.h>
+#include <common/wait_queue.h>
 #include <process/process.h>
 #include <sched/sched.h>
 

+ 1 - 1
kernel/src/mm/allocator.rs

@@ -1,5 +1,5 @@
 use crate::include::bindings::bindings::{gfp_t, kfree, kmalloc, PAGE_2M_SIZE};
-use crate::include::gfp::__GFP_ZERO;
+use crate::include::DragonOS::gfp::__GFP_ZERO;
 
 use core::alloc::{GlobalAlloc, Layout};
 

+ 18 - 20
kernel/src/mm/mm.h

@@ -1,7 +1,8 @@
 #pragma once
 
-#include <common/glib.h>
+#include <asm/current.h>
 #include <common/gfp.h>
+#include <common/glib.h>
 #include <mm/mm-types.h>
 #include <process/process.h>
 
@@ -48,7 +49,7 @@
 #define IO_APIC_MAPPING_OFFSET 0xfec00000UL
 #define LOCAL_APIC_MAPPING_OFFSET 0xfee00000UL
 #define AHCI_MAPPING_OFFSET 0xff200000UL // AHCI 映射偏移量,之后使用了4M的地址
-#define XHCI_MAPPING_OFFSET 0x100000000  // XHCI控制器映射偏移量(后方请预留1GB的虚拟空间来映射不同的controller)
+#define XHCI_MAPPING_OFFSET 0x100000000 // XHCI控制器映射偏移量(后方请预留1GB的虚拟空间来映射不同的controller)
 
 // ===== 内存区域属性 =====
 // DMA区域
@@ -145,16 +146,15 @@
  * @brief 刷新TLB的宏定义
  * 由于任何写入cr3的操作都会刷新TLB,因此这个宏定义可以刷新TLB
  */
-#define flush_tlb()                 \
-    do                              \
-    {                               \
-        ul tmp;                     \
-        io_mfence();                \
-        __asm__ __volatile__(       \
-            "movq %%cr3, %0\n\t"    \
-            "movq %0, %%cr3\n\t"    \
-            : "=r"(tmp)::"memory"); \
-                                    \
+#define flush_tlb()                                                                                                    \
+    do                                                                                                                 \
+    {                                                                                                                  \
+        ul tmp;                                                                                                        \
+        io_mfence();                                                                                                   \
+        __asm__ __volatile__("movq %%cr3, %0\n\t"                                                                      \
+                             "movq %0, %%cr3\n\t"                                                                      \
+                             : "=r"(tmp)::"memory");                                                                   \
+                                                                                                                       \
     } while (0);
 
 /**
@@ -231,9 +231,7 @@ unsigned long page_init(struct Page *page, ul flags);
 unsigned long *get_CR3()
 {
     ul *tmp;
-    __asm__ __volatile__(
-        "movq %%cr3, %0\n\t"
-        : "=r"(tmp)::"memory");
+    __asm__ __volatile__("movq %%cr3, %0\n\t" : "=r"(tmp)::"memory");
     return tmp;
 }
 
@@ -420,7 +418,8 @@ int mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flags
  * @param flush 是否刷新tlb
  * @param use4k 是否使用4k页
  */
-int mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool user, bool flush, bool use4k);
+int mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul phys_addr_start, ul length,
+                           ul flags, bool user, bool flush, bool use4k);
 
 int mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul flags);
 
@@ -440,9 +439,7 @@ void mm_unmap_proc_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_sta
  * @param virt_addr 虚拟地址
  * @param length 地址长度
  */
-#define mm_unmap_addr(virt_addr, length) ({                            \
-    mm_unmap_proc_table((uint64_t)get_CR3(), true, virt_addr, length); \
-})
+#define mm_unmap_addr(virt_addr, length) ({ mm_unmap_proc_table((uint64_t)get_CR3(), true, virt_addr, length); })
 
 /**
  * @brief 创建VMA
@@ -455,7 +452,8 @@ void mm_unmap_proc_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_sta
  * @param res_vma 返回的vma指针
  * @return int 错误码
  */
-int mm_create_vma(struct mm_struct *mm, uint64_t vaddr, uint64_t length, vm_flags_t vm_flags, struct vm_operations_t *vm_ops, struct vm_area_struct **res_vma);
+int mm_create_vma(struct mm_struct *mm, uint64_t vaddr, uint64_t length, vm_flags_t vm_flags,
+                  struct vm_operations_t *vm_ops, struct vm_area_struct **res_vma);
 
 /**
  * @brief 将指定的物理地址映射到指定的vma处

+ 2 - 5
kernel/src/process/preempt.h

@@ -1,10 +1,7 @@
 #pragma once
 
-#if ARCH(X86_64)
-#include <arch/x86_64/current.h>
-#else
-#error Unsupported architecture!
-#endif
+#include <asm/current.h>
+
 #include "proc-types.h"
 
 /**

+ 11 - 1
kernel/src/process/proc-types.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include <common/wait_queue.h>
+#include <DragonOS/signal.h>
 
 // 进程最大可拥有的文件描述符数量
 #define PROC_MAX_FD_NUM 16
@@ -73,7 +74,7 @@ struct process_control_block
     // 进程标志:进程、线程、内核线程
     unsigned long flags;
     int64_t preempt_count; // 持有的自旋锁的数量
-    long signal;
+    
     long cpu_id; // 当前进程在哪个CPU核心上运行
     char name[PCB_NAME_LEN];
 
@@ -114,6 +115,15 @@ struct process_control_block
 
     /* PF_kTHREAD  | PF_IO_WORKER 的进程,worker_private不为NULL*/
     void *worker_private;
+
+    // ==== 信号处理相关 =====
+    struct signal_struct *signal;
+    struct sighand_struct *sighand;
+    // 一个bitmap,表示被阻塞的信号
+    sigset_t blocked;
+    // 正在等待的信号的标志位,表示某个信号正在等待处理
+    struct sigpending sig_pending;
+
 };
 
 // 将进程的pcb和内核栈融合到一起,8字节对齐

+ 50 - 77
kernel/src/process/process.h

@@ -9,45 +9,27 @@
  */
 
 #pragma once
-#include <common/cpu.h>
-#include <common/glib.h>
-#include <syscall/syscall.h>
 #include "ptrace.h"
+#include <common/cpu.h>
 #include <common/errno.h>
-#include <filesystem/VFS/VFS.h>
+#include <common/glib.h>
 #include <common/wait_queue.h>
+#include <filesystem/VFS/VFS.h>
 #include <mm/mm-types.h>
+#include <syscall/syscall.h>
 
-#if ARCH(I386) || ARCH(X86_64)
-#include <arch/x86_64/current.h>
-#else
-#error Unsupported architecture!
-#endif
+#include <asm/current.h>
 
 #include "proc-types.h"
 
 // 设置初始进程的PCB
-#define INITIAL_PROC(proc)                \
-	{                                     \
-		.state = PROC_UNINTERRUPTIBLE,    \
-		.flags = PF_KTHREAD,              \
-		.preempt_count = 0,               \
-		.signal = 0,                      \
-		.cpu_id = 0,                      \
-		.mm = &initial_mm,                \
-		.thread = &initial_thread,        \
-		.addr_limit = 0xffffffffffffffff, \
-		.pid = 0,                         \
-		.priority = 2,                    \
-		.virtual_runtime = 0,             \
-		.fds = {0},                       \
-		.next_pcb = &proc,                \
-		.parent_pcb = &proc,              \
-		.exit_code = 0,                   \
-		.wait_child_proc_exit = 0,        \
-		.worker_private = NULL,           \
-		.policy = SCHED_NORMAL            \
-	}
+#define INITIAL_PROC(proc)                                                                                             \
+    {                                                                                                                  \
+        .state = PROC_UNINTERRUPTIBLE, .flags = PF_KTHREAD, .preempt_count = 0, .signal = 0, .cpu_id = 0,              \
+        .mm = &initial_mm, .thread = &initial_thread, .addr_limit = 0xffffffffffffffff, .pid = 0, .priority = 2,       \
+        .virtual_runtime = 0, .fds = {0}, .next_pcb = &proc, .parent_pcb = &proc, .exit_code = 0,                      \
+        .wait_child_proc_exit = 0, .worker_private = NULL, .policy = SCHED_NORMAL                                      \
+    }
 
 /**
  * @brief 任务状态段结构体
@@ -55,28 +37,19 @@
  */
 
 // 设置初始进程的tss
-#define INITIAL_TSS                                                       \
-	{                                                                     \
-		.reserved0 = 0,                                                   \
-		.rsp0 = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)), \
-		.rsp1 = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)), \
-		.rsp2 = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)), \
-		.reserved1 = 0,                                                   \
-		.ist1 = 0xffff800000007c00,                                       \
-		.ist2 = 0xffff800000007c00,                                       \
-		.ist3 = 0xffff800000007c00,                                       \
-		.ist4 = 0xffff800000007c00,                                       \
-		.ist5 = 0xffff800000007c00,                                       \
-		.ist6 = 0xffff800000007c00,                                       \
-		.ist7 = 0xffff800000007c00,                                       \
-		.reserved2 = 0,                                                   \
-		.reserved3 = 0,                                                   \
-		.io_map_base_addr = 0                                             \
-	}
-
-#define GET_CURRENT_PCB    \
-	"movq %rsp, %rbx \n\t" \
-	"andq $-32768, %rbx\n\t"
+#define INITIAL_TSS                                                                                                    \
+    {                                                                                                                  \
+        .reserved0 = 0, .rsp0 = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)),                              \
+        .rsp1 = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)),                                              \
+        .rsp2 = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)), .reserved1 = 0, .ist1 = 0xffff800000007c00,  \
+        .ist2 = 0xffff800000007c00, .ist3 = 0xffff800000007c00, .ist4 = 0xffff800000007c00,                            \
+        .ist5 = 0xffff800000007c00, .ist6 = 0xffff800000007c00, .ist7 = 0xffff800000007c00, .reserved2 = 0,            \
+        .reserved3 = 0, .io_map_base_addr = 0                                                                          \
+    }
+
+#define GET_CURRENT_PCB                                                                                                \
+    "movq %rsp, %rbx \n\t"                                                                                             \
+    "andq $-32768, %rbx\n\t"
 
 /**
  * @brief 切换进程上下文
@@ -84,24 +57,24 @@
  * 然后调用__switch_to切换栈,配置其他信息,最后恢复下一个进程的rax rbp。
  */
 
-#define switch_proc(prev, next)                                                                     \
-	do                                                                                              \
-	{                                                                                               \
-		__asm__ __volatile__("pushq	%%rbp	\n\t"                                                     \
-							 "pushq	%%rax	\n\t"                                                     \
-							 "movq	%%rsp,	%0	\n\t"                                                  \
-							 "movq	%2,	%%rsp	\n\t"                                                  \
-							 "leaq	switch_proc_ret_addr(%%rip),	%%rax	\n\t"                         \
-							 "movq	%%rax,	%1	\n\t"                                                  \
-							 "pushq	%3		\n\t"                                                       \
-							 "jmp	__switch_to	\n\t"                                                 \
-							 "switch_proc_ret_addr:	\n\t"                                           \
-							 "popq	%%rax	\n\t"                                                      \
-							 "popq	%%rbp	\n\t"                                                      \
-							 : "=m"(prev->thread->rsp), "=m"(prev->thread->rip)                     \
-							 : "m"(next->thread->rsp), "m"(next->thread->rip), "D"(prev), "S"(next) \
-							 : "memory");                                                           \
-	} while (0)
+#define switch_proc(prev, next)                                                                                        \
+    do                                                                                                                 \
+    {                                                                                                                  \
+        __asm__ __volatile__("pushq	%%rbp	\n\t"                                                                        \
+                             "pushq	%%rax	\n\t"                                                                        \
+                             "movq	%%rsp,	%0	\n\t"                                                                     \
+                             "movq	%2,	%%rsp	\n\t"                                                                     \
+                             "leaq	switch_proc_ret_addr(%%rip),	%%rax	\n\t"                                            \
+                             "movq	%%rax,	%1	\n\t"                                                                     \
+                             "pushq	%3		\n\t"                                                                          \
+                             "jmp	__switch_to	\n\t"                                                                    \
+                             "switch_proc_ret_addr:	\n\t"                                                              \
+                             "popq	%%rax	\n\t"                                                                         \
+                             "popq	%%rbp	\n\t"                                                                         \
+                             : "=m"(prev->thread->rsp), "=m"(prev->thread->rip)                                        \
+                             : "m"(next->thread->rsp), "m"(next->thread->rip), "D"(prev), "S"(next)                    \
+                             : "memory");                                                                              \
+    } while (0)
 
 /**
  * @brief 初始化系统的第一个进程
@@ -118,7 +91,8 @@ void process_init();
  * @param stack_size 堆栈大小
  * @return unsigned long
  */
-unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size);
+unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned long stack_start,
+                      unsigned long stack_size);
 
 /**
  * @brief 根据pid获取进程的pcb
@@ -196,12 +170,11 @@ int process_release_pcb(struct process_control_block *pcb);
  * @param next 下一个进程的pcb
  *
  */
-#define process_switch_mm(next_pcb)                                    \
-	do                                                                 \
-	{                                                                  \
-		asm volatile("movq %0, %%cr3	\n\t" ::"r"(next_pcb->mm->pgd) \
-					 : "memory");                                      \
-	} while (0)
+#define process_switch_mm(next_pcb)                                                                                    \
+    do                                                                                                                 \
+    {                                                                                                                  \
+        asm volatile("movq %0, %%cr3	\n\t" ::"r"(next_pcb->mm->pgd) : "memory");                                    \
+    } while (0)
 // flush_tlb();
 
 // 获取当前cpu id

+ 27 - 16
kernel/src/smp/smp.c

@@ -1,12 +1,13 @@
 #include "smp.h"
+#include <common/cpu.h>
 #include <common/kprint.h>
+#include <common/spinlock.h>
 #include <driver/interrupt/apic/apic.h>
 #include <exception/gate.h>
-#include <common/cpu.h>
 #include <mm/slab.h>
 #include <process/process.h>
-#include <common/spinlock.h>
 
+#include <process/preempt.h>
 #include <sched/sched.h>
 
 #include "ipi.h"
@@ -36,7 +37,8 @@ void smp_init()
     }
 
     // 将引导程序复制到物理地址0x20000处
-    memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start, (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
+    memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start,
+           (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
     io_mfence();
     // 设置多核IPI中断门
     for (int i = 200; i < 210; ++i)
@@ -58,7 +60,9 @@ void smp_init()
         io_mfence();
 
         // 跳过BSP
-        kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i, proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->local_apic_id, proc_local_apic_structs[i]->flags);
+        kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i,
+               proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->local_apic_id,
+               proc_local_apic_structs[i]->flags);
         if (proc_local_apic_structs[i]->local_apic_id == 0)
         {
             --total_processor_num;
@@ -73,7 +77,8 @@ void smp_init()
         // continue;
         io_mfence();
         spin_lock(&multi_core_starting_lock);
-        preempt_enable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt count
+        preempt_enable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,bsp的自旋锁持有计数不会发生改变,需要手动恢复preempt
+                          // count
         current_starting_cpu = proc_local_apic_structs[i]->ACPI_Processor_UID;
         io_mfence();
         // 为每个AP处理器分配栈空间
@@ -85,8 +90,10 @@ void smp_init()
         io_mfence();
 
         // 设置ap处理器的中断栈及内核栈中的cpu_id
-        ((struct process_control_block *)(cpu_core_info[current_starting_cpu].stack_start - STACK_SIZE))->cpu_id = proc_local_apic_structs[i]->local_apic_id;
-        ((struct process_control_block *)(cpu_core_info[current_starting_cpu].ist_stack_start - STACK_SIZE))->cpu_id = proc_local_apic_structs[i]->local_apic_id;
+        ((struct process_control_block *)(cpu_core_info[current_starting_cpu].stack_start - STACK_SIZE))->cpu_id =
+            proc_local_apic_structs[i]->local_apic_id;
+        ((struct process_control_block *)(cpu_core_info[current_starting_cpu].ist_stack_start - STACK_SIZE))->cpu_id =
+            proc_local_apic_structs[i]->local_apic_id;
 
         cpu_core_info[current_starting_cpu].tss_vaddr = (uint64_t)&initial_tss[current_starting_cpu];
 
@@ -94,15 +101,21 @@ void smp_init()
 
         set_tss_descriptor(10 + (current_starting_cpu * 2), (void *)(cpu_core_info[current_starting_cpu].tss_vaddr));
         io_mfence();
-        set_tss64((uint *)cpu_core_info[current_starting_cpu].tss_vaddr, cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start,
-                  cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start);
+        set_tss64(
+            (uint *)cpu_core_info[current_starting_cpu].tss_vaddr, cpu_core_info[current_starting_cpu].stack_start,
+            cpu_core_info[current_starting_cpu].stack_start, cpu_core_info[current_starting_cpu].stack_start,
+            cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start,
+            cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start,
+            cpu_core_info[current_starting_cpu].ist_stack_start, cpu_core_info[current_starting_cpu].ist_stack_start,
+            cpu_core_info[current_starting_cpu].ist_stack_start);
         io_mfence();
 
         // 连续发送两次start-up IPI
-        ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, proc_local_apic_structs[i]->local_apic_id);
+        ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand,
+                     proc_local_apic_structs[i]->local_apic_id);
         io_mfence();
-        ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, proc_local_apic_structs[i]->local_apic_id);
-
+        ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand,
+                     proc_local_apic_structs[i]->local_apic_id);
     }
     io_mfence();
     while (num_cpu_started != total_processor_num)
@@ -130,10 +143,8 @@ void smp_ap_start()
 
     //  切换栈基地址
     //  uint64_t stack_start = (uint64_t)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
-    __asm__ __volatile__("movq %0, %%rbp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start)
-                         : "memory");
-    __asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start)
-                         : "memory");
+    __asm__ __volatile__("movq %0, %%rbp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start) : "memory");
+    __asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start) : "memory");
 
     ksuccess("AP core %d successfully started!", current_starting_cpu);
     io_mfence();

+ 2 - 2
tools/bootstrap.sh

@@ -140,7 +140,7 @@ rustInstall() {
 ############ 开始执行 ###############
 banner
 rustInstall
-exit
+
 if [ "Darwin" == "$(uname -s)" ]; then
 	install_osx_pkg "$emulator" || exit 1
 else
@@ -174,6 +174,6 @@ else
 fi
 
 # 创建磁盘镜像
-sudo bash create_hdd_image.sh
+bash create_hdd_image.sh
 
 congratulations