Browse Source

signal的发送(暂时父子进程之间共享信号及相应的结构体) (#89)

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

* new: 初步实现signal的数据结构

* new:signal相关数据结构

* fix: 解决bindings.rs报一堆警告的问题

* new: rust下的kdebug kinfo kwarn kBUG kerror宏

* 移动asm.h和cmpxchg.h

* new: signal的发送(暂时只支持父子进程共享信号及处理函数)
login 2 years ago
parent
commit
66f67c6a95
44 changed files with 1677 additions and 472 deletions
  1. 3 0
      kernel/src/arch/mod.rs
  2. 18 0
      kernel/src/arch/x86_64/asm/current.rs
  3. 24 0
      kernel/src/arch/x86_64/asm/irqflags.rs
  4. 3 0
      kernel/src/arch/x86_64/asm/mod.rs
  5. 16 0
      kernel/src/arch/x86_64/cpu.rs
  6. 0 0
      kernel/src/arch/x86_64/include/asm/asm.h
  7. 1 1
      kernel/src/arch/x86_64/include/asm/cmpxchg.h
  8. 1 1
      kernel/src/arch/x86_64/include/asm/irqflags.h
  9. 3 0
      kernel/src/arch/x86_64/mod.rs
  10. 2 5
      kernel/src/common/glib.h
  11. 1 5
      kernel/src/common/list.h
  12. 1 0
      kernel/src/include/DragonOS/refcount.h
  13. 42 2
      kernel/src/include/DragonOS/signal.h
  14. 216 7
      kernel/src/include/DragonOS/signal.rs
  15. 1 0
      kernel/src/include/bindings/wrapper.h
  16. 402 0
      kernel/src/ipc/signal.rs
  17. 44 9
      kernel/src/lib.rs
  18. 11 0
      kernel/src/libs/atomic.rs
  19. 29 0
      kernel/src/libs/ffi_convert.rs
  20. 1 1
      kernel/src/libs/lockref.c
  21. 6 1
      kernel/src/libs/mod.rs
  22. 54 0
      kernel/src/libs/refcount.rs
  23. 30 0
      kernel/src/libs/spinlock.rs
  24. 391 0
      kernel/src/process/fork.c
  25. 27 0
      kernel/src/process/fork.rs
  26. 26 0
      kernel/src/process/initial_proc.rs
  27. 5 0
      kernel/src/process/mod.rs
  28. 18 0
      kernel/src/process/pid.rs
  29. 13 0
      kernel/src/process/preempt.rs
  30. 20 19
      kernel/src/process/proc-types.h
  31. 25 400
      kernel/src/process/process.c
  32. 32 9
      kernel/src/process/process.h
  33. 103 0
      kernel/src/process/process.rs
  34. 13 0
      kernel/src/sched/core.rs
  35. 1 0
      kernel/src/sched/mod.rs
  36. 1 0
      kernel/src/sched/sched.c
  37. 14 0
      kernel/src/smp/core.rs
  38. 1 0
      kernel/src/smp/mod.rs
  39. 5 4
      kernel/src/syscall/syscall.c
  40. 1 0
      kernel/src/syscall/syscall_num.h
  41. 28 7
      user/apps/shell/cmd.c
  42. 3 1
      user/apps/shell/cmd.h
  43. 40 0
      user/libs/libc/include/signal.h
  44. 1 0
      user/libs/libsystem/syscall.h

+ 3 - 0
kernel/src/arch/mod.rs

@@ -0,0 +1,3 @@
+#[cfg(target_arch="x86_64")]
+#[macro_use]
+pub mod x86_64;

+ 18 - 0
kernel/src/arch/x86_64/asm/current.rs

@@ -0,0 +1,18 @@
+use crate::include::bindings::bindings::process_control_block;
+
+use core::{arch::asm, sync::atomic::compiler_fence};
+
+/// @brief 获取指向当前进程的pcb的可变引用
+#[inline]
+pub fn current_pcb() -> &'static mut process_control_block {
+    let ret: Option<&mut process_control_block>;
+    unsafe {
+        let mut tmp: u64 = !(32767u64);
+        compiler_fence(core::sync::atomic::Ordering::SeqCst);
+        asm!("and {0}, rsp", inout(reg)(tmp),);
+        compiler_fence(core::sync::atomic::Ordering::SeqCst);
+        ret = (tmp as *mut process_control_block).as_mut();
+    }
+
+    ret.unwrap()
+}

+ 24 - 0
kernel/src/arch/x86_64/asm/irqflags.rs

@@ -0,0 +1,24 @@
+use core::arch::asm;
+
+#[inline]
+pub fn local_irq_save(flags: &mut u64) {
+    unsafe {
+        asm!(
+            "pushfq",
+            "pop rax",
+            "mov rax, {0}",
+            "cli",
+            out(reg)(*flags),
+        );
+    }
+}
+
+#[inline]
+pub fn local_irq_restore(flags: &u64) {
+    let x = *flags;
+
+    unsafe {
+        asm!("push r15",
+            "popfq", in("r15")(x));
+    }
+}

+ 3 - 0
kernel/src/arch/x86_64/asm/mod.rs

@@ -0,0 +1,3 @@
+pub mod irqflags;
+#[macro_use]
+pub mod current;

+ 16 - 0
kernel/src/arch/x86_64/cpu.rs

@@ -0,0 +1,16 @@
+use core::arch::asm;
+
+/// @brief 获取当前cpu的apic id
+#[inline]
+pub fn arch_current_apic_id() -> u8 {
+    let cpuid_res: u32;
+    unsafe {
+        asm!(
+             "mov eax, 1",
+             "cpuid",
+             "mov r15, ebx",
+             lateout("r15") cpuid_res
+        );
+    }
+    return (cpuid_res >> 24) as u8;
+}

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


+ 1 - 1
kernel/src/arch/x86_64/asm/cmpxchg.h → kernel/src/arch/x86_64/include/asm/cmpxchg.h

@@ -1,6 +1,6 @@
 #pragma once
 #include <common/compiler.h>
-#include <arch/x86_64/asm/asm.h>
+#include <asm/asm.h>
 
 /**
  * @brief 通过extern不存在的函数,来让编译器报错。以防止不符合要求的代码的产生。

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

@@ -1,5 +1,5 @@
 #pragma once
-
+#include <asm/asm.h>
 // 保存当前rflags的值到变量x内并关闭中断
 #define local_irq_save(x) __asm__ __volatile__("pushfq ; popq %0 ; cli" \
                                                : "=g"(x)::"memory")

+ 3 - 0
kernel/src/arch/x86_64/mod.rs

@@ -0,0 +1,3 @@
+#[macro_use]
+pub mod asm;
+pub mod cpu;

+ 2 - 5
kernel/src/common/glib.h

@@ -13,11 +13,8 @@
 #include <common/compiler.h>
 #include <common/list.h>
 
-#if ARCH(I386) || ARCH(X86_64)
-#include <arch/x86_64/asm/asm.h>
-#else
-#error Arch not supported.
-#endif
+
+#include <asm/asm.h>
 
 /**
  * @brief 根据结构体变量内某个成员变量member的基地址,计算出该结构体变量的基地址

+ 1 - 5
kernel/src/common/list.h

@@ -1,11 +1,7 @@
 #pragma once
 #include <common/stddef.h>
 
-#if ARCH(I386) || ARCH(X86_64)
-#include <arch/x86_64/asm/asm.h>
-#else
-#error Arch not supported.
-#endif
+#include <asm/asm.h>
 
 //链表数据结构
 struct List

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

@@ -1,6 +1,7 @@
 #pragma once
 #include <common/atomic.h>
 
+// 该结构体需要与libs/refcount.rs的保持一致,且以rust版本为准
 typedef struct refcount_struct {
 	atomic_t refs;
 } refcount_t;

+ 42 - 2
kernel/src/include/DragonOS/signal.h

@@ -14,6 +14,46 @@ typedef __signalfn_t *__sighandler_t;
 
 typedef uint64_t sigset_t;
 
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+
+#define SIGPWR 30
+#define SIGSYS 31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN 32
+#define SIGRTMAX MAX_SIG_NUM
+
+// 注意,该结构体最大16字节
 union __sifields {
     /* kill() */
     struct
@@ -27,8 +67,9 @@ union __sifields {
     struct                                                                                                             \
     {                                                                                                                  \
         int32_t si_signo; /* signal number */                                                                          \
-        int32_t code;                                                                                                  \
+        int32_t si_code;                                                                                               \
         int32_t si_errno;                                                                                              \
+        uint32_t reserved; /* 保留备用 */                                                                          \
         union __sifields _sifields;                                                                                    \
     }
 
@@ -80,7 +121,6 @@ struct sighand_struct
 
 /**
  * @brief 正在等待的信号的标志位
- *
  */
 struct sigpending
 {

+ 216 - 7
kernel/src/include/DragonOS/signal.rs

@@ -3,14 +3,21 @@
 
 // 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;
+use crate::libs::ffi_convert::FFIBind2Rust;
+use crate::libs::ffi_convert::__convert_mut;
+use crate::libs::ffi_convert::__convert_ref;
+use crate::libs::refcount::RefCount;
 
+/// 请注意,sigset_t这个bitmap, 第0位表示sig=1的信号。也就是说,SignalNumber-1才是sigset_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.h)
+pub const MAX_SIG_NUM: i32 = 64;
+
 /// 由于signal_struct总是和sighand_struct一起使用,并且信号处理的过程中必定会对sighand加锁
 /// 因此signal_struct不用加锁
 /// **请将该结构体与`include/DragonOS/signal.h`中的保持同步**
@@ -37,11 +44,17 @@ pub union sigaction__union_u {
     >,
 }
 
+impl core::fmt::Debug for sigaction__union_u{
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.write_str("sigaction__union_u")
+    }
+}
+
 /**
  * @brief 信号处理结构体
  */
 #[repr(C)]
-#[derive(Copy, Clone)]
+#[derive(Debug, Copy, Clone)]
 pub struct sigaction {
     pub _u: sigaction__union_u,
     pub sa_flags: u64,
@@ -49,6 +62,7 @@ pub struct sigaction {
     pub sa_restorer: ::core::option::Option<unsafe extern "C" fn()>, // 暂时未实现该函数
 }
 
+
 /**
  * 信号消息的结构体,作为参数传入sigaction结构体中指向的处理函数
  */
@@ -68,13 +82,15 @@ pub union __siginfo_union {
 #[derive(Copy, Clone)]
 pub struct __siginfo_union_data {
     pub si_signo: i32,
-    pub code: i32,
+    pub si_code: i32,
     pub si_errno: i32,
+    pub reserved: u32,
     pub _sifields: __sifields,
 }
 
 /**
- * siginfo中,根据signal的来源不同,该union中对应了不同的数据
+ * siginfo中,根据signal的来源不同,该union中对应了不同的数据./=
+ * 请注意,该union最大占用16字节
  */
 #[repr(C)]
 #[derive(Copy, Clone)]
@@ -95,12 +111,12 @@ pub struct __sifields__kill {
  * @brief 信号处理结构体,位于pcb之中
  */
 #[repr(C)]
-#[derive(Copy, Clone)]
+#[derive(Debug, Copy, Clone)]
 pub struct sighand_struct {
     pub siglock: spinlock_t,
-    pub count: refcount_t,
+    pub count: RefCount,
     pub signal_fd_wqh: wait_queue_head_t,
-    pub action: [sigaction; 64usize],
+    pub action: [sigaction; MAX_SIG_NUM as usize],
 }
 
 /**
@@ -111,3 +127,196 @@ pub struct sighand_struct {
 pub struct sigpending {
     pub signal: sigset_t,
 }
+
+#[allow(dead_code)]
+#[repr(i32)]
+pub enum si_code_val {
+    /// sent by kill, sigsend, raise
+    SI_USER = 0,
+    /// sent by kernel from somewhere
+    SI_KERNEL = 0x80,
+    /// 通过sigqueue发送
+    SI_QUEUE = -1,
+    /// 定时器过期时发送
+    SI_TIMER = -2,
+    /// 当实时消息队列的状态发生改变时发送
+    SI_MESGQ = -3,
+    /// 当异步IO完成时发送
+    SI_ASYNCIO = -4,
+    /// sent by queued SIGIO
+    SI_SIGIO = -5,
+}
+
+impl si_code_val {
+    /// 为si_code_val这个枚举类型实现从i32转换到枚举类型的转换函数
+    #[allow(dead_code)]
+    pub fn from_i32(x: i32) -> si_code_val {
+        match x {
+            0 => Self::SI_USER,
+            0x80 => Self::SI_KERNEL,
+            -1 => Self::SI_QUEUE,
+            -2 => Self::SI_TIMER,
+            -3 => Self::SI_MESGQ,
+            -4 => Self::SI_ASYNCIO,
+            -5 => Self::SI_SIGIO,
+            _ => panic!("si code not valid"),
+        }
+    }
+}
+
+#[allow(dead_code)]
+#[derive(Debug, Clone, Copy)]
+#[repr(i32)]
+pub enum SignalNumber {
+    SIGHUP = 1,
+    SIGINT,
+    SIGQUIT,
+    SIGILL,
+    SIGTRAP,
+    /// SIGABRT和SIGIOT共用这个号码
+    SIGABRT_OR_IOT,
+    SIGBUS,
+    SIGFPE,
+    SIGKILL,
+    SIGUSR1,
+
+    SIGSEGV = 11,
+    SIGUSR2,
+    SIGPIPE,
+    SIGALRM,
+    SIGTERM,
+    SIGSTKFLT,
+    SIGCHLD,
+    SIGCONT,
+    SIGSTOP,
+    SIGTSTP,
+
+    SIGTTIN = 21,
+    SIGTTOU,
+    SIGURG,
+    SIGXCPU,
+    SIGXFSZ,
+    SIGVTALRM,
+    SIGPROF,
+    SIGWINCH,
+    /// SIGIO和SIGPOLL共用这个号码
+    SIGIO_OR_POLL,
+    SIGPWR,
+
+    SIGSYS = 31,
+}
+
+/// 为SignalNumber实现判断相等的trait
+impl PartialEq for SignalNumber {
+    fn eq(&self, other: &SignalNumber) -> bool {
+        *self as i32 == *other as i32
+    }
+}
+
+impl SignalNumber {
+    /// @brief 从i32转换为SignalNumber枚举类型,如果传入的x不符合要求,则返回None
+    #[allow(dead_code)]
+    pub fn from_i32(x: i32) -> Option<SignalNumber> {
+        if Self::valid_signal_number(x) {
+            let ret: SignalNumber = unsafe { core::mem::transmute(x) };
+            return Some(ret);
+        }
+
+        return None;
+    }
+
+    /// 判断一个数字是否为可用的信号
+    fn valid_signal_number(x: i32) -> bool {
+        if x > 0 && x < MAX_SIG_NUM {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
+#[allow(dead_code)]
+pub const SIGRTMIN: i32 = 32;
+#[allow(dead_code)]
+pub const SIGRTMAX: i32 = MAX_SIG_NUM;
+
+/// @brief 将给定的signal_struct解析为Rust的signal.rs中定义的signal_struct的引用
+///
+/// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的
+impl FFIBind2Rust<crate::include::bindings::bindings::signal_struct> for signal_struct {
+    fn convert_mut<'a>(
+        src: *mut crate::include::bindings::bindings::signal_struct,
+    ) -> Option<&'a mut Self> {
+        return __convert_mut(src);
+    }
+    fn convert_ref<'a>(
+        src: *const crate::include::bindings::bindings::signal_struct,
+    ) -> Option<&'a Self> {
+        return __convert_ref(src);
+    }
+}
+
+/// @brief 将给定的siginfo解析为Rust的signal.rs中定义的siginfo的引用
+///
+/// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的
+impl FFIBind2Rust<crate::include::bindings::bindings::siginfo> for siginfo {
+    fn convert_mut<'a>(
+        src: *mut crate::include::bindings::bindings::siginfo,
+    ) -> Option<&'a mut Self> {
+        return __convert_mut(src);
+    }
+    fn convert_ref<'a>(
+        src: *const crate::include::bindings::bindings::siginfo,
+    ) -> Option<&'a Self> {
+        return __convert_ref(src)
+    }
+}
+
+
+/// @brief 将给定的sigset_t解析为Rust的signal.rs中定义的sigset_t的引用
+///
+/// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的
+impl FFIBind2Rust<crate::include::bindings::bindings::sigset_t> for sigset_t {
+    fn convert_mut<'a>(
+        src: *mut crate::include::bindings::bindings::sigset_t,
+    ) -> Option<&'a mut Self> {
+        return __convert_mut(src);
+    }
+    fn convert_ref<'a>(
+        src: *const crate::include::bindings::bindings::sigset_t,
+    ) -> Option<&'a Self> {
+        return __convert_ref(src)
+    }
+}
+
+/// @brief 将给定的sigpending解析为Rust的signal.rs中定义的sigpending的引用
+///
+/// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的
+impl FFIBind2Rust<crate::include::bindings::bindings::sigpending> for sigpending {
+    fn convert_mut<'a>(
+        src: *mut crate::include::bindings::bindings::sigpending,
+    ) -> Option<&'a mut Self> {
+        return __convert_mut(src);
+    }
+    fn convert_ref<'a>(
+        src: *const crate::include::bindings::bindings::sigpending,
+    ) -> Option<&'a Self> {
+        return __convert_ref(src)
+    }
+}
+
+/// @brief 将给定的来自bindgen的sighand_struct解析为Rust的signal.rs中定义的sighand_struct的引用
+///
+/// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的,会导致无法自定义功能的问题。
+impl FFIBind2Rust<crate::include::bindings::bindings::sighand_struct> for sighand_struct{
+    fn convert_mut<'a>(
+        src: *mut crate::include::bindings::bindings::sighand_struct,
+    ) -> Option<&'a mut Self> {
+        return __convert_mut(src);
+    }
+    fn convert_ref<'a>(
+        src: *const crate::include::bindings::bindings::sighand_struct,
+    ) -> Option<&'a Self> {
+        return __convert_ref(src)
+    }
+}

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

@@ -27,5 +27,6 @@
 #include <include/DragonOS/signal.h>
 #include <mm/mm.h>
 #include <mm/slab.h>
+#include <process/process.h>
 #include <sched/cfs.h>
 #include <sched/sched.h>

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

@@ -0,0 +1,402 @@
+use core::ptr::read_volatile;
+
+use crate::{
+    include::{
+        bindings::bindings::{
+            pid_t, process_control_block, process_find_pcb_by_pid, pt_regs, spinlock_t, EINVAL,
+            ENOTSUP, ESRCH, PF_EXITING, PF_KTHREAD, PF_WAKEKILL, PROC_INTERRUPTIBLE,
+        },
+        DragonOS::signal::{
+            si_code_val, sighand_struct, siginfo, signal_struct, sigpending, sigset_t,
+            SignalNumber, MAX_SIG_NUM, sigaction, sigaction__union_u,
+        },
+    },
+    kBUG, kdebug, kwarn,
+    libs::{
+        ffi_convert::FFIBind2Rust,
+        spinlock::{spin_is_locked, spin_lock_irqsave, spin_unlock_irqrestore},
+    },
+    println,
+    process::{
+        pid::PidType,
+        process::{process_is_stopped, process_kick, process_wake_up_state},
+    },
+};
+
+use crate::include::DragonOS::signal::{__siginfo_union, __siginfo_union_data};
+
+/// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
+pub static DEFAULT_SIGACTION: sigaction = sigaction{
+    _u: sigaction__union_u{
+        _sa_handler: None,
+    },
+    sa_flags:0,
+    sa_mask:0,
+    sa_restorer:None
+};
+
+/// @brief kill系统调用,向指定的进程发送信号
+/// @param regs->r8 pid 要接收信号的进程id
+/// @param regs->r9 sig 信号
+#[no_mangle]
+pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
+    println!(
+        "sys kill, target pid={}, file={}, line={}",
+        regs.r8,
+        file!(),
+        line!()
+    );
+
+    let pid: pid_t = regs.r8 as pid_t;
+    let sig: Option<SignalNumber> = SignalNumber::from_i32(regs.r9 as i32);
+    if sig.is_none() {
+        // 传入的signal数值不合法
+        kwarn!("Not a valid signal number");
+        return (-(EINVAL as i64)) as u64;
+    }
+
+    // 初始化signal info
+    let mut info = siginfo {
+        _sinfo: __siginfo_union {
+            data: __siginfo_union_data {
+                si_signo: sig.unwrap() as i32,
+                si_code: si_code_val::SI_USER as i32,
+                si_errno: 0,
+                reserved: 0,
+                _sifields: crate::include::DragonOS::signal::__sifields {
+                    _kill: crate::include::DragonOS::signal::__sifields__kill { _pid: pid },
+                },
+            },
+        },
+    };
+
+    return signal_kill_something_info(sig.unwrap(), Some(&mut info), pid) as u64;
+}
+
+/// 通过kill的方式向目标进程发送信号
+/// @param sig 要发送的信号
+/// @param info 要发送的信息
+/// @param pid 进程id(目前只支持pid>0)
+fn signal_kill_something_info(sig: SignalNumber, info: Option<&mut siginfo>, pid: pid_t) -> i32 {
+    // 暂时不支持特殊的kill操作
+    if pid <= 0 {
+        kwarn!("Kill operation not support: pid={}", pid);
+        return -(ENOTSUP as i32);
+    }
+
+    // kill单个进程
+    return signal_kill_proc_info(sig, info, pid);
+}
+
+fn signal_kill_proc_info(sig: SignalNumber, info: Option<&mut siginfo>, pid: pid_t) -> i32 {
+    let mut retval: i32 = -(ESRCH as i32);
+
+    // step1: 当进程管理模块拥有pcblist_lock之后,对其加锁
+
+    // step2: 根据pid找到pcb
+    let pcb = unsafe { process_find_pcb_by_pid(pid).as_mut() };
+
+    if pcb.is_none() {
+        kwarn!("No such process.");
+        return retval;
+    }
+
+    println!("Target pcb = {:?}", pcb.as_ref().unwrap());
+
+    // step3: 调用signal_send_sig_info函数,发送信息
+    retval = signal_send_sig_info(sig, info, pcb.unwrap());
+    // step4: 解锁
+    return retval;
+}
+
+/// @brief 验证信号的值是否在范围内
+#[inline]
+fn verify_signal(sig: SignalNumber) -> bool {
+    return if (sig as i32) <= MAX_SIG_NUM {
+        true
+    } else {
+        false
+    };
+}
+
+/// @brief 在发送信号给指定的进程前,做一些权限检查. 检查是否有权限发送
+/// @param sig 要发送的信号
+/// @param info 要发送的信息
+/// @param target_pcb 信号的接收者
+fn signal_send_sig_info(
+    sig: SignalNumber,
+    info: Option<&mut siginfo>,
+    target_pcb: &mut process_control_block,
+) -> i32 {
+    kdebug!("signal_send_sig_info");
+    // 检查sig是否符合要求,如果不符合要求,则退出。
+    if !verify_signal(sig) {
+        return -(EINVAL as i32);
+    }
+
+    // 信号符合要求,可以发送
+
+    let mut retval = -(ESRCH as i32);
+    let mut flags: u64 = 0;
+    // 如果上锁成功,则发送信号
+    if !lock_process_sighand(target_pcb, &mut flags).is_none() {
+        // 发送信号
+        retval = send_signal_locked(sig, info, target_pcb, PidType::PID);
+        
+        kdebug!("flags=0x{:016x}", flags);
+        // 对sighand放锁
+        unlock_process_sighand(target_pcb, &flags);
+    }
+    return retval;
+}
+
+/// @brief 对pcb的sighand结构体中的siglock进行加锁,并关闭中断
+/// @param pcb 目标pcb
+/// @param flags 用来保存rflags的变量
+/// @return 指向sighand_struct的可变引用
+fn lock_process_sighand<'a>(
+    pcb: &'a mut process_control_block,
+    flags: &mut u64,
+) -> Option<&'a mut sighand_struct> {
+    kdebug!("lock_process_sighand");
+    let x = unsafe { &mut *pcb.sighand };
+
+    let sighand_ptr = sighand_struct::convert_mut(unsafe { &mut *pcb.sighand });
+    // kdebug!("sighand_ptr={:?}", &sighand_ptr);
+    if !sighand_ptr.is_some() {
+        kBUG!("Sighand ptr of process {pid} is NULL!", pid = pcb.pid);
+        return None;
+    }else{
+
+        kdebug!("7777");
+    }
+    let lock =  {&mut sighand_ptr.unwrap().siglock};
+    kdebug!("123");
+    kdebug!("lock={}", unsafe{*(lock as *mut spinlock_t as *mut i8)});
+    spin_lock_irqsave(lock, flags);
+    kdebug!("lock={}", unsafe{*(lock as *mut spinlock_t as *mut i8)});
+    kdebug!("locked");
+    let ret = unsafe { ((*pcb).sighand as *mut sighand_struct).as_mut() };
+
+    return ret;
+}
+
+/// @brief 对pcb的sighand结构体中的siglock进行放锁,并恢复之前存储的rflags
+/// @param pcb 目标pcb
+/// @param flags 用来保存rflags的变量,将这个值恢复到rflags寄存器中
+fn unlock_process_sighand(pcb: &mut process_control_block, flags: &u64) {
+    kdebug!("unlock_process_sighand");
+    let lock = unsafe{&mut (*pcb.sighand).siglock};
+    kdebug!("lock={:?}", lock);
+    spin_unlock_irqrestore(lock, flags);
+    kdebug!("lock={}", unsafe{*(lock as *mut spinlock_t as *mut i8)});
+    kdebug!("123443");
+}
+
+/// @brief 判断是否需要强制发送信号,然后发送信号
+/// 注意,进入该函数前,我们应当对pcb.sighand.siglock加锁。
+///
+/// @return i32 错误码
+fn send_signal_locked(
+    sig: SignalNumber,
+    info: Option<&mut siginfo>,
+    pcb: &mut process_control_block,
+    pt: PidType,
+) -> i32 {
+    kdebug!("send_signal_locked");
+    // 是否强制发送信号
+    let mut force_send = false;
+    // signal的信息为空
+    if info.is_none() {
+        // todo: 判断signal是否来自于一个祖先进程的namespace,如果是,则强制发送信号
+    } else {
+        force_send = unsafe { info.as_ref().unwrap()._sinfo.data }.si_code
+            == (si_code_val::SI_KERNEL as i32);
+    }
+
+    kdebug!("force send={}", force_send);
+
+    return __send_signal_locked(sig, info, pcb, pt, force_send);
+}
+
+/// @brief 发送信号
+/// 注意,进入该函数前,我们应当对pcb.sighand.siglock加锁。
+///
+/// @param sig 信号
+/// @param _info 信号携带的信息
+/// @param pcb 目标进程的pcb
+/// @param pt siginfo结构体中,pid字段代表的含义
+/// @return i32 错误码
+fn __send_signal_locked(
+    sig: SignalNumber,
+    _info: Option<&mut siginfo>,
+    pcb: &mut process_control_block,
+    pt: PidType,
+    _force_send: bool,
+) -> i32 {
+    kdebug!("__send_signal_locked");
+    let mut retval = 0;
+
+    // 判断该进入该函数时,是否已经持有了锁
+    println!("locked={}",spin_is_locked(unsafe { &(*pcb.sighand).siglock }));
+    kdebug!("1234");
+    let _pending: Option<&mut sigpending> = sigpending::convert_mut(&mut pcb.sig_pending);
+    kdebug!("567");
+
+    // 如果是kill或者目标pcb是内核线程,则无需获取sigqueue,直接发送信号即可
+    if sig == SignalNumber::SIGKILL || (pcb.flags & (PF_KTHREAD as u64)) != 0 {
+        complete_signal(sig, pcb, pt);
+    } else {
+        // todo: 如果是其他信号,则加入到sigqueue内,然后complete_signal
+        retval = -(ENOTSUP as i32);
+    }
+    kdebug!("12342");
+    return retval;
+}
+
+/// @brief 将信号添加到目标进程的sig_pending。在引入进程组后,本函数还将负责把信号传递给整个进程组。
+///
+/// @param sig 信号
+/// @param pcb 目标pcb
+/// @param pt siginfo结构体中,pid字段代表的含义
+fn complete_signal(sig: SignalNumber, pcb: &mut process_control_block, pt: PidType) {
+    // todo: 将信号产生的消息通知到正在监听这个信号的进程(引入signalfd之后,在这里调用signalfd_notify)
+    kdebug!("complete_signal");
+    // 将这个信号加到目标进程的sig_pending中
+    sigset_add(
+        sigset_t::convert_mut(&mut pcb.sig_pending.signal).unwrap(),
+        sig,
+    );
+
+    // ===== 寻找需要wakeup的目标进程 =====
+    // 备注:由于当前没有进程组的概念,每个进程只有1个对应的线程,因此不需要通知进程组内的每个进程。
+    //      todo: 当引入进程组的概念后,需要完善这里,使得它能寻找一个目标进程来唤醒,接着执行信号处理的操作。
+
+    let _signal: Option<&mut signal_struct> = signal_struct::convert_mut(pcb.signal);
+
+    let mut _target: Option<&mut process_control_block> = None;
+
+    // 判断目标进程是否想接收这个信号
+    if wants_signal(sig, pcb) {
+        _target = Some(pcb);
+    } else if pt == PidType::PID {
+        /*
+         * There is just one thread and it does not need to be woken.
+         * It will dequeue unblocked signals before it runs again.
+         */
+        return;
+    } else {
+        /*
+         * Otherwise try to find a suitable thread.
+         * 由于目前每个进程只有1个线程,因此当前情况可以返回。信号队列的dequeue操作不需要考虑同步阻塞的问题。
+         */
+        return;
+    }
+
+    // todo:引入进程组后,在这里挑选一个进程来唤醒,让它执行相应的操作。
+    // todo!();
+
+    // todo: 到这里,信号已经被放置在共享的pending队列中,我们在这里把目标进程唤醒。
+    if _target.is_some() {
+        signal_wake_up(pcb, sig == SignalNumber::SIGKILL);
+    }
+}
+
+/// @brief 本函数用于检测指定的进程是否想要接收SIG这个信号。
+/// 当我们对于进程组中的所有进程都运行了这个检查之后,我们将可以找到组内愿意接收信号的进程。
+/// 这么做是为了防止我们把信号发送给了一个正在或已经退出的进程,或者是不响应该信号的进程。
+#[inline]
+fn wants_signal(sig: SignalNumber, pcb: &process_control_block) -> bool {
+    // 如果改进程屏蔽了这个signal,则不能接收
+    if sig_is_member(sigset_t::convert_ref(&pcb.sig_blocked).unwrap(), sig) {
+        return false;
+    }
+
+    // 如果进程正在退出,则不能接收信号
+    if (pcb.flags & (PF_EXITING as u64)) > 0 {
+        return false;
+    }
+
+    if sig == SignalNumber::SIGKILL {
+        return true;
+    }
+
+    if process_is_stopped(pcb) {
+        return false;
+    }
+
+    // todo: 检查目标进程是否正在一个cpu上执行,如果是,则返回true,否则继续检查下一项
+
+    // 检查目标进程是否有信号正在等待处理,如果是,则返回false,否则返回true
+    return !has_sig_pending(pcb);
+}
+
+/// @brief 判断指定的信号在sigset中的对应位是否被置位
+/// @return true: 给定的信号在sigset中被置位
+/// @return false: 给定的信号在sigset中没有被置位
+#[inline]
+fn sig_is_member(set: &sigset_t, _sig: SignalNumber) -> bool {
+    return if 1 & (set >> ((_sig as u32) - 1)) != 0 {
+        true
+    } else {
+        false
+    };
+}
+
+/// @brief 将指定的信号在sigset中的对应bit进行置位
+#[inline]
+fn sigset_add(set: &mut sigset_t, _sig: SignalNumber) {
+    *set |= 1 << ((_sig as u32) - 1);
+}
+
+/// @brief 判断signal的处理是否可能使得整个进程组退出
+/// @return true 可能会导致退出(不一定)
+#[allow(dead_code)]
+#[inline]
+fn sig_fatal(pcb: &process_control_block, sig: SignalNumber) -> bool {
+    let handler = unsafe {
+        sighand_struct::convert_ref(pcb.sighand).unwrap().action[(sig as usize) - 1]
+            ._u
+            ._sa_handler
+    };
+
+    // 如果handler是空,采用默认函数,signal处理可能会导致进程退出。
+    if handler.is_none() {
+        return true;
+    } else {
+        return false;
+    }
+
+    // todo: 参照linux的sig_fatal实现完整功能
+}
+
+/// @brief 判断某个进程是否有信号正在等待处理
+#[inline]
+fn has_sig_pending(pcb: &process_control_block) -> bool {
+    let ptr = &sigpending::convert_ref(&(*pcb).sig_pending).unwrap().signal;
+    if unsafe { read_volatile(ptr) } != 0 {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+#[inline]
+fn signal_wake_up(pcb: &mut process_control_block, fatal: bool) {
+    let mut state: u64 = 0;
+    if fatal {
+        state = PF_WAKEKILL as u64;
+    }
+    signal_wake_up_state(pcb, state);
+}
+
+fn signal_wake_up_state(pcb: &mut process_control_block, state: u64) {
+    assert!(spin_is_locked(&unsafe { *pcb.sighand }.siglock));
+    // todo: 设置线程结构体的标志位为TIF_SIGPENDING
+
+    // 如果目标进程已经在运行,则发起一个ipi,使得它陷入内核
+    if !process_wake_up_state(pcb, state | (PROC_INTERRUPTIBLE as u64)) {
+        process_kick(pcb);
+    }
+}
+

+ 44 - 9
kernel/src/lib.rs

@@ -2,27 +2,32 @@
 #![no_main] // <1>
 #![feature(core_intrinsics)] // <2>
 #![feature(alloc_error_handler)]
+#![feature(panic_info_message)]
 
 #[allow(non_upper_case_globals)]
 #[allow(non_camel_case_types)]
 #[allow(non_snake_case)]
-
-use core::intrinsics; // <2>
 use core::panic::PanicInfo;
 
-
 #[macro_use]
-mod mm;
+mod arch;
+#[macro_use]
 mod include;
-mod libs;
 mod ipc;
 
+#[macro_use]
+mod libs;
+mod mm;
+mod process;
+mod sched;
+mod smp;
+
 extern crate alloc;
 
 use mm::allocator::KernelAllocator;
 
 // <3>
-use crate::include::bindings::bindings::{BLACK, GREEN};
+use crate::{include::bindings::bindings::{process_do_exit, BLACK, GREEN}, arch::x86_64::asm::current::current_pcb};
 
 // 声明全局的slab分配器
 #[cfg_attr(not(test), global_allocator)]
@@ -31,14 +36,44 @@ pub static KERNEL_ALLOCATOR: KernelAllocator = KernelAllocator {};
 /// 全局的panic处理函数
 #[panic_handler]
 #[no_mangle]
-pub fn panic(_info: &PanicInfo) -> ! {
-    intrinsics::abort(); // <4>
+pub fn panic(info: &PanicInfo) -> ! {
+    kerror!("Kernel Panic Occurred.");
+
+    match info.location() {
+        Some(loc) => {
+            println!(
+                "Location:\n\tFile: {}\n\tLine: {}, Column: {}",
+                loc.file(),
+                loc.line(),
+                loc.column()
+            );
+        }
+        None => {
+            println!("No location info");
+        }
+    }
+
+    match info.message() {
+        Some(msg) => {
+            println!("Message:\n\t{}", msg);
+        }
+        None => {
+            println!("No panic message.");
+        }
+    }
+
+    println!("Current PCB:\n\t{:?}", current_pcb());
+    unsafe {
+        process_do_exit(u64::MAX);
+    };
+    loop {
+        
+    }
 }
 
 /// 该函数用作测试,在process.c的initial_kernel_thread()中调用了此函数
 #[no_mangle]
 pub extern "C" fn __rust_demo_func() -> i32 {
-    
     printk_color!(GREEN, BLACK, "__rust_demo_func()\n");
 
     return 0;

+ 11 - 0
kernel/src/libs/atomic.rs

@@ -0,0 +1,11 @@
+use core::ptr::read_volatile;
+
+use crate::include::bindings::bindings::atomic_t;
+
+/// @brief 原子的读取指定的原子变量的值
+#[inline]
+pub fn atomic_read(ato:*const atomic_t)-> i64{
+    unsafe{
+        return read_volatile(&(*ato).value);
+    }
+}

+ 29 - 0
kernel/src/libs/ffi_convert.rs

@@ -0,0 +1,29 @@
+/// @brief 由bindgen生成的结构体转换成rust原生定义的结构体的特性
+pub trait FFIBind2Rust<T> {
+    /// 转换为不可变引用
+    fn convert_ref<'a>(src: *const T) -> Option<&'a Self>;
+    /// 转换为可变引用
+    fn convert_mut<'a>(src: *mut T) -> Option<&'a mut Self>;
+}
+
+
+
+pub fn __convert_mut<'a, S, D>(src:*mut S) ->Option<&'a mut D>{
+    return unsafe {
+        core::mem::transmute::<
+            *mut S,
+            *mut D,
+        >(src)
+        .as_mut()
+    };
+}
+
+pub fn __convert_ref<'a, S, D>(src:*const S) ->Option<&'a D>{
+    return unsafe {
+        core::mem::transmute::<
+            *const S,
+            *const D,
+        >(src)
+        .as_ref()
+    };
+}

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

@@ -2,7 +2,7 @@
 #include <common/compiler.h>
 
 #ifdef __LOCKREF_ENABLE_CMPXCHG__
-#include <arch/x86_64/asm/cmpxchg.h>
+#include <asm/cmpxchg.h>
 
 #define CMPXCHG_LOOP(__lock_ref, CODE, SUCCESS)                                                     \
     {                                                                                               \

+ 6 - 1
kernel/src/libs/mod.rs

@@ -1 +1,6 @@
-pub mod printk;
+pub mod printk;
+pub mod spinlock;
+pub mod ffi_convert;
+#[macro_use]
+pub mod refcount;
+pub mod atomic;

+ 54 - 0
kernel/src/libs/refcount.rs

@@ -0,0 +1,54 @@
+use crate::{include::bindings::bindings::{atomic_inc, atomic_t, atomic_dec}, kwarn};
+
+use super::{ffi_convert::{FFIBind2Rust, __convert_mut, __convert_ref}, atomic::atomic_read};
+
+#[derive(Debug, Copy, Clone)]
+pub struct RefCount {
+    pub refs: atomic_t,
+}
+
+/// @brief 将给定的来自bindgen的refcount_t解析为Rust的RefCount的引用
+impl FFIBind2Rust<crate::include::bindings::bindings::refcount_struct> for RefCount{
+    fn convert_mut<'a>(
+        src: *mut crate::include::bindings::bindings::refcount_struct,
+    ) -> Option<&'a mut Self> {
+        return __convert_mut(src);
+    }
+    fn convert_ref<'a>(
+        src: *const crate::include::bindings::bindings::refcount_struct,
+    ) -> Option<&'a Self> {
+        return __convert_ref(src)
+    }
+}
+
+macro_rules! REFCOUNT_INIT {
+    ($x:expr) => {
+        $crate::libs::refcount::RefCount {
+            refs: atomic_t { value: 0 },
+        }
+    };
+}
+
+/// @brief 引用计数自增1
+#[allow(dead_code)]
+#[inline]
+pub fn refcount_inc(r: &mut RefCount) {
+    if atomic_read(&r.refs) == 0{
+        kwarn!("Refcount increased from 0, may be use-after free");
+    }
+    
+    unsafe {
+        atomic_inc(&mut r.refs);
+    }
+}
+
+/// @brief 引用计数自减1
+#[allow(dead_code)]
+#[inline]
+pub fn refcount_dec(r: &mut RefCount){
+    unsafe{
+        atomic_dec(&mut r.refs);
+    }
+}
+
+

+ 30 - 0
kernel/src/libs/spinlock.rs

@@ -0,0 +1,30 @@
+#![allow(dead_code)]
+use core::ptr::read_volatile;
+
+use crate::arch::x86_64::asm::irqflags::{local_irq_restore, local_irq_save};
+use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
+
+/// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
+pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) {
+    local_irq_save(flags);
+    unsafe {
+        spin_lock(lock);
+    }
+}
+
+/// @brief 恢复rflags以及中断状态并解锁自旋锁
+#[no_mangle]
+pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) {
+    unsafe {
+        spin_unlock(lock);
+    }
+    // kdebug!("123");
+    local_irq_restore(flags);
+}
+
+/// 判断一个自旋锁是否已经被加锁
+pub fn spin_is_locked(lock: &spinlock_t) -> bool {
+    let val = unsafe { read_volatile(&lock.lock as *const i8) };
+
+    return if val == 0 { true } else { false };
+}

+ 391 - 0
kernel/src/process/fork.c

@@ -0,0 +1,391 @@
+#include "process.h"
+#include <common/err.h>
+#include <common/kthread.h>
+#include <common/spinlock.h>
+
+extern spinlock_t process_global_pid_write_lock;
+extern long process_global_pid;
+
+extern void kernel_thread_func(void);
+
+int process_copy_files(uint64_t clone_flags, struct process_control_block *pcb);
+int process_copy_flags(uint64_t clone_flags, struct process_control_block *pcb);
+int process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb);
+int process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
+                             uint64_t stack_size, struct pt_regs *current_regs);
+
+extern int process_copy_sighand(uint64_t clone_flags, struct process_control_block * pcb);
+extern int process_copy_signal(uint64_t clone_flags, struct process_control_block * pcb);
+
+
+/**
+ * @brief fork当前进程
+ *
+ * @param regs 新的寄存器值
+ * @param clone_flags 克隆标志
+ * @param stack_start 堆栈开始地址
+ * @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)
+{
+    int retval = 0;
+    struct process_control_block *tsk = NULL;
+
+    // 为新的进程分配栈空间,并将pcb放置在底部
+    tsk = (struct process_control_block *)kzalloc(STACK_SIZE, 0);
+    barrier();
+
+    if (tsk == NULL)
+    {
+        retval = -ENOMEM;
+        return retval;
+    }
+
+    barrier();
+    memset(tsk, 0, sizeof(struct process_control_block));
+    io_mfence();
+    // 将当前进程的pcb复制到新的pcb内
+    memcpy(tsk, current_pcb, sizeof(struct process_control_block));
+    tsk->worker_private = NULL;
+    io_mfence();
+
+    // 初始化进程的循环链表结点
+    list_init(&tsk->list);
+
+    io_mfence();
+    // 判断是否为内核态调用fork
+    if ((current_pcb->flags & PF_KTHREAD) && stack_start != 0)
+        tsk->flags |= PF_KFORK;
+
+    if (tsk->flags & PF_KTHREAD)
+    {
+        // 对于内核线程,设置其worker私有信息
+        retval = kthread_set_worker_private(tsk);
+        if (IS_ERR_VALUE(retval))
+            goto copy_flags_failed;
+        tsk->virtual_runtime = 0;
+    }
+    tsk->priority = 2;
+    tsk->preempt_count = 0;
+
+    // 增加全局的pid并赋值给新进程的pid
+    spin_lock(&process_global_pid_write_lock);
+    tsk->pid = process_global_pid++;
+    barrier();
+    // 加入到进程链表中
+    // todo: 对pcb_list_lock加锁
+    tsk->prev_pcb = &initial_proc_union.pcb;
+    barrier();
+    tsk->next_pcb = initial_proc_union.pcb.next_pcb;
+    barrier();
+    initial_proc_union.pcb.next_pcb = tsk;
+    barrier();
+    tsk->parent_pcb = current_pcb;
+    barrier();
+
+    spin_unlock(&process_global_pid_write_lock);
+
+    tsk->cpu_id = proc_current_cpu_id;
+    tsk->state = PROC_UNINTERRUPTIBLE;
+
+    tsk->parent_pcb = current_pcb;
+    wait_queue_init(&tsk->wait_child_proc_exit, NULL);
+    barrier();
+    list_init(&tsk->list);
+
+    retval = -ENOMEM;
+
+    // 拷贝标志位
+    retval = process_copy_flags(clone_flags, tsk);
+    if (retval)
+        goto copy_flags_failed;
+
+    // 拷贝内存空间分布结构体
+    retval = process_copy_mm(clone_flags, tsk);
+    if (retval)
+        goto copy_mm_failed;
+
+    // 拷贝文件
+    retval = process_copy_files(clone_flags, tsk);
+    if (retval)
+        goto copy_files_failed;
+    
+    // 拷贝信号处理函数
+    retval = process_copy_sighand(clone_flags, tsk);
+    if(retval)
+        goto copy_sighand_failed;
+    
+    retval = process_copy_signal(clone_flags, tsk);
+    if(retval)
+        goto copy_signal_failed;
+
+    // 拷贝线程结构体
+    retval = process_copy_thread(clone_flags, tsk, stack_start, stack_size, regs);
+    if (retval)
+        goto copy_thread_failed;
+
+    // 拷贝成功
+    retval = tsk->pid;
+
+    tsk->flags &= ~PF_KFORK;
+
+    // 唤醒进程
+    process_wakeup(tsk);
+
+    return retval;
+
+copy_thread_failed:;
+    // 回收线程
+    process_exit_thread(tsk);
+copy_files_failed:;
+    // 回收文件
+    process_exit_files(tsk);
+copy_sighand_failed:;
+    process_exit_sighand(tsk);
+copy_signal_failed:;
+    process_exit_signal(tsk);
+copy_mm_failed:;
+    // 回收内存空间分布结构体
+    process_exit_mm(tsk);
+copy_flags_failed:;
+    kfree(tsk);
+    return retval;
+}
+
+/**
+ * @brief 拷贝当前进程的标志位
+ *
+ * @param clone_flags 克隆标志位
+ * @param pcb 新的进程的pcb
+ * @return uint64_t
+ */
+int process_copy_flags(uint64_t clone_flags, struct process_control_block *pcb)
+{
+    if (clone_flags & CLONE_VM)
+        pcb->flags |= PF_VFORK;
+    return 0;
+}
+
+/**
+ * @brief 拷贝当前进程的文件描述符等信息
+ *
+ * @param clone_flags 克隆标志位
+ * @param pcb 新的进程的pcb
+ * @return uint64_t
+ */
+int process_copy_files(uint64_t clone_flags, struct process_control_block *pcb)
+{
+    int retval = 0;
+    // 如果CLONE_FS被置位,那么子进程与父进程共享文件描述符
+    // 文件描述符已经在复制pcb时被拷贝
+    if (clone_flags & CLONE_FS)
+        return retval;
+
+    // 为新进程拷贝新的文件描述符
+    for (int i = 0; i < PROC_MAX_FD_NUM; ++i)
+    {
+        if (current_pcb->fds[i] == NULL)
+            continue;
+
+        pcb->fds[i] = (struct vfs_file_t *)kmalloc(sizeof(struct vfs_file_t), 0);
+        memcpy(pcb->fds[i], current_pcb->fds[i], sizeof(struct vfs_file_t));
+    }
+
+    return retval;
+}
+
+/**
+ * @brief 拷贝当前进程的内存空间分布结构体信息
+ *
+ * @param clone_flags 克隆标志位
+ * @param pcb 新的进程的pcb
+ * @return uint64_t
+ */
+int process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb)
+{
+    int retval = 0;
+    // 与父进程共享内存空间
+    if (clone_flags & CLONE_VM)
+    {
+        pcb->mm = current_pcb->mm;
+
+        return retval;
+    }
+
+    // 分配新的内存空间分布结构体
+    struct mm_struct *new_mms = (struct mm_struct *)kmalloc(sizeof(struct mm_struct), 0);
+    memset(new_mms, 0, sizeof(struct mm_struct));
+
+    memcpy(new_mms, current_pcb->mm, sizeof(struct mm_struct));
+    new_mms->vmas = NULL;
+    pcb->mm = new_mms;
+
+    // 分配顶层页表, 并设置顶层页表的物理地址
+    new_mms->pgd = (pml4t_t *)virt_2_phys(kmalloc(PAGE_4K_SIZE, 0));
+    // 由于高2K部分为内核空间,在接下来需要覆盖其数据,因此不用清零
+    memset(phys_2_virt(new_mms->pgd), 0, PAGE_4K_SIZE / 2);
+
+    // 拷贝内核空间的页表指针
+    memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]->mm->pgd) + 256,
+           PAGE_4K_SIZE / 2);
+
+    uint64_t *current_pgd = (uint64_t *)phys_2_virt(current_pcb->mm->pgd);
+
+    uint64_t *new_pml4t = (uint64_t *)phys_2_virt(new_mms->pgd);
+
+    // 拷贝用户空间的vma
+    struct vm_area_struct *vma = current_pcb->mm->vmas;
+    while (vma != NULL)
+    {
+        if (vma->vm_end > USER_MAX_LINEAR_ADDR || vma->vm_flags & VM_DONTCOPY)
+        {
+            vma = vma->vm_next;
+            continue;
+        }
+
+        int64_t vma_size = vma->vm_end - vma->vm_start;
+        // kdebug("vma_size=%ld, vm_start=%#018lx", vma_size, vma->vm_start);
+        if (vma_size > PAGE_2M_SIZE / 2)
+        {
+            int page_to_alloc = (PAGE_2M_ALIGN(vma_size)) >> PAGE_2M_SHIFT;
+            for (int i = 0; i < page_to_alloc; ++i)
+            {
+                uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys;
+
+                struct vm_area_struct *new_vma = NULL;
+                int ret = mm_create_vma(new_mms, vma->vm_start + i * PAGE_2M_SIZE, PAGE_2M_SIZE, vma->vm_flags,
+                                        vma->vm_ops, &new_vma);
+                // 防止内存泄露
+                if (unlikely(ret == -EEXIST))
+                    free_pages(Phy_to_2M_Page(pa), 1);
+                else
+                    mm_map_vma(new_vma, pa, 0, PAGE_2M_SIZE);
+
+                memcpy((void *)phys_2_virt(pa), (void *)(vma->vm_start + i * PAGE_2M_SIZE),
+                       (vma_size >= PAGE_2M_SIZE) ? PAGE_2M_SIZE : vma_size);
+                vma_size -= PAGE_2M_SIZE;
+            }
+        }
+        else
+        {
+            uint64_t map_size = PAGE_4K_ALIGN(vma_size);
+            uint64_t va = (uint64_t)kmalloc(map_size, 0);
+
+            struct vm_area_struct *new_vma = NULL;
+            int ret = mm_create_vma(new_mms, vma->vm_start, map_size, vma->vm_flags, vma->vm_ops, &new_vma);
+            // 防止内存泄露
+            if (unlikely(ret == -EEXIST))
+                kfree((void *)va);
+            else
+                mm_map_vma(new_vma, virt_2_phys(va), 0, map_size);
+
+            memcpy((void *)va, (void *)vma->vm_start, vma_size);
+        }
+        vma = vma->vm_next;
+    }
+
+    return retval;
+}
+
+/**
+ * @brief 重写内核栈中的rbp地址
+ *
+ * @param new_regs 子进程的reg
+ * @param new_pcb 子进程的pcb
+ * @return int
+ */
+static int process_rewrite_rbp(struct pt_regs *new_regs, struct process_control_block *new_pcb)
+{
+
+    uint64_t new_top = ((uint64_t)new_pcb) + STACK_SIZE;
+    uint64_t old_top = (uint64_t)(current_pcb) + STACK_SIZE;
+
+    uint64_t *rbp = &new_regs->rbp;
+    uint64_t *tmp = rbp;
+
+    // 超出内核栈范围
+    if ((uint64_t)*rbp >= old_top || (uint64_t)*rbp < (old_top - STACK_SIZE))
+        return 0;
+
+    while (1)
+    {
+        // 计算delta
+        uint64_t delta = old_top - *rbp;
+        // 计算新的rbp值
+        uint64_t newVal = new_top - delta;
+
+        // 新的值不合法
+        if (unlikely((uint64_t)newVal >= new_top || (uint64_t)newVal < (new_top - STACK_SIZE)))
+            break;
+        // 将新的值写入对应位置
+        *rbp = newVal;
+        // 跳转栈帧
+        rbp = (uint64_t *)*rbp;
+    }
+
+    // 设置内核态fork返回到enter_syscall_int()函数内的时候,rsp寄存器的值
+    new_regs->rsp = new_top - (old_top - new_regs->rsp);
+    return 0;
+}
+
+/**
+ * @brief 拷贝当前进程的线程结构体
+ *
+ * @param clone_flags 克隆标志位
+ * @param pcb 新的进程的pcb
+ * @return uint64_t
+ */
+int process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
+                             uint64_t stack_size, struct pt_regs *current_regs)
+{
+    // 将线程结构体放置在pcb后方
+    struct thread_struct *thd = (struct thread_struct *)(pcb + 1);
+    memset(thd, 0, sizeof(struct thread_struct));
+    pcb->thread = thd;
+
+    struct pt_regs *child_regs = NULL;
+    // 拷贝栈空间
+    if (pcb->flags & PF_KFORK) // 内核态下的fork
+    {
+        // 内核态下则拷贝整个内核栈
+        uint32_t size = ((uint64_t)current_pcb) + STACK_SIZE - (uint64_t)(current_regs);
+
+        child_regs = (struct pt_regs *)(((uint64_t)pcb) + STACK_SIZE - size);
+        memcpy(child_regs, (void *)current_regs, size);
+        barrier();
+        // 然后重写新的栈中,每个栈帧的rbp值
+        process_rewrite_rbp(child_regs, pcb);
+    }
+    else
+    {
+        child_regs = (struct pt_regs *)((uint64_t)pcb + STACK_SIZE - sizeof(struct pt_regs));
+        memcpy(child_regs, current_regs, sizeof(struct pt_regs));
+        barrier();
+        child_regs->rsp = stack_start;
+    }
+
+    // 设置子进程的返回值为0
+    child_regs->rax = 0;
+    if (pcb->flags & PF_KFORK)
+        thd->rbp =
+            (uint64_t)(child_regs + 1); // 设置新的内核线程开始执行时的rbp(也就是进入ret_from_system_call时的rbp)
+    else
+        thd->rbp = (uint64_t)pcb + STACK_SIZE;
+
+    // 设置新的内核线程开始执行的时候的rsp
+    thd->rsp = (uint64_t)child_regs;
+    thd->fs = current_pcb->thread->fs;
+    thd->gs = current_pcb->thread->gs;
+
+    // 根据是否为内核线程、是否在内核态fork,设置进程的开始执行的地址
+    if (pcb->flags & PF_KFORK)
+        thd->rip = (uint64_t)ret_from_system_call;
+    else if (pcb->flags & PF_KTHREAD && (!(pcb->flags & PF_KFORK)))
+        thd->rip = (uint64_t)kernel_thread_func;
+    else
+        thd->rip = (uint64_t)ret_from_system_call;
+
+    return 0;
+}

+ 27 - 0
kernel/src/process/fork.rs

@@ -0,0 +1,27 @@
+use crate::{include::bindings::bindings::{process_control_block, CLONE_SIGHAND}, kdebug, libs::{refcount::{refcount_inc, RefCount}, ffi_convert::FFIBind2Rust}, arch::x86_64::asm::current::current_pcb};
+
+#[no_mangle]
+pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
+    kdebug!("process_copy_sighand");
+    if(clone_flags & (CLONE_SIGHAND as u64)) != 0{
+        let r = RefCount::convert_mut(unsafe{&mut (*((current_pcb().sighand))).count}).unwrap();
+       refcount_inc(r);
+    }
+    0
+}
+
+#[no_mangle]
+pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
+    kdebug!("process_copy_signal");
+    0
+}
+
+#[no_mangle]
+pub extern "C" fn process_exit_signal(pcb: *mut process_control_block){
+    // todo: 回收进程的信号结构体
+}
+
+#[no_mangle]
+pub extern "C" fn process_exit_sighand(pcb: *mut process_control_block){
+    // todo: 回收进程的sighand结构体
+}

+ 26 - 0
kernel/src/process/initial_proc.rs

@@ -0,0 +1,26 @@
+use crate::{
+    include::{
+        bindings::bindings::{atomic_t, spinlock_t, wait_queue_head_t, List},
+        DragonOS::signal::{sighand_struct, signal_struct, MAX_SIG_NUM},
+    },
+    ipc::signal::DEFAULT_SIGACTION,
+};
+
+#[no_mangle]
+pub static INITIAL_SIGNALS: signal_struct = signal_struct {
+    sig_cnt: atomic_t { value: 0 },
+};
+
+#[no_mangle]
+pub static mut INITIAL_SIGHAND: sighand_struct = sighand_struct {
+    count: REFCOUNT_INIT!(1),
+    siglock: spinlock_t { lock: 1 },
+    signal_fd_wqh: wait_queue_head_t {
+        lock: spinlock_t { lock: 1 },
+        wait_list: List {
+            prev: unsafe { &INITIAL_SIGHAND.signal_fd_wqh.wait_list as *const List } as *mut List,
+            next: unsafe { &INITIAL_SIGHAND.signal_fd_wqh.wait_list as *const List } as *mut List,
+        },
+    },
+    action: [DEFAULT_SIGACTION; MAX_SIG_NUM as usize],
+};

+ 5 - 0
kernel/src/process/mod.rs

@@ -0,0 +1,5 @@
+pub mod pid;
+pub mod process;
+pub mod preempt;
+pub mod initial_proc;
+pub mod fork;

+ 18 - 0
kernel/src/process/pid.rs

@@ -0,0 +1,18 @@
+#[allow(dead_code)]
+#[derive(Debug, Clone, Copy)]
+#[repr(u8)]
+pub enum PidType {
+    /// pid类型是进程id
+    PID = 1,
+    TGID = 2,
+    PGID = 3,
+    SID = 4,
+    MAX = 5,
+}
+
+/// 为PidType实现判断相等的trait
+impl PartialEq for PidType {
+    fn eq(&self, other: &PidType) -> bool {
+        *self as u8 == *other as u8
+    }
+}

+ 13 - 0
kernel/src/process/preempt.rs

@@ -0,0 +1,13 @@
+use crate::arch::x86_64::asm::current::current_pcb;
+
+/// @brief 增加进程的锁持有计数
+#[inline]
+pub fn preempt_disable() {
+    current_pcb().preempt_count += 1;
+}
+
+/// @brief 减少进程的锁持有计数
+#[inline]
+pub fn preempt_enable() {
+    current_pcb().preempt_count -= 1;
+}

+ 20 - 19
kernel/src/process/proc-types.h

@@ -1,7 +1,8 @@
 #pragma once
 
-#include <common/wait_queue.h>
+#include <stdint.h>
 #include <DragonOS/signal.h>
+#include <common/wait_queue.h>
 
 // 进程最大可拥有的文件描述符数量
 #define PROC_MAX_FD_NUM 16
@@ -12,9 +13,9 @@
 // 进程的运行状态
 // 正在运行
 #define PROC_RUNNING (1 << 0)
-// 可被
+// 可被信号打
 #define PROC_INTERRUPTIBLE (1 << 1)
-// 不可被
+// 不可被信号打
 #define PROC_UNINTERRUPTIBLE (1 << 2)
 // 挂起
 #define PROC_ZOMBIE (1 << 3)
@@ -32,8 +33,9 @@
 
 // 进程初始化时的数据拷贝标志位
 #define CLONE_FS (1UL << 0) // 在进程间共享打开的文件
-#define CLONE_SIGNAL (1UL << 1)
+#define CLONE_SIGNAL (1UL << 1) // 克隆时,与父进程共享信号结构体
 #define CLONE_VM (1UL << 2) // 在进程间共享虚拟内存空间
+#define CLONE_SIGHAND (1UL << 3) // 克隆时,与父进程共享信号处理结构体
 
 #define PCB_NAME_LEN 16
 
@@ -60,9 +62,10 @@ struct thread_struct
 #define PF_KTHREAD (1UL << 0)    // 内核线程
 #define PF_NEED_SCHED (1UL << 1) // 进程需要被调度
 #define PF_VFORK (1UL << 2)      // 标志进程是否由于vfork而存在资源共享
-#define PF_KFORK (1UL << 3)      // 标志在内核态下调用fork(临时标记,do_fork()结束后会将其复位)
-#define PF_NOFREEZE (1UL << 4)   // 当前进程不能被冻结
-
+#define PF_KFORK (1UL << 3)    // 标志在内核态下调用fork(临时标记,do_fork()结束后会将其复位)
+#define PF_NOFREEZE (1UL << 4) // 当前进程不能被冻结
+#define PF_EXITING (1UL << 5)  // 进程正在退出
+#define PF_WAKEKILL (1UL << 6) // 进程由于接收到终止信号唤醒
 /**
  * @brief 进程控制块
  *
@@ -70,12 +73,12 @@ struct thread_struct
 struct process_control_block
 {
     // 进程的状态
-    volatile long state;
+    volatile uint64_t state;
     // 进程标志:进程、线程、内核线程
-    unsigned long flags;
-    int64_t preempt_count; // 持有的自旋锁的数量
-    
-    long cpu_id; // 当前进程在哪个CPU核心上运行
+    uint64_t flags;
+    int32_t preempt_count; // 持有的自旋锁的数量
+
+    uint32_t cpu_id; // 当前进程在哪个CPU核心上运行
     char name[PCB_NAME_LEN];
 
     // 内存空间分布结构体, 记录内存页表和程序段信息
@@ -87,9 +90,9 @@ struct process_control_block
     // pcb加入调度队列时,所使用的链表节点
     struct List list;
 
-    //todo:给pcb中加一个spinlock_t成员
+    // todo:给pcb中加一个spinlock_t成员
     //进程自旋锁
-    // spinlock_t alloc_lock;
+    //  spinlock_t alloc_lock;
 
     // 地址空间范围
     // 用户空间: 0x0000 0000 0000 0000 ~ 0x0000 7fff ffff ffff
@@ -119,16 +122,14 @@ struct process_control_block
     // ==== 信号处理相关 =====
     struct signal_struct *signal;
     struct sighand_struct *sighand;
-    // 一个bitmap,表示被阻塞的信号
-    sigset_t blocked;
+    // 一个bitmap,表示当前进程被禁用的信号
+    sigset_t sig_blocked;
     // 正在等待的信号的标志位,表示某个信号正在等待处理
     struct sigpending sig_pending;
-
 };
 
 // 将进程的pcb和内核栈融合到一起,8字节对齐
-union proc_union
-{
+union proc_union {
     struct process_control_block pcb;
     ul stack[STACK_SIZE / sizeof(ul)];
 } __attribute__((aligned(8)));

+ 25 - 400
kernel/src/process/process.c

@@ -1,5 +1,6 @@
 #include "process.h"
 
+#include <DragonOS/signal.h>
 #include <common/compiler.h>
 #include <common/completion.h>
 #include <common/elf.h>
@@ -21,13 +22,12 @@
 #include <filesystem/devfs/devfs.h>
 #include <filesystem/fat32/fat32.h>
 #include <filesystem/rootfs/rootfs.h>
+#include <ktest/ktest.h>
 #include <mm/slab.h>
 #include <sched/sched.h>
 #include <syscall/syscall.h>
 #include <syscall/syscall_num.h>
 
-#include <ktest/ktest.h>
-
 #include <mm/mmio.h>
 
 #include <common/lz4.h>
@@ -43,6 +43,19 @@ extern void kernel_thread_func(void);
 
 ul _stack_start; // initial proc的栈基地址(虚拟地址)
 extern struct mm_struct initial_mm;
+extern struct signal_struct INITIAL_SIGNALS;
+extern struct sighand_struct INITIAL_SIGHAND;
+
+// 设置初始进程的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, .prev_pcb = &proc, .parent_pcb = &proc, .exit_code = 0,   \
+        .wait_child_proc_exit = 0, .worker_private = NULL, .policy = SCHED_NORMAL, .sig_blocked = 0,                   \
+        .signal = &INITIAL_SIGNALS, .sighand = &INITIAL_SIGHAND,                                                       \
+    }
+
 struct thread_struct initial_thread = {
     .rbp = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)),
     .rsp = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)),
@@ -62,24 +75,6 @@ struct process_control_block *initial_proc[MAX_CPU_NUM] = {&initial_proc_union.p
 // 为每个核心初始化初始进程的tss
 struct tss_struct initial_tss[MAX_CPU_NUM] = {[0 ... MAX_CPU_NUM - 1] = INITIAL_TSS};
 
-/**
- * @brief 拷贝当前进程的标志位
- *
- * @param clone_flags 克隆标志位
- * @param pcb 新的进程的pcb
- * @return uint64_t
- */
-uint64_t process_copy_flags(uint64_t clone_flags, struct process_control_block *pcb);
-
-/**
- * @brief 拷贝当前进程的文件描述符等信息
- *
- * @param clone_flags 克隆标志位
- * @param pcb 新的进程的pcb
- * @return uint64_t
- */
-uint64_t process_copy_files(uint64_t clone_flags, struct process_control_block *pcb);
-
 /**
  * @brief 回收进程的所有文件描述符
  *
@@ -88,15 +83,6 @@ uint64_t process_copy_files(uint64_t clone_flags, struct process_control_block *
  */
 uint64_t process_exit_files(struct process_control_block *pcb);
 
-/**
- * @brief 拷贝当前进程的内存空间分布结构体信息
- *
- * @param clone_flags 克隆标志位
- * @param pcb 新的进程的pcb
- * @return uint64_t
- */
-uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb);
-
 /**
  * @brief 释放进程的页表
  *
@@ -105,17 +91,7 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
  */
 uint64_t process_exit_mm(struct process_control_block *pcb);
 
-/**
- * @brief 拷贝当前进程的线程结构体
- *
- * @param clone_flags 克隆标志位
- * @param pcb 新的进程的pcb
- * @return uint64_t
- */
-uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
-                             uint64_t stack_size, struct pt_regs *current_regs);
 
-void process_exit_thread(struct process_control_block *pcb);
 
 /**
  * @brief 切换进程
@@ -644,6 +620,7 @@ void process_init()
 
     // 初始化进程的循环链表
     list_init(&initial_proc_union.pcb.list);
+    wait_queue_init(&initial_proc_union.pcb.wait_child_proc_exit, NULL);
 
     // 临时设置IDLE进程的的虚拟运行时间为0,防止下面的这些内核线程的虚拟运行时间出错
     current_pcb->virtual_runtime = 0;
@@ -660,130 +637,9 @@ void process_init()
     current_pcb->virtual_runtime = (1UL << 60);
 }
 
-/**
- * @brief fork当前进程
- *
- * @param regs 新的寄存器值
- * @param clone_flags 克隆标志
- * @param stack_start 堆栈开始地址
- * @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)
-{
-    int retval = 0;
-    struct process_control_block *tsk = NULL;
-
-    // 为新的进程分配栈空间,并将pcb放置在底部
-    tsk = (struct process_control_block *)kzalloc(STACK_SIZE, 0);
-    barrier();
-
-    if (tsk == NULL)
-    {
-        retval = -ENOMEM;
-        return retval;
-    }
-
-    barrier();
-    memset(tsk, 0, sizeof(struct process_control_block));
-    io_mfence();
-    // 将当前进程的pcb复制到新的pcb内
-    memcpy(tsk, current_pcb, sizeof(struct process_control_block));
-    tsk->worker_private = NULL;
-    io_mfence();
-
-    // 初始化进程的循环链表结点
-    list_init(&tsk->list);
-
-    io_mfence();
-    // 判断是否为内核态调用fork
-    if ((current_pcb->flags & PF_KTHREAD) && stack_start != 0)
-        tsk->flags |= PF_KFORK;
-
-    if (tsk->flags & PF_KTHREAD)
-    {
-        // 对于内核线程,设置其worker私有信息
-        retval = kthread_set_worker_private(tsk);
-        if (IS_ERR_VALUE(retval))
-            goto copy_flags_failed;
-        tsk->virtual_runtime = 0;
-    }
-    tsk->priority = 2;
-    tsk->preempt_count = 0;
-
-    // 增加全局的pid并赋值给新进程的pid
-    spin_lock(&process_global_pid_write_lock);
-    tsk->pid = process_global_pid++;
-    barrier();
-    // 加入到进程链表中
-    // todo: 对pcb_list_lock加锁
-    tsk->prev_pcb = &initial_proc_union.pcb;
-    barrier();
-    tsk->next_pcb = initial_proc_union.pcb.next_pcb;
-    barrier();
-    initial_proc_union.pcb.next_pcb = tsk;
-    barrier();
-    tsk->parent_pcb = current_pcb;
-    barrier();
-
-    spin_unlock(&process_global_pid_write_lock);
-
-    tsk->cpu_id = proc_current_cpu_id;
-    tsk->state = PROC_UNINTERRUPTIBLE;
-
-    tsk->parent_pcb = current_pcb;
-    wait_queue_init(&tsk->wait_child_proc_exit, NULL);
-    barrier();
-    list_init(&tsk->list);
-
-    retval = -ENOMEM;
-
-    // 拷贝标志位
-    if (process_copy_flags(clone_flags, tsk))
-        goto copy_flags_failed;
-
-    // 拷贝内存空间分布结构体
-    if (process_copy_mm(clone_flags, tsk))
-        goto copy_mm_failed;
-
-    // 拷贝文件
-    if (process_copy_files(clone_flags, tsk))
-        goto copy_files_failed;
-
-    // 拷贝线程结构体
-    if (process_copy_thread(clone_flags, tsk, stack_start, stack_size, regs))
-        goto copy_thread_failed;
-
-    // 拷贝成功
-    retval = tsk->pid;
-
-    tsk->flags &= ~PF_KFORK;
-
-    // 唤醒进程
-    process_wakeup(tsk);
-
-    return retval;
-
-copy_thread_failed:;
-    // 回收线程
-    process_exit_thread(tsk);
-copy_files_failed:;
-    // 回收文件
-    process_exit_files(tsk);
-copy_mm_failed:;
-    // 回收内存空间分布结构体
-    process_exit_mm(tsk);
-copy_flags_failed:;
-    kfree(tsk);
-    return retval;
-
-    return 0;
-}
-
 /**
  * @brief 根据pid获取进程的pcb。存在对应的pcb时,返回对应的pcb的指针,否则返回NULL
- *
+ *  当进程管理模块拥有pcblist_lock之后,调用本函数之前,应当对其加锁
  * @param pid
  * @return struct process_control_block*
  */
@@ -803,16 +659,19 @@ struct process_control_block *process_find_pcb_by_pid(pid_t pid)
 }
 
 /**
- * @brief 将进程加入到调度器的就绪队列中
+ * @brief 将进程加入到调度器的就绪队列中.
  *
  * @param pcb 进程的pcb
+ *
+ * @return true 成功加入调度队列
+ * @return false 进程已经在运行
  */
 int process_wakeup(struct process_control_block *pcb)
 {
     // kdebug("pcb pid = %#018lx", pcb->pid);
 
     BUG_ON(pcb == NULL);
-    if (pcb == current_pcb || pcb == NULL)
+    if (pcb == NULL)
         return -EINVAL;
     // 如果pcb正在调度队列中,则不重复加入调度队列
     if (pcb->state & PROC_RUNNING)
@@ -820,7 +679,7 @@ int process_wakeup(struct process_control_block *pcb)
 
     pcb->state |= PROC_RUNNING;
     sched_enqueue(pcb);
-    return 0;
+    return 1;
 }
 
 /**
@@ -838,47 +697,6 @@ int process_wakeup_immediately(struct process_control_block *pcb)
     // 将当前进程标志为需要调度,缩短新进程被wakeup的时间
     current_pcb->flags |= PF_NEED_SCHED;
 }
-/**
- * @brief 拷贝当前进程的标志位
- *
- * @param clone_flags 克隆标志位
- * @param pcb 新的进程的pcb
- * @return uint64_t
- */
-uint64_t process_copy_flags(uint64_t clone_flags, struct process_control_block *pcb)
-{
-    if (clone_flags & CLONE_VM)
-        pcb->flags |= PF_VFORK;
-    return 0;
-}
-
-/**
- * @brief 拷贝当前进程的文件描述符等信息
- *
- * @param clone_flags 克隆标志位
- * @param pcb 新的进程的pcb
- * @return uint64_t
- */
-uint64_t process_copy_files(uint64_t clone_flags, struct process_control_block *pcb)
-{
-    int retval = 0;
-    // 如果CLONE_FS被置位,那么子进程与父进程共享文件描述符
-    // 文件描述符已经在复制pcb时被拷贝
-    if (clone_flags & CLONE_FS)
-        return retval;
-
-    // 为新进程拷贝新的文件描述符
-    for (int i = 0; i < PROC_MAX_FD_NUM; ++i)
-    {
-        if (current_pcb->fds[i] == NULL)
-            continue;
-
-        pcb->fds[i] = (struct vfs_file_t *)kmalloc(sizeof(struct vfs_file_t), 0);
-        memcpy(pcb->fds[i], current_pcb->fds[i], sizeof(struct vfs_file_t));
-    }
-
-    return retval;
-}
 
 /**
  * @brief 回收进程的所有文件描述符
@@ -903,99 +721,6 @@ uint64_t process_exit_files(struct process_control_block *pcb)
     memset(pcb->fds, 0, sizeof(struct vfs_file_t *) * PROC_MAX_FD_NUM);
 }
 
-/**
- * @brief 拷贝当前进程的内存空间分布结构体信息
- *
- * @param clone_flags 克隆标志位
- * @param pcb 新的进程的pcb
- * @return uint64_t
- */
-uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb)
-{
-    int retval = 0;
-    // 与父进程共享内存空间
-    if (clone_flags & CLONE_VM)
-    {
-        pcb->mm = current_pcb->mm;
-
-        return retval;
-    }
-
-    // 分配新的内存空间分布结构体
-    struct mm_struct *new_mms = (struct mm_struct *)kmalloc(sizeof(struct mm_struct), 0);
-    memset(new_mms, 0, sizeof(struct mm_struct));
-
-    memcpy(new_mms, current_pcb->mm, sizeof(struct mm_struct));
-    new_mms->vmas = NULL;
-    pcb->mm = new_mms;
-
-    // 分配顶层页表, 并设置顶层页表的物理地址
-    new_mms->pgd = (pml4t_t *)virt_2_phys(kmalloc(PAGE_4K_SIZE, 0));
-    // 由于高2K部分为内核空间,在接下来需要覆盖其数据,因此不用清零
-    memset(phys_2_virt(new_mms->pgd), 0, PAGE_4K_SIZE / 2);
-
-    // 拷贝内核空间的页表指针
-    memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]->mm->pgd) + 256,
-           PAGE_4K_SIZE / 2);
-
-    uint64_t *current_pgd = (uint64_t *)phys_2_virt(current_pcb->mm->pgd);
-
-    uint64_t *new_pml4t = (uint64_t *)phys_2_virt(new_mms->pgd);
-
-    // 拷贝用户空间的vma
-    struct vm_area_struct *vma = current_pcb->mm->vmas;
-    while (vma != NULL)
-    {
-        if (vma->vm_end > USER_MAX_LINEAR_ADDR || vma->vm_flags & VM_DONTCOPY)
-        {
-            vma = vma->vm_next;
-            continue;
-        }
-
-        int64_t vma_size = vma->vm_end - vma->vm_start;
-        // kdebug("vma_size=%ld, vm_start=%#018lx", vma_size, vma->vm_start);
-        if (vma_size > PAGE_2M_SIZE / 2)
-        {
-            int page_to_alloc = (PAGE_2M_ALIGN(vma_size)) >> PAGE_2M_SHIFT;
-            for (int i = 0; i < page_to_alloc; ++i)
-            {
-                uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys;
-
-                struct vm_area_struct *new_vma = NULL;
-                int ret = mm_create_vma(new_mms, vma->vm_start + i * PAGE_2M_SIZE, PAGE_2M_SIZE, vma->vm_flags,
-                                        vma->vm_ops, &new_vma);
-                // 防止内存泄露
-                if (unlikely(ret == -EEXIST))
-                    free_pages(Phy_to_2M_Page(pa), 1);
-                else
-                    mm_map_vma(new_vma, pa, 0, PAGE_2M_SIZE);
-
-                memcpy((void *)phys_2_virt(pa), (void *)(vma->vm_start + i * PAGE_2M_SIZE),
-                       (vma_size >= PAGE_2M_SIZE) ? PAGE_2M_SIZE : vma_size);
-                vma_size -= PAGE_2M_SIZE;
-            }
-        }
-        else
-        {
-            uint64_t map_size = PAGE_4K_ALIGN(vma_size);
-            uint64_t va = (uint64_t)kmalloc(map_size, 0);
-
-            struct vm_area_struct *new_vma = NULL;
-            int ret = mm_create_vma(new_mms, vma->vm_start, map_size, vma->vm_flags, vma->vm_ops, &new_vma);
-            // 防止内存泄露
-            if (unlikely(ret == -EEXIST))
-                kfree((void *)va);
-            else
-                mm_map_vma(new_vma, virt_2_phys(va), 0, map_size);
-
-            memcpy((void *)va, (void *)vma->vm_start, vma_size);
-        }
-        vma = vma->vm_next;
-    }
-
-    return retval;
-}
-
 /**
  * @brief 释放进程的页表
  *
@@ -1059,106 +784,6 @@ uint64_t process_exit_mm(struct process_control_block *pcb)
     return 0;
 }
 
-/**
- * @brief 重写内核栈中的rbp地址
- *
- * @param new_regs 子进程的reg
- * @param new_pcb 子进程的pcb
- * @return int
- */
-static int process_rewrite_rbp(struct pt_regs *new_regs, struct process_control_block *new_pcb)
-{
-
-    uint64_t new_top = ((uint64_t)new_pcb) + STACK_SIZE;
-    uint64_t old_top = (uint64_t)(current_pcb) + STACK_SIZE;
-
-    uint64_t *rbp = &new_regs->rbp;
-    uint64_t *tmp = rbp;
-
-    // 超出内核栈范围
-    if ((uint64_t)*rbp >= old_top || (uint64_t)*rbp < (old_top - STACK_SIZE))
-        return 0;
-
-    while (1)
-    {
-        // 计算delta
-        uint64_t delta = old_top - *rbp;
-        // 计算新的rbp值
-        uint64_t newVal = new_top - delta;
-
-        // 新的值不合法
-        if (unlikely((uint64_t)newVal >= new_top || (uint64_t)newVal < (new_top - STACK_SIZE)))
-            break;
-        // 将新的值写入对应位置
-        *rbp = newVal;
-        // 跳转栈帧
-        rbp = (uint64_t *)*rbp;
-    }
-
-    // 设置内核态fork返回到enter_syscall_int()函数内的时候,rsp寄存器的值
-    new_regs->rsp = new_top - (old_top - new_regs->rsp);
-    return 0;
-}
-
-/**
- * @brief 拷贝当前进程的线程结构体
- *
- * @param clone_flags 克隆标志位
- * @param pcb 新的进程的pcb
- * @return uint64_t
- */
-uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
-                             uint64_t stack_size, struct pt_regs *current_regs)
-{
-    // 将线程结构体放置在pcb后方
-    struct thread_struct *thd = (struct thread_struct *)(pcb + 1);
-    memset(thd, 0, sizeof(struct thread_struct));
-    pcb->thread = thd;
-
-    struct pt_regs *child_regs = NULL;
-    // 拷贝栈空间
-    if (pcb->flags & PF_KFORK) // 内核态下的fork
-    {
-        // 内核态下则拷贝整个内核栈
-        uint32_t size = ((uint64_t)current_pcb) + STACK_SIZE - (uint64_t)(current_regs);
-
-        child_regs = (struct pt_regs *)(((uint64_t)pcb) + STACK_SIZE - size);
-        memcpy(child_regs, (void *)current_regs, size);
-        barrier();
-        // 然后重写新的栈中,每个栈帧的rbp值
-        process_rewrite_rbp(child_regs, pcb);
-    }
-    else
-    {
-        child_regs = (struct pt_regs *)((uint64_t)pcb + STACK_SIZE - sizeof(struct pt_regs));
-        memcpy(child_regs, current_regs, sizeof(struct pt_regs));
-        barrier();
-        child_regs->rsp = stack_start;
-    }
-
-    // 设置子进程的返回值为0
-    child_regs->rax = 0;
-    if (pcb->flags & PF_KFORK)
-        thd->rbp =
-            (uint64_t)(child_regs + 1); // 设置新的内核线程开始执行时的rbp(也就是进入ret_from_system_call时的rbp)
-    else
-        thd->rbp = (uint64_t)pcb + STACK_SIZE;
-
-    // 设置新的内核线程开始执行的时候的rsp
-    thd->rsp = (uint64_t)child_regs;
-    thd->fs = current_pcb->thread->fs;
-    thd->gs = current_pcb->thread->gs;
-
-    // 根据是否为内核线程、是否在内核态fork,设置进程的开始执行的地址
-    if (pcb->flags & PF_KFORK)
-        thd->rip = (uint64_t)ret_from_system_call;
-    else if (pcb->flags & PF_KTHREAD && (!(pcb->flags & PF_KFORK)))
-        thd->rip = (uint64_t)kernel_thread_func;
-    else
-        thd->rip = (uint64_t)ret_from_system_call;
-
-    return 0;
-}
 
 /**
  * @brief todo: 回收线程结构体
@@ -1181,12 +806,12 @@ int process_release_pcb(struct process_control_block *pcb)
     process_exit_mm(pcb);
     if ((pcb->flags & PF_KTHREAD)) // 释放内核线程的worker private结构体
         free_kthread_struct(pcb);
-    
+
     // 将pcb从pcb链表中移除
     // todo: 对相关的pcb加锁
     pcb->prev_pcb->next_pcb = pcb->next_pcb;
     pcb->next_pcb->prev_pcb = pcb->prev_pcb;
-    
+
     // 释放当前pcb
     kfree(pcb);
     return 0;

+ 32 - 9
kernel/src/process/process.h

@@ -22,14 +22,8 @@
 
 #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, .prev_pcb = &proc, .parent_pcb = &proc, .exit_code = 0,    \
-        .wait_child_proc_exit = 0, .worker_private = NULL, .policy = SCHED_NORMAL                                      \
-    }
+extern void process_exit_thread(struct process_control_block *pcb);
+extern uint64_t process_exit_files(struct process_control_block *pcb);
 
 /**
  * @brief 任务状态段结构体
@@ -96,7 +90,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
 
 /**
  * @brief 根据pid获取进程的pcb。存在对应的pcb时,返回对应的pcb的指针,否则返回NULL
- *
+ * 当进程管理模块拥有pcblist_lock之后,调用本函数之前,应当对其加锁
  * @param pid
  * @return struct process_control_block*
  */
@@ -106,6 +100,8 @@ struct process_control_block *process_find_pcb_by_pid(pid_t pid);
  * @brief 将进程加入到调度器的就绪队列中
  *
  * @param pcb 进程的pcb
+ *
+ * @return 如果进程被成功唤醒,则返回1,如果进程正在运行,则返回0.如果pcb为NULL,则返回-EINVAL
  */
 int process_wakeup(struct process_control_block *pcb);
 
@@ -197,3 +193,30 @@ extern struct process_control_block *initial_proc[MAX_CPU_NUM];
  * @param pcb_name 保存名字的char数组
  */
 void process_set_pcb_name(struct process_control_block *pcb, const char *pcb_name);
+
+/**
+ * @brief 判断进程是否已经停止
+ *
+ * hint: 本函数在rust中实现,请参考rust版本的注释
+ *
+ * @param pcb 目标pcb
+ * @return true
+ * @return false
+ */
+extern bool process_is_stopped(struct process_control_block *pcb);
+
+/**
+ * @brief 尝试唤醒指定的进程。
+ * 本函数的行为:If (@_state & @pcb->state) @pcb->state = TASK_RUNNING.
+ *
+ * hint: 本函数在rust中实现,请参考rust版本的注释
+ */
+extern int process_try_to_wake_up(struct process_control_block *_pcb, uint64_t _state, int32_t _wake_flags);
+
+/** @brief 当进程,满足 (@state & @pcb->state)时,唤醒进程,并设置: @pcb->state = TASK_RUNNING.
+ *
+ * hint: 本函数在rust中实现,请参考rust版本的注释
+ * @return true 唤醒成功
+ * @return false 唤醒失败
+ */
+extern int process_wake_up_state(struct process_control_block *pcb, uint64_t state);

+ 103 - 0
kernel/src/process/process.rs

@@ -0,0 +1,103 @@
+use core::ptr::{read_volatile, write_volatile};
+
+use crate::{
+    arch::x86_64::asm::current::current_pcb,
+    include::bindings::bindings::{
+        process_control_block, sched_enqueue, PROC_RUNNING, PROC_STOPPED,
+    },
+    sched::core::cpu_executing,
+    smp::core::{smp_get_processor_id, smp_send_reschedule},
+};
+
+use super::preempt::{preempt_disable, preempt_enable};
+
+/// 判断进程是否已经停止
+#[no_mangle]
+pub extern "C" fn process_is_stopped(pcb: *const process_control_block) -> bool {
+    let state: u64 = unsafe { read_volatile(&(*pcb).state) } as u64;
+    if (state & (PROC_STOPPED as u64)) != 0 {
+        return true;
+    } else {
+        return false;
+    }
+}
+
+/// @brief 尝试唤醒指定的进程。
+/// 本函数的行为:If (@_state & @pcb->state) @pcb->state = TASK_RUNNING.
+///
+/// @param _pcb 要被唤醒的进程的pcb
+/// @param _state 如果pcb的state与_state匹配,则唤醒这个进程
+/// @param _wake_flags 保留,暂未使用,请置为0
+/// @return true: 成功唤醒
+///         false: 不符合唤醒条件,无法唤醒
+#[no_mangle]
+pub extern "C" fn process_try_to_wake_up(
+    _pcb: *mut process_control_block,
+    _state: u64,
+    _wake_flags: i32,
+) -> bool {
+    preempt_disable();
+
+    let mut retval = false;
+    // 获取对pcb的可变引用
+    let pcb = unsafe { _pcb.as_mut() }.unwrap();
+
+    // 如果要唤醒的就是当前的进程
+    if current_pcb() as *mut process_control_block as usize == _pcb as usize {
+        unsafe {
+            write_volatile(&mut pcb.state, PROC_RUNNING as u64);
+        }
+        preempt_enable();
+        retval = true;
+        return retval;
+    }
+    // todo: 将来调度器引入ttwu队列之后,需要修改这里的判断条件
+
+    // todo: 为pcb引入pi_lock,然后在这里加锁
+    if unsafe { read_volatile(&pcb.state) } & _state != 0 {
+        // 可以wakeup
+        unsafe {
+            write_volatile(&mut pcb.state, PROC_RUNNING as u64);
+            sched_enqueue(pcb);
+        }
+        retval = true;
+    }
+    // todo: 对pcb的pi_lock放锁
+    preempt_enable();
+    return retval;
+}
+
+/// @brief 当进程,满足 (@state & @pcb->state)时,唤醒进程,并设置: @pcb->state = TASK_RUNNING.
+///
+/// @return true 唤醒成功
+/// @return false 唤醒失败
+#[no_mangle]
+pub extern "C" fn process_wake_up_state(pcb: *mut process_control_block, state: u64) -> bool {
+    return process_try_to_wake_up(pcb, state, 0);
+}
+
+
+/// @brief 让一个正在cpu上运行的进程陷入内核
+pub fn process_kick(pcb: *mut process_control_block) {
+    preempt_disable();
+    let cpu = process_cpu(pcb);
+    // 如果给定的进程正在别的核心上执行,则立即发送请求,让它陷入内核态,以及时响应信号。
+    if cpu != smp_get_processor_id() && process_is_executing(pcb) {
+        smp_send_reschedule(cpu);
+    }
+    preempt_enable();
+}
+
+/// @brief 获取给定的进程在哪个cpu核心上运行(使用volatile避免编译器优化)
+#[inline]
+pub fn process_cpu(pcb: *const process_control_block) -> u32 {
+    unsafe { read_volatile(&(*pcb).cpu_id) }
+}
+
+/// @brief 判断给定的进程是否正在处理器上执行
+///
+/// @param pcb 进程的pcb
+#[inline]
+pub fn process_is_executing(pcb: *const process_control_block) -> bool {
+    return cpu_executing(process_cpu(pcb)) == pcb;
+}

+ 13 - 0
kernel/src/sched/core.rs

@@ -0,0 +1,13 @@
+use crate::{include::bindings::bindings::process_control_block, process::process::process_cpu, arch::x86_64::asm::current::current_pcb};
+
+/// @brief 获取指定的cpu上正在执行的进程的pcb
+#[inline]
+pub fn cpu_executing(cpu_id:u32) -> *const process_control_block{
+    // todo: 引入per_cpu之后,该函数真正执行“返回指定的cpu上正在执行的pcb”的功能
+
+    if cpu_id == process_cpu(current_pcb()){
+        return current_pcb();
+    }else {
+        todo!()
+    }
+}

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

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

+ 1 - 0
kernel/src/sched/sched.c

@@ -4,6 +4,7 @@
 #include <driver/video/video.h>
 #include <sched/cfs.h>
 #include <common/string.h>
+
 /**
  * @brief
  *

+ 14 - 0
kernel/src/smp/core.rs

@@ -0,0 +1,14 @@
+/// @brief 获取当前的cpu id
+#[inline]
+pub fn smp_get_processor_id() -> u32 {
+    if cfg!(x86_64) {
+        return crate::arch::x86_64::cpu::arch_current_apic_id() as u32;
+    } else {
+        255
+    }
+}
+
+#[inline]
+pub fn smp_send_reschedule(_cpu: u32) {
+    // todo:
+}

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

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

+ 5 - 4
kernel/src/syscall/syscall.c

@@ -1,6 +1,7 @@
 #include "syscall.h"
 #include <common/errno.h>
 #include <common/fcntl.h>
+#include <common/kthread.h>
 #include <common/string.h>
 #include <driver/disk/ahci/ahci.h>
 #include <exception/gate.h>
@@ -10,7 +11,6 @@
 #include <mm/slab.h>
 #include <process/process.h>
 #include <time/sleep.h>
-#include <common/kthread.h>
 // 导出系统调用入口函数,定义在entry.S中
 extern void system_call(void);
 extern void syscall_int(void);
@@ -19,6 +19,7 @@ extern uint64_t sys_clock(struct pt_regs *regs);
 extern uint64_t sys_mstat(struct pt_regs *regs);
 extern uint64_t sys_open(struct pt_regs *regs);
 extern uint64_t sys_unlink_at(struct pt_regs *regs);
+extern uint64_t sys_kill(struct pt_regs *regs);
 
 /**
  * @brief 导出系统调用处理函数的符号
@@ -518,7 +519,7 @@ uint64_t sys_wait4(struct pt_regs *regs)
     // 查找pid为指定值的进程
     // ps: 这里判断子进程的方法没有按照posix 2008来写。
     // todo: 根据进程树判断是否为当前进程的子进程
-    
+    // todo: 当进程管理模块拥有pcblist_lock之后,调用之前,应当对其加锁
     child_proc = process_find_pcb_by_pid(pid);
 
     if (child_proc == NULL)
@@ -598,7 +599,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
     [20] = sys_pipe,
     [21] = sys_mstat,
     [22] = sys_unlink_at,
-    [23 ... 254] = system_call_not_exists,
+    [23] = sys_kill,
+    [24 ... 254] = system_call_not_exists,
     [255] = sys_ahci_end_req,
 };
-

+ 1 - 0
kernel/src/syscall/syscall_num.h

@@ -34,5 +34,6 @@
 
 #define SYS_MSTAT 21     // 获取系统的内存状态信息
 #define SYS_UNLINK_AT 22 // 删除文件夹/删除文件链接
+#define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
 
 #define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用

+ 28 - 7
user/apps/shell/cmd.c

@@ -4,6 +4,7 @@
 #include <libc/dirent.h>
 #include <libc/errno.h>
 #include <libc/fcntl.h>
+#include <libc/include/signal.h>
 #include <libc/stddef.h>
 #include <libc/stdio.h>
 #include <libc/stdlib.h>
@@ -23,7 +24,7 @@ struct built_in_cmd_t shell_cmds[] = {
     {"cd", shell_cmd_cd},         {"cat", shell_cmd_cat},     {"exec", shell_cmd_exec},   {"ls", shell_cmd_ls},
     {"mkdir", shell_cmd_mkdir},   {"pwd", shell_cmd_pwd},     {"rm", shell_cmd_rm},       {"rmdir", shell_cmd_rmdir},
     {"reboot", shell_cmd_reboot}, {"touch", shell_cmd_touch}, {"about", shell_cmd_about}, {"free", shell_cmd_free},
-    {"help", shell_help},         {"pipe", shell_pipe_test},
+    {"help", shell_help},         {"pipe", shell_pipe_test},  {"kill", shell_cmd_kill},
 
 };
 // 总共的内建命令数量
@@ -331,11 +332,14 @@ int shell_cmd_touch(int argc, char **argv)
 {
     int path_len = 0;
     char *file_path;
-    bool alloc_full_path=false;
+    bool alloc_full_path = false;
     if (argv[1][0] == '/')
         file_path = argv[1];
     else
-        {file_path = get_target_filepath(argv[1], &path_len);alloc_full_path=true;}
+    {
+        file_path = get_target_filepath(argv[1], &path_len);
+        alloc_full_path = true;
+    }
 
     // 打开文件
     int fd = open(file_path, O_CREAT);
@@ -351,7 +355,7 @@ int shell_cmd_touch(int argc, char **argv)
     close(fd);
     if (argv != NULL)
         free(argv);
-    if(alloc_full_path)
+    if (alloc_full_path)
         free(file_path);
     return 0;
 }
@@ -425,7 +429,7 @@ int shell_cmd_rmdir(int argc, char **argv)
  */
 int shell_cmd_rm(int argc, char **argv)
 {
-     char *full_path = NULL;
+    char *full_path = NULL;
     int result_path_len = -1;
     int retval = 0;
     bool alloc_full_path = false;
@@ -472,7 +476,7 @@ int shell_cmd_exec(int argc, char **argv)
         execv(file_path, argv);
         free(argv);
         free(file_path);
-        
+
         exit(-1);
     }
     else
@@ -498,7 +502,24 @@ int shell_cmd_about(int argc, char **argv)
 
     parse_command(input_buffer, &aac, &aav);
 
-    shell_cmd_exec(aac, aav);
+    return shell_cmd_exec(aac, aav);
+}
+
+int shell_cmd_kill(int argc, char **argv)
+{
+    int retval = 0;
+    if (argc < 2)
+    {
+        printf("Usage: Kill <pid>\n");
+        retval = -EINVAL;
+        goto out;
+    }
+    printf("argc = %d, argv[1]=%s\n", argc, argv[1]);
+    printf("atoi(argv[1])=%d\n", atoi(argv[1]));
+    retval = syscall_invoke(SYS_KILL, atoi(argv[1]), SIGKILL, 0, 0, 0, 0, 0, 0);
+out:;
+    free(argv);
+    return retval;
 }
 
 /**

+ 3 - 1
user/apps/shell/cmd.h

@@ -149,4 +149,6 @@ int shell_cmd_free(int argc, char **argv);
  * @param argv 返回值:参数列表
  * @return int
  */
-int parse_command(char *buf, int *argc, char ***argv);
+int parse_command(char *buf, int *argc, char ***argv);
+
+int shell_cmd_kill(int argc, char **argv);

+ 40 - 0
user/libs/libc/include/signal.h

@@ -0,0 +1,40 @@
+#pragma once
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+
+#define SIGPWR 30
+#define SIGSYS 31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN 32
+#define SIGRTMAX MAX_SIG_NUM

+ 1 - 0
user/libs/libsystem/syscall.h

@@ -28,6 +28,7 @@
 
 #define SYS_MSTAT 21    // 获取系统的内存状态信息
 #define SYS_UNLINK_AT 22    // 删除文件夹/删除文件链接
+#define SYS_KILL 23 // kill一个进程(向这个进程发出信号)
 
 /**
  * @brief 用户态系统调用函数