Browse Source

signal的处理(kill命令)以及一些其他的改进 (#100)

* 将entry.S中冗余的ret_from_syscall代码删除,改为jmp Restore_all

* new: 增加判断pt_regs是否来自用户态的函数

* new: rust的cli和sti封装

* 将原有的判断pt_regs是否来自用户态的代码,统一改为调用user_mode函数

* ffz函数:获取u64中的第一个值为0的bit

* spinlock增加 spinlock irq spin_unlock_irq

* 临时解决显示刷新线程迟迟不运行的问题

* 更改ffi_convert的生命周期标签

* new: 测试signal用的app

* 解决由于编译器优化导致local_irq_restore无法获取到正确的rflags的值的问题

* new: exec命令增加"&"后台运行选项

* procfs->status增加显示preempt和虚拟运行时间

* 更改引用计数的FFIBind2Rust trait中的生命周期标签

* new: signal处理(kill)

* 更正在review中发现的一些细节问题
login 2 years ago
parent
commit
1a2eaa402f

+ 11 - 0
kernel/src/arch/x86_64/asm/bitops.rs

@@ -0,0 +1,11 @@
+use core::arch::x86_64::_popcnt64;
+
+/// @brief ffz - 寻找u64中的第一个0所在的位(从第0位开始寻找)
+/// 请注意,如果x中没有0,那么结果将是未定义的。请确保传入的x至少存在1个0
+/// 
+/// @param x 目标u64
+/// @return i32 bit-number(0..63) of the first (least significant) zero bit.
+#[inline]
+pub fn ffz(x: u64) -> i32 {
+    return unsafe { _popcnt64((x & ((!x) - 1)).try_into().unwrap()) };
+}

+ 3 - 9
kernel/src/arch/x86_64/asm/irqflags.rs

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

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

@@ -1,3 +1,5 @@
 pub mod irqflags;
 #[macro_use]
-pub mod current;
+pub mod current;
+pub mod ptrace;
+pub mod bitops;

+ 12 - 0
kernel/src/arch/x86_64/asm/ptrace.rs

@@ -0,0 +1,12 @@
+#![allow(dead_code)]
+use crate::include::bindings::bindings::pt_regs;
+
+/// @brief 判断给定的栈帧是否来自用户态
+/// 判断方法为:根据代码段选择子是否具有ring3的访问权限(低2bit均为1)
+pub fn user_mode(regs: *const pt_regs)->bool{
+    if (unsafe{(*regs).cs} & 0x3) != 0{
+        return true;
+    }else {
+        return false;
+    }
+}

+ 18 - 0
kernel/src/arch/x86_64/interrupt/mod.rs

@@ -0,0 +1,18 @@
+#![allow(dead_code)]
+use core::arch::asm;
+
+/// @brief 关闭中断
+#[inline]
+pub fn cli(){
+    unsafe{
+        asm!("cli");
+    }
+}
+
+/// @brief 开启中断
+#[inline]
+pub fn sti(){
+    unsafe{
+        asm!("sti");
+    }
+}

+ 2 - 1
kernel/src/arch/x86_64/mod.rs

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

+ 6 - 2
kernel/src/driver/video/video.c

@@ -66,6 +66,7 @@ int video_refresh_daemon(void *unused)
                 memcpy((void *)video_frame_buffer_info.vaddr, (void *)video_refresh_target->vaddr,
                        video_refresh_target->size);
                 spin_unlock(&daemon_refresh_lock);
+                video_daemon_pcb->virtual_runtime = 0xfffff0000000; // 临时解决由于显示刷新进程的虚拟运行时间过大/过小,导致其不运行,或者一直运行的问题。将来应使用实时调度解决它
             }
             video_refresh_expire_jiffies = cal_next_n_ms_jiffies(REFRESH_INTERVAL << 1);
         }
@@ -83,8 +84,11 @@ void video_refresh_framebuffer(void *data)
 {
     if (unlikely(video_daemon_pcb == NULL))
         return;
-
-    process_wakeup(video_daemon_pcb);
+    if (clock() >= video_refresh_expire_jiffies)
+    {
+        video_daemon_pcb->virtual_runtime = 0;
+        process_wakeup(video_daemon_pcb);
+    }
 }
 
 /**

+ 8 - 0
kernel/src/exception/entry.S

@@ -60,6 +60,14 @@ ret_from_exception:
     // === 从中断中返回 ===
 
 ENTRY(ret_from_intr)
+
+    // 进入信号处理流程
+    cli
+    // 将原本要返回的栈帧的栈指针传入do_signal的第一个参数
+    movq %rsp, %rdi
+    callq do_signal
+    
+    // 恢复寄存器
     jmp Restore_all
 
     

+ 2 - 2
kernel/src/exception/trap.c

@@ -24,8 +24,8 @@ void do_debug(struct pt_regs *regs, unsigned long error_code)
 {
     printk("[ ");
     printk_color(RED, BLACK, "ERROR / TRAP");
-    printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip,
-           proc_current_cpu_id);
+    printk(" ] do_debug(1),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d, pid:%d\n", error_code, regs->rsp, regs->rip,
+           proc_current_cpu_id, current_pcb->pid);
 
     while (1)
         hlt();

+ 1 - 1
kernel/src/filesystem/VFS/VFS.c

@@ -359,7 +359,7 @@ uint64_t sys_mkdir(struct pt_regs *regs)
     // kdebug("path = %s", path);
     mode_t mode = (mode_t)regs->r9;
 
-    if (regs->cs & USER_CS)
+    if (user_mode(regs))
         return vfs_mkdir(path, mode, true);
     else
         return vfs_mkdir(path, mode, false);

+ 11 - 6
kernel/src/filesystem/procfs/procfs.c

@@ -124,18 +124,23 @@ static long procfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_
     switch (mode)
     {
     case 1:
-        data_puts(fdata, "Name:");
+        data_puts(fdata, "Name:\t");
         data_puts(fdata, pcb_t->name);
-        data_puts(fdata, "\nstate:");
+        data_puts(fdata, "\nstate:\t");
         data_puts(fdata, ltoa(pcb_t->state));
-        data_puts(fdata, "\npid:");
+        data_puts(fdata, "\npid:\t");
         data_puts(fdata, ltoa(pcb_t->pid));
-        data_puts(fdata, "\nPpid:");
+        data_puts(fdata, "\nPpid:\t");
         data_puts(fdata, ltoa(pcb_t->parent_pcb->pid));
-        data_puts(fdata, "\ncpu_id:");
+        data_puts(fdata, "\ncpu_id:\t");
         data_puts(fdata, ltoa(pcb_t->cpu_id));
-        data_puts(fdata, "\npriority:");
+        data_puts(fdata, "\npriority:\t");
         data_puts(fdata, ltoa(pcb_t->priority));
+        data_puts(fdata, "\npreempt:\t");
+        data_puts(fdata, ltoa(pcb_t->preempt_count));
+        data_puts(fdata, "\nvrtime:\t");
+        data_puts(fdata, ltoa(pcb_t->virtual_runtime));
+
         // data_puts(fdata,"\n");
 
         uint64_t hiwater_vm, text, data;

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

@@ -1,3 +1,12 @@
+/**
+ * @file signal.h
+ * @author longjin ([email protected])
+ * @brief signal相关类型在C语言中的导出。(以rust版本为准)
+ * @version 0.1
+ *
+ * @copyright Copyright (c) 2022
+ *
+ */
 #pragma once
 #include <DragonOS/refcount.h>
 #include <common/atomic.h>
@@ -8,6 +17,8 @@
 
 // 系统最大支持的信号数量
 #define MAX_SIG_NUM 64
+// sigset所占用的u64的数量
+#define _NSIG_U64_CNT (MAX_SIG_NUM / 64)
 
 typedef void __signalfn_t(int);
 typedef __signalfn_t *__sighandler_t;
@@ -97,6 +108,11 @@ struct sigaction
     void (*sa_restorer)(void); // 暂时未实现
 };
 
+// ============ sigaction结构体中的的sa_flags的可选值 ===========
+#define SA_FLAG_IGN (1UL << 0)      // 当前sigaction表示忽略信号的动作
+#define SA_FLAG_DFL (1UL << 1)      // 当前sigaction表示系统默认的动作
+#define SA_FLAG_RESTORER (1UL << 2) // 当前sigaction具有用户指定的restorer
+
 /**
  * 由于signal_struct总是和sighand_struct一起使用,并且信号处理的过程中必定会对sighand加锁,
  * 因此signal_struct不用加锁
@@ -124,4 +140,5 @@ struct sighand_struct
 struct sigpending
 {
     sigset_t signal;
+    void *sigqueue; // 信号队列(在rust中实现)
 };

+ 417 - 60
kernel/src/ipc/signal.rs

@@ -1,17 +1,23 @@
-use core::ptr::read_volatile;
+use core::{ffi::c_void, intrinsics::size_of, ptr::read_volatile, sync::atomic::compiler_fence};
 
 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,
-        },
-        
+    arch::x86_64::{
+        asm::{bitops::ffz, current::current_pcb, ptrace::user_mode},
+        interrupt::sti,
+    },
+    include::bindings::bindings::{
+        pid_t, process_control_block, process_do_exit, process_find_pcb_by_pid, pt_regs,
+        spinlock_t, verify_area, EINVAL, ENOTSUP, EPERM, ESRCH, PF_EXITING, PF_KTHREAD,
+        PF_SIGNALED, PF_WAKEKILL, PROC_INTERRUPTIBLE, USER_CS, USER_DS, USER_MAX_LINEAR_ADDR,
     },
-    kBUG, kdebug, kwarn,
+    ipc::signal_types::sigset_add,
+    kBUG, kdebug, kerror, kwarn,
     libs::{
         ffi_convert::FFIBind2Rust,
-        spinlock::{spin_is_locked, spin_lock_irqsave, spin_unlock_irqrestore},
+        spinlock::{
+            spin_is_locked, spin_lock_irq, spin_lock_irqsave, spin_unlock_irq,
+            spin_unlock_irqrestore,
+        },
     },
     println,
     process::{
@@ -21,18 +27,26 @@ use crate::{
 };
 
 use super::signal_types::{
-    si_code_val, sigaction, sigaction__union_u, sighand_struct, siginfo, signal_struct,
-    sigpending, sigset_t, SignalNumber, MAX_SIG_NUM,
+    si_code_val, sigaction, sigaction__union_u, sigcontext, sigframe, sighand_struct, siginfo,
+    signal_struct, sigpending, sigset_clear, sigset_del, sigset_t, SignalNumber, MAX_SIG_NUM,
+    SA_FLAG_DFL, SA_FLAG_IGN, SA_FLAG_RESTORER, STACK_ALIGN, _NSIG_U64_CNT,
 };
 
-
-
 use super::signal_types::{__siginfo_union, __siginfo_union_data};
 
 /// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
 pub static DEFAULT_SIGACTION: sigaction = sigaction {
     _u: sigaction__union_u { _sa_handler: None },
-    sa_flags: 0,
+    sa_flags: SA_FLAG_DFL,
+    sa_mask: 0,
+    sa_restorer: None,
+};
+
+/// 默认的“忽略信号”的sigaction
+#[allow(dead_code)]
+pub static DEFAULT_SIGACTION_IGNORE: sigaction = sigaction {
+    _u: sigaction__union_u { _sa_handler: None },
+    sa_flags: SA_FLAG_IGN,
     sa_mask: 0,
     sa_restorer: None,
 };
@@ -50,8 +64,8 @@ pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
     );
 
     let pid: pid_t = regs.r8 as pid_t;
-    let sig: Option<SignalNumber> = SignalNumber::from_i32(regs.r9 as i32);
-    if sig.is_none() {
+    let sig: SignalNumber = SignalNumber::from(regs.r9 as i32);
+    if sig == SignalNumber::INVALID {
         // 传入的signal数值不合法
         kwarn!("Not a valid signal number");
         return (-(EINVAL as i64)) as u64;
@@ -61,7 +75,7 @@ pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
     let mut info = siginfo {
         _sinfo: __siginfo_union {
             data: __siginfo_union_data {
-                si_signo: sig.unwrap() as i32,
+                si_signo: sig as i32,
                 si_code: si_code_val::SI_USER as i32,
                 si_errno: 0,
                 reserved: 0,
@@ -71,8 +85,12 @@ pub extern "C" fn sys_kill(regs: &pt_regs) -> u64 {
             },
         },
     };
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
 
-    return signal_kill_something_info(sig.unwrap(), Some(&mut info), pid) as u64;
+    let retval = signal_kill_something_info(sig, Some(&mut info), pid) as u64;
+
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
+    return retval;
 }
 
 /// 通过kill的方式向目标进程发送信号
@@ -103,10 +121,11 @@ fn signal_kill_proc_info(sig: SignalNumber, info: Option<&mut siginfo>, pid: pid
         return retval;
     }
 
-    println!("Target pcb = {:?}", pcb.as_ref().unwrap());
-
+    // println!("Target pcb = {:?}", pcb.as_ref().unwrap());
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
     // step3: 调用signal_send_sig_info函数,发送信息
     retval = signal_send_sig_info(sig, info, pcb.unwrap());
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
     // step4: 解锁
     return retval;
 }
@@ -130,7 +149,7 @@ fn signal_send_sig_info(
     info: Option<&mut siginfo>,
     target_pcb: &mut process_control_block,
 ) -> i32 {
-    kdebug!("signal_send_sig_info");
+    // kdebug!("signal_send_sig_info");
     // 检查sig是否符合要求,如果不符合要求,则退出。
     if !verify_signal(sig) {
         return -(EINVAL as i32);
@@ -142,12 +161,13 @@ fn signal_send_sig_info(
     let mut flags: u64 = 0;
     // 如果上锁成功,则发送信号
     if !lock_process_sighand(target_pcb, &mut flags).is_none() {
+        compiler_fence(core::sync::atomic::Ordering::SeqCst);
         // 发送信号
         retval = send_signal_locked(sig, info, target_pcb, PidType::PID);
-
-        kdebug!("flags=0x{:016x}", flags);
+        compiler_fence(core::sync::atomic::Ordering::SeqCst);
+        // kdebug!("flags=0x{:016x}", flags);
         // 对sighand放锁
-        unlock_process_sighand(target_pcb, &flags);
+        unlock_process_sighand(target_pcb, flags);
     }
     return retval;
 }
@@ -160,22 +180,18 @@ fn lock_process_sighand<'a>(
     pcb: &'a mut process_control_block,
     flags: &mut u64,
 ) -> Option<&'a mut sighand_struct> {
-    kdebug!("lock_process_sighand");
+    // kdebug!("lock_process_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;
@@ -184,13 +200,10 @@ fn lock_process_sighand<'a>(
 /// @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");
+fn unlock_process_sighand(pcb: &mut process_control_block, flags: u64) {
     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");
+
+    spin_unlock_irqrestore(lock, &flags);
 }
 
 /// @brief 判断是否需要强制发送信号,然后发送信号
@@ -203,18 +216,17 @@ fn send_signal_locked(
     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
+        force_send = unsafe { info.as_ref().unwrap()._sinfo.data.si_code }
             == (si_code_val::SI_KERNEL as i32);
     }
 
-    kdebug!("force send={}", force_send);
+    // kdebug!("force send={}", force_send);
 
     return __send_signal_locked(sig, info, pcb, pt, force_send);
 }
@@ -234,18 +246,14 @@ fn __send_signal_locked(
     pt: PidType,
     _force_send: bool,
 ) -> i32 {
-    kdebug!("__send_signal_locked");
+    // 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");
+    assert!(spin_is_locked(unsafe { &(*pcb.sighand).siglock }));
 
+    let _pending: Option<&mut sigpending> = sigpending::convert_mut(&mut pcb.sig_pending);
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
     // 如果是kill或者目标pcb是内核线程,则无需获取sigqueue,直接发送信号即可
     if sig == SignalNumber::SIGKILL || (pcb.flags & (PF_KTHREAD as u64)) != 0 {
         complete_signal(sig, pcb, pt);
@@ -253,7 +261,7 @@ fn __send_signal_locked(
         // todo: 如果是其他信号,则加入到sigqueue内,然后complete_signal
         retval = -(ENOTSUP as i32);
     }
-    kdebug!("12342");
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
     return retval;
 }
 
@@ -263,14 +271,15 @@ fn __send_signal_locked(
 /// @param pcb 目标pcb
 /// @param pt siginfo结构体中,pid字段代表的含义
 fn complete_signal(sig: SignalNumber, pcb: &mut process_control_block, pt: PidType) {
+    // kdebug!("complete_signal");
+
     // todo: 将信号产生的消息通知到正在监听这个信号的进程(引入signalfd之后,在这里调用signalfd_notify)
-    kdebug!("complete_signal");
     // 将这个信号加到目标进程的sig_pending中
     sigset_add(
         sigset_t::convert_mut(&mut pcb.sig_pending.signal).unwrap(),
         sig,
     );
-
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
     // ===== 寻找需要wakeup的目标进程 =====
     // 备注:由于当前没有进程组的概念,每个进程只有1个对应的线程,因此不需要通知进程组内的每个进程。
     //      todo: 当引入进程组的概念后,需要完善这里,使得它能寻找一个目标进程来唤醒,接着执行信号处理的操作。
@@ -298,7 +307,7 @@ fn complete_signal(sig: SignalNumber, pcb: &mut process_control_block, pt: PidTy
 
     // todo:引入进程组后,在这里挑选一个进程来唤醒,让它执行相应的操作。
     // todo!();
-
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
     // todo: 到这里,信号已经被放置在共享的pending队列中,我们在这里把目标进程唤醒。
     if _target.is_some() {
         signal_wake_up(pcb, sig == SignalNumber::SIGKILL);
@@ -346,12 +355,6 @@ fn sig_is_member(set: &sigset_t, _sig: SignalNumber) -> bool {
     };
 }
 
-/// @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)]
@@ -386,6 +389,7 @@ fn has_sig_pending(pcb: &process_control_block) -> bool {
 
 #[inline]
 fn signal_wake_up(pcb: &mut process_control_block, fatal: bool) {
+    // kdebug!("signal_wake_up");
     let mut state: u64 = 0;
     if fatal {
         state = PF_WAKEKILL as u64;
@@ -394,11 +398,364 @@ fn signal_wake_up(pcb: &mut process_control_block, fatal: bool) {
 }
 
 fn signal_wake_up_state(pcb: &mut process_control_block, state: u64) {
-    assert!(spin_is_locked(&unsafe { *pcb.sighand }.siglock));
+    assert!(spin_is_locked(&unsafe { (*pcb.sighand).siglock }));
     // todo: 设置线程结构体的标志位为TIF_SIGPENDING
-
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
     // 如果目标进程已经在运行,则发起一个ipi,使得它陷入内核
     if !process_wake_up_state(pcb, state | (PROC_INTERRUPTIBLE as u64)) {
         process_kick(pcb);
     }
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
+}
+
+/// @brief 信号处理函数。该函数在进程退出内核态的时候会被调用,且调用前会关闭中断。
+#[no_mangle]
+pub extern "C" fn do_signal(regs: &mut pt_regs) {
+    // 检查sigpending是否为0
+    if current_pcb().sig_pending.signal == 0 || (!user_mode(regs)) {
+        // 若没有正在等待处理的信号,或者将要返回到的是内核态,则启用中断,然后返回
+        sti();
+        return;
+    }
+
+    // 做完上面的检查后,开中断
+    sti();
+    // return;
+    // kdebug!("do_signal");
+    let oldset = current_pcb().sig_blocked;
+    loop {
+        let (sig_number, info, ka) = get_signal_to_deliver(regs.clone());
+        // 所有的信号都处理完了
+        if sig_number == SignalNumber::INVALID {
+            return;
+        }
+        kdebug!(
+            "To handle signal [{}] for pid:{}",
+            sig_number as i32,
+            current_pcb().pid
+        );
+        let res = handle_signal(sig_number, ka.unwrap(), &info.unwrap(), &oldset, regs);
+        if res.is_err() {
+            kerror!(
+                "Error occurred when handling signal: {}, pid={}, errcode={}",
+                sig_number as i32,
+                current_pcb().pid,
+                res.unwrap_err()
+            );
+        }
+    }
+}
+
+/// @brief 获取要被发送的信号的signumber, siginfo, 以及对应的sigaction结构体
+fn get_signal_to_deliver(
+    _regs: pt_regs,
+) -> (
+    SignalNumber,
+    Option<siginfo>,
+    Option<&'static mut sigaction>,
+) {
+    let mut info: Option<siginfo>;
+    let ka: Option<&mut sigaction>;
+    let mut sig_number;
+    let sighand: &mut sighand_struct;
+
+    {
+        let _tmp = sighand_struct::convert_mut(current_pcb().sighand);
+        if let Some(i) = _tmp {
+            sighand = i;
+        } else {
+            panic!("Sighand is NULL! pid={}", current_pcb().pid);
+        }
+    }
+
+    spin_lock_irq(&mut sighand.siglock);
+    loop {
+        (sig_number, info) =
+            dequeue_signal(sigset_t::convert_mut(&mut current_pcb().sig_blocked).unwrap());
+
+        // 如果信号非法,则直接返回
+        if sig_number == SignalNumber::INVALID {
+            spin_unlock_irq(unsafe { (&mut (*current_pcb().sighand).siglock) as *mut spinlock_t });
+            return (sig_number, None, None);
+        }
+
+        // 获取指向sigaction结构体的引用
+        let hand = sighand_struct::convert_mut(current_pcb().sighand).unwrap();
+        // kdebug!("hand=0x{:018x}", hand as *const sighand_struct as usize);
+        let tmp_ka = &mut hand.action[sig_number as usize - 1];
+
+        // 如果当前动作是忽略这个信号,则不管它了。
+        if (tmp_ka.sa_flags & SA_FLAG_IGN) != 0 {
+            continue;
+        } else if (tmp_ka.sa_flags & SA_FLAG_DFL) == 0 {
+            // 当前不采用默认的信号处理函数
+            ka = Some(tmp_ka);
+            break;
+        }
+        kdebug!(
+            "Use default handler to handle signal [{}] for pid {}",
+            sig_number as i32,
+            current_pcb().pid
+        );
+        // ===== 经过上面的判断,如果能走到这一步,就意味着我们采用默认的信号处理函数来处理这个信号 =====
+        spin_unlock_irq(&mut sighand.siglock);
+        // 标记当前进程由于信号而退出
+        current_pcb().flags |= PF_SIGNALED as u64;
+
+        // 执行进程的退出动作
+        unsafe { process_do_exit(info.unwrap()._sinfo.data.si_signo as u64) };
+        /* NOT REACHED 这部分代码将不会到达 */
+    }
+    spin_unlock_irq(&mut sighand.siglock);
+    return (sig_number, info, ka);
+}
+
+/// @brief 从当前进程的sigpending中取出下一个待处理的signal,并返回给调用者。(调用者应当处理这个信号)
+/// 请注意,进入本函数前,当前进程应当持有current_pcb().sighand.siglock
+fn dequeue_signal(sig_mask: &mut sigset_t) -> (SignalNumber, Option<siginfo>) {
+    // kdebug!("dequeue signal");
+    // 获取下一个要处理的信号的编号
+    let sig = next_signal(
+        sigpending::convert_ref(&(current_pcb().sig_pending)).unwrap(),
+        sig_mask,
+    );
+
+    let info: Option<siginfo>;
+    if sig != SignalNumber::INVALID {
+        // 如果下一个要处理的信号是合法的,则收集其siginfo
+        info = Some(collect_signal(
+            sig,
+            sigpending::convert_mut(&mut current_pcb().sig_pending).unwrap(),
+        ));
+    } else {
+        info = None;
+    }
+
+    // 当一个进程具有多个线程之后,在这里需要重新计算线程的flag中的TIF_SIGPENDING位
+    recalc_sigpending();
+    return (sig, info);
+}
+
+/// @brief 获取下一个要处理的信号(sig number越小的信号,优先级越高)
+///
+/// @param pending 等待处理的信号
+/// @param sig_mask 屏蔽了的信号
+/// @return i32 下一个要处理的信号的number. 如果为0,则无效
+fn next_signal(pending: &sigpending, sig_mask: &sigset_t) -> SignalNumber {
+    let mut sig = SignalNumber::INVALID;
+
+    let s = pending.signal;
+    let m = *sig_mask;
+
+    // 获取第一个待处理的信号的号码
+    let x = s & (!m);
+    if x != 0 {
+        sig = SignalNumber::from(ffz(!x) + 1);
+        return sig;
+    }
+
+    // 暂时只支持64种信号信号
+    assert_eq!(_NSIG_U64_CNT, 1);
+
+    return sig;
+}
+
+/// @brief 当一个进程具有多个线程之后,在这里需要重新计算线程的flag中的TIF_SIGPENDING位
+fn recalc_sigpending() {
+    // todo:
+}
+
+/// @brief 收集信号的信息
+///
+/// @param sig 要收集的信号的信息
+/// @param pending 信号的排队等待标志
+/// @return siginfo 信号的信息
+fn collect_signal(sig: SignalNumber, pending: &mut sigpending) -> siginfo {
+    let (info, still_pending) = unsafe { pending.queue.as_mut() }
+        .unwrap()
+        .find_and_delete(sig);
+
+    // 如果没有仍在等待的信号,则清除pending位
+    if !still_pending {
+        sigset_del(&mut pending.signal, sig);
+    }
+
+    if info.is_some() {
+        return info.unwrap();
+    } else {
+        // 信号不在sigqueue中,这意味着当前信号是来自快速路径,因此直接把siginfo设置为0即可。
+        let mut ret = siginfo::new(sig, 0, si_code_val::SI_USER);
+        ret._sinfo.data._sifields._kill._pid = 0;
+        return ret;
+    }
+}
+
+/// @brief 真正发送signal,执行自定义的处理函数
+///
+/// @param sig 信号number
+/// @param ka 信号响应动作
+/// @param info 信号信息
+/// @param oldset
+/// @param regs 之前的系统调用将要返回的时候,要弹出的栈帧的拷贝
+///
+/// @return Result<0,i32> 若Error, 则返回错误码,否则返回Ok(0)
+fn handle_signal(
+    sig: SignalNumber,
+    ka: &mut sigaction,
+    info: &siginfo,
+    oldset: &sigset_t,
+    regs: &mut pt_regs,
+) -> Result<i32, i32> {
+    // 设置栈帧
+    let retval = setup_frame(sig, ka, info, oldset, regs);
+    if retval.is_err() {
+        return retval;
+    }
+    return Ok(0);
+}
+
+/// @brief 在用户栈上开辟一块空间,并且把内核栈的栈帧以及需要在用户态执行的代码给保存进去。
+///
+/// @param regs 进入信号处理流程前,Restore all要弹出的内核栈栈帧
+fn setup_frame(
+    sig: SignalNumber,
+    ka: &mut sigaction,
+    info: &siginfo,
+    oldset: &sigset_t,
+    regs: &mut pt_regs,
+) -> Result<i32, i32> {
+    let mut err = 0;
+    let frame: *mut sigframe = get_stack(ka, &regs, size_of::<sigframe>());
+
+    // 要求这个frame的地址位于用户空间,因此进行校验
+    let access_check_ok = unsafe { verify_area(frame as u64, size_of::<sigframe>() as u64) };
+    if !access_check_ok {
+        // 如果地址区域位于内核空间,则直接报错
+        // todo: 生成一个sigsegv
+        kerror!("In setup frame: access check failed");
+        return Err(-(EPERM as i32));
+    }
+
+    unsafe {
+        (*frame).arg0 = sig as u64;
+        (*frame).arg1 = &((*frame).info) as *const siginfo as usize;
+        (*frame).arg2 = &((*frame).context) as *const sigcontext as usize;
+        (*frame).handler = ka._u._sa_handler.unwrap() as *mut core::ffi::c_void;
+    }
+
+    // 将siginfo拷贝到用户栈
+    err |= copy_siginfo_to_user(unsafe { &mut (*frame).info }, info).unwrap_or(1);
+
+    // todo: 拷贝处理程序备用栈的地址、大小、ss_flags
+
+    err |= setup_sigcontext(unsafe { &mut (*frame).context }, oldset, &regs).unwrap_or(1);
+
+    // 为了与Linux的兼容性,64位程序必须由用户自行指定restorer
+    if ka.sa_flags & SA_FLAG_RESTORER != 0 {
+        unsafe {
+            (*frame).ret_code_ptr =
+                (&mut ka.sa_restorer.unwrap()) as *mut unsafe extern "C" fn() as *mut c_void;
+        }
+    } else {
+        kerror!(
+            "pid-{} forgot to set SA_FLAG_RESTORER for signal {}",
+            current_pcb().pid,
+            sig as i32
+        );
+        err = 1;
+    }
+    if err != 0 {
+        // todo: 在这里生成一个sigsegv,然后core dump
+        return Err(1);
+    }
+
+    regs.rdi = sig as u64;
+    regs.rsi = unsafe { &(*frame).info as *const siginfo as u64 };
+    regs.rsp = frame as u64;
+    regs.rip = unsafe { ka._u._sa_handler.unwrap() as *const unsafe extern "C" fn() as u64 };
+
+    // 如果handler位于内核空间
+    if regs.rip >= USER_MAX_LINEAR_ADDR {
+        // 如果当前是SIGSEGV,则采用默认函数处理
+        if sig == SignalNumber::SIGSEGV {
+            ka.sa_flags |= SA_FLAG_DFL;
+        }
+
+        // 将rip设置为0
+        regs.rip = 0;
+    }
+
+    // 设置cs和ds寄存器
+    regs.cs = (USER_CS | 0x3) as u64;
+    regs.ds = (USER_DS | 0x3) as u64;
+
+    return if err == 0 { Ok(0) } else { Err(1) };
+}
+
+#[inline(always)]
+fn get_stack(_ka: &sigaction, regs: &pt_regs, size: usize) -> *mut sigframe {
+    // 默认使用 用户栈的栈顶指针-128字节的红区-sigframe的大小
+    let mut rsp: usize = (regs.rsp as usize) - 128 - size;
+    // 按照要求进行对齐
+    rsp &= (-(STACK_ALIGN as i64)) as usize;
+    return rsp as *mut sigframe;
+}
+
+/// @brief 将siginfo结构体拷贝到用户栈
+fn copy_siginfo_to_user(to: *mut siginfo, from: &siginfo) -> Result<i32, i32> {
+    // 验证目标地址是否为用户空间
+    if unsafe { !verify_area(to as u64, size_of::<siginfo>() as u64) } {
+        // 如果目标地址空间不为用户空间,则直接返回错误码 -EPERM
+        return Err(-(EPERM as i32));
+    }
+
+    let retval: Result<i32, i32> = Ok(0);
+
+    // todo: 将这里按照si_code的类型来分别拷贝不同的信息。
+    // 这里参考linux-2.6.39  网址: http://opengrok.ringotek.cn/xref/linux-2.6.39/arch/ia64/kernel/signal.c#137
+
+    unsafe {
+        (*to)._sinfo.data._sifields._kill._pid = from._sinfo.data._sifields._kill._pid;
+    }
+
+    return retval;
+}
+
+/// @brief 设置目标的sigcontext
+///
+/// @param context 要被设置的目标sigcontext
+/// @param mask 要被暂存的信号mask标志位
+/// @param regs 进入信号处理流程前,Restore all要弹出的内核栈栈帧
+fn setup_sigcontext(context: &mut sigcontext, mask: &sigset_t, regs: &pt_regs) -> Result<i32, i32> {
+    let current_thread = current_pcb().thread;
+
+    context.oldmask = *mask;
+    context.regs = regs.clone();
+    context.trap_num = unsafe { (*current_thread).trap_num };
+    context.err_code = unsafe { (*current_thread).err_code };
+    context.cr2 = unsafe { (*current_thread).cr2 };
+    return Ok(0);
+}
+
+/// @brief 刷新指定进程的sighand的sigaction,将满足条件的sigaction恢复为Default
+///     除非某个信号被设置为ignore且force_default为false,否则都不会将其恢复
+///
+/// @param pcb 要被刷新的pcb
+/// @param force_default 是否强制将sigaction恢复成默认状态
+pub fn flush_signal_handlers(pcb: *mut process_control_block, force_default: bool) {
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
+
+    let action = unsafe { &mut (*(*pcb).sighand).action };
+    for ka in action.iter_mut() {
+        if force_default || (ka.sa_flags != SA_FLAG_IGN) {
+            ka.sa_flags = SA_FLAG_DFL;
+            ka._u._sa_handler = None;
+        }
+        // 清除flags中,除了DFL和IGN以外的所有标志
+        ka.sa_flags &= SA_FLAG_DFL | SA_FLAG_IGN;
+        ka.sa_restorer = None;
+        sigset_clear(&mut ka.sa_mask);
+        compiler_fence(core::sync::atomic::Ordering::SeqCst);
+    }
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
 }

+ 257 - 56
kernel/src/ipc/signal_types.rs

@@ -1,9 +1,16 @@
 #![allow(non_camel_case_types)]
 // 这是signal暴露给其他模块的公有的接口文件
 
+use core::ffi::c_void;
+use core::fmt::Debug;
+
+use alloc::vec::Vec;
+
 // todo: 将这里更换为手动编写的ffi绑定
 use crate::include::bindings::bindings::atomic_t;
+use crate::include::bindings::bindings::pt_regs;
 use crate::include::bindings::bindings::spinlock_t;
+use crate::kerror;
 use crate::libs::ffi_convert::FFIBind2Rust;
 use crate::libs::ffi_convert::__convert_mut;
 use crate::libs::ffi_convert::__convert_ref;
@@ -14,8 +21,12 @@ 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)
+/// 最大的信号数量(改动这个值的时候请同步到signal.h)
 pub const MAX_SIG_NUM: i32 = 64;
+/// sigset所占用的u64的数量(改动这个值的时候请同步到signal.h)
+pub const _NSIG_U64_CNT: i32 = MAX_SIG_NUM / 64;
+/// 信号处理的栈的栈指针的最小对齐数量
+pub const STACK_ALIGN: u64 = 16;
 
 /// 由于signal_struct总是和sighand_struct一起使用,并且信号处理的过程中必定会对sighand加锁
 /// 因此signal_struct不用加锁
@@ -26,9 +37,11 @@ pub struct signal_struct {
     pub sig_cnt: atomic_t,
 }
 
-impl Default for signal_struct{
+impl Default for signal_struct {
     fn default() -> Self {
-        Self { sig_cnt: Default::default() }
+        Self {
+            sig_cnt: Default::default(),
+        }
     }
 }
 
@@ -49,19 +62,23 @@ pub union sigaction__union_u {
     >,
 }
 
-impl core::fmt::Debug for 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")
     }
 }
 
-
 impl Default for sigaction__union_u {
     fn default() -> Self {
-        Self{_sa_handler:None}
+        Self { _sa_handler: None }
     }
 }
 
+// ============ sigaction结构体中的的sa_flags的可选值 ===========
+pub const SA_FLAG_IGN: u64 = 1u64 << 0; // 当前sigaction表示忽略信号的动作
+pub const SA_FLAG_DFL: u64 = 1u64 << 1; // 当前sigaction表示系统默认的动作
+pub const SA_FLAG_RESTORER: u64 = 1u64 << 2; // 当前sigaction具有用户指定的restorer
+
 /**
  * @brief 信号处理结构体
  */
@@ -71,17 +88,21 @@ 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()>, // 暂时未实现该函数
+    /// 信号处理函数执行结束后,将会跳转到这个函数内进行执行,然后执行sigreturn系统调用
+    pub sa_restorer: ::core::option::Option<unsafe extern "C" fn()>,
 }
 
-impl Default for sigaction{
+impl Default for sigaction {
     fn default() -> Self {
-        Self { _u: Default::default(), sa_flags: Default::default(), sa_mask: Default::default(), sa_restorer: Default::default() }
+        Self {
+            _u: Default::default(),
+            sa_flags: Default::default(),
+            sa_mask: Default::default(),
+            sa_restorer: Default::default(),
+        }
     }
 }
 
-
-
 /**
  * 信号消息的结构体,作为参数传入sigaction结构体中指向的处理函数
  */
@@ -126,6 +147,38 @@ pub struct __sifields__kill {
     pub _pid: i64, /* 发起kill的进程的pid */
 }
 
+impl siginfo {
+    pub fn new(sig: SignalNumber, _si_errno: i32, _si_code: si_code_val) -> Self {
+        siginfo {
+            _sinfo: __siginfo_union {
+                data: __siginfo_union_data {
+                    si_signo: sig as i32,
+                    si_code: _si_code as i32,
+                    si_errno: _si_errno,
+                    reserved: 0,
+                    _sifields: super::signal_types::__sifields {
+                        _kill: super::signal_types::__sifields__kill { _pid: 0 },
+                    },
+                },
+            },
+        }
+    }
+}
+
+impl Debug for siginfo {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        unsafe {
+            f.write_fmt(format_args!(
+                "si_signo:{}, si_code:{}, si_errno:{}, _pid:{}",
+                self._sinfo.data.si_signo,
+                self._sinfo.data.si_code,
+                self._sinfo.data.si_errno,
+                self._sinfo.data._sifields._kill._pid
+            ))
+        }
+    }
+}
+
 /**
  * @brief 信号处理结构体,位于pcb之中
  */
@@ -137,9 +190,13 @@ pub struct sighand_struct {
     pub action: [sigaction; MAX_SIG_NUM as usize],
 }
 
-impl Default for sighand_struct{
+impl Default for sighand_struct {
     fn default() -> Self {
-        Self { siglock: Default::default(), count: Default::default(), action: [Default::default();MAX_SIG_NUM as usize] }
+        Self {
+            siglock: Default::default(),
+            count: Default::default(),
+            action: [Default::default(); MAX_SIG_NUM as usize],
+        }
     }
 }
 
@@ -150,8 +207,12 @@ impl Default for sighand_struct{
 #[derive(Debug, Copy, Clone)]
 pub struct sigpending {
     pub signal: sigset_t,
+    /// 信号队列
+    pub queue: *mut SigQueue,
 }
 
+/// siginfo中的si_code的可选值
+/// 请注意,当这个值小于0时,表示siginfo来自用户态,否则来自内核态
 #[allow(dead_code)]
 #[repr(i32)]
 pub enum si_code_val {
@@ -192,6 +253,7 @@ impl si_code_val {
 #[derive(Debug, Clone, Copy)]
 #[repr(i32)]
 pub enum SignalNumber {
+    INVALID = 0,
     SIGHUP = 1,
     SIGINT,
     SIGQUIT,
@@ -237,18 +299,18 @@ impl PartialEq for SignalNumber {
     }
 }
 
-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);
+impl From<i32> for SignalNumber {
+    fn from(value: i32) -> Self {
+        if Self::valid_signal_number(value) {
+            let ret: SignalNumber = unsafe { core::mem::transmute(value) };
+            return ret;
+        } else {
+            kerror!("Try to convert an invalid number to SignalNumber");
+            return SignalNumber::INVALID;
         }
-
-        return None;
     }
-
+}
+impl SignalNumber {
     /// 判断一个数字是否为可用的信号
     fn valid_signal_number(x: i32) -> bool {
         if x > 0 && x < MAX_SIG_NUM {
@@ -268,14 +330,14 @@ pub const SIGRTMAX: i32 = MAX_SIG_NUM;
 ///
 /// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的
 impl FFIBind2Rust<crate::include::bindings::bindings::signal_struct> for signal_struct {
-    fn convert_mut<'a>(
+    fn convert_mut(
         src: *mut crate::include::bindings::bindings::signal_struct,
-    ) -> Option<&'a mut Self> {
+    ) -> Option<&'static mut Self> {
         return __convert_mut(src);
     }
-    fn convert_ref<'a>(
+    fn convert_ref(
         src: *const crate::include::bindings::bindings::signal_struct,
-    ) -> Option<&'a Self> {
+    ) -> Option<&'static Self> {
         return __convert_ref(src);
     }
 }
@@ -284,32 +346,31 @@ impl FFIBind2Rust<crate::include::bindings::bindings::signal_struct> for signal_
 ///
 /// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的
 impl FFIBind2Rust<crate::include::bindings::bindings::siginfo> for siginfo {
-    fn convert_mut<'a>(
+    fn convert_mut(
         src: *mut crate::include::bindings::bindings::siginfo,
-    ) -> Option<&'a mut Self> {
+    ) -> Option<&'static mut Self> {
         return __convert_mut(src);
     }
-    fn convert_ref<'a>(
+    fn convert_ref(
         src: *const crate::include::bindings::bindings::siginfo,
-    ) -> Option<&'a Self> {
-        return __convert_ref(src)
+    ) -> Option<&'static 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>(
+    fn convert_mut(
         src: *mut crate::include::bindings::bindings::sigset_t,
-    ) -> Option<&'a mut Self> {
+    ) -> Option<&'static mut Self> {
         return __convert_mut(src);
     }
-    fn convert_ref<'a>(
+    fn convert_ref(
         src: *const crate::include::bindings::bindings::sigset_t,
-    ) -> Option<&'a Self> {
-        return __convert_ref(src)
+    ) -> Option<&'static Self> {
+        return __convert_ref(src);
     }
 }
 
@@ -317,44 +378,184 @@ impl FFIBind2Rust<crate::include::bindings::bindings::sigset_t> for sigset_t {
 ///
 /// 这么做的主要原因在于,由于PCB是通过bindgen生成的FFI,因此pcb中的结构体类型都是bindgen自动生成的
 impl FFIBind2Rust<crate::include::bindings::bindings::sigpending> for sigpending {
-    fn convert_mut<'a>(
+    fn convert_mut(
         src: *mut crate::include::bindings::bindings::sigpending,
-    ) -> Option<&'a mut Self> {
+    ) -> Option<&'static mut Self> {
         return __convert_mut(src);
     }
-    fn convert_ref<'a>(
+    fn convert_ref(
         src: *const crate::include::bindings::bindings::sigpending,
-    ) -> Option<&'a Self> {
-        return __convert_ref(src)
+    ) -> Option<&'static 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>(
+impl FFIBind2Rust<crate::include::bindings::bindings::sighand_struct> for sighand_struct {
+    fn convert_mut(
         src: *mut crate::include::bindings::bindings::sighand_struct,
-    ) -> Option<&'a mut Self> {
+    ) -> Option<&'static mut Self> {
         return __convert_mut(src);
     }
-    fn convert_ref<'a>(
+    fn convert_ref(
         src: *const crate::include::bindings::bindings::sighand_struct,
-    ) -> Option<&'a Self> {
-        return __convert_ref(src)
+    ) -> Option<&'static Self> {
+        return __convert_ref(src);
     }
 }
 
 /// @brief 将给定的来自bindgen的sigaction解析为Rust的signal.rs中定义的sigaction的引用
-impl FFIBind2Rust<crate::include::bindings::bindings::sigaction> for sigaction{
-    fn convert_mut<'a>(
+impl FFIBind2Rust<crate::include::bindings::bindings::sigaction> for sigaction {
+    fn convert_mut(
         src: *mut crate::include::bindings::bindings::sigaction,
-    ) -> Option<&'a mut Self> {
+    ) -> Option<&'static mut Self> {
         return __convert_mut(src);
     }
-    fn convert_ref<'a>(
+    fn convert_ref(
         src: *const crate::include::bindings::bindings::sigaction,
-    ) -> Option<&'a Self> {
-        return __convert_ref(src)
+    ) -> Option<&'static Self> {
+        return __convert_ref(src);
+    }
+}
+
+/// @brief 进程接收到的信号的队列
+pub struct SigQueue {
+    pub q: Vec<siginfo>,
+}
+
+#[allow(dead_code)]
+impl SigQueue {
+    /// @brief 初始化一个新的信号队列
+    pub fn new(capacity: usize) -> Self {
+        SigQueue {
+            q: Vec::with_capacity(capacity),
+        }
     }
-}
+
+    /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并返回它的引用
+    ///
+    /// @return (第一个满足要求的siginfo的引用; 是否有多个满足条件的siginfo)
+    pub fn find(&self, sig: SignalNumber) -> (Option<&siginfo>, bool) {
+        // 是否存在多个满足条件的siginfo
+        let mut still_pending = false;
+        let mut info: Option<&siginfo> = None;
+
+        for x in self.q.iter() {
+            if unsafe { x._sinfo.data.si_signo } == sig as i32 {
+                if info.is_some() {
+                    still_pending = true;
+                    break;
+                } else {
+                    info = Some(x);
+                }
+            }
+        }
+        return (info, still_pending);
+    }
+
+    /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并将其从队列中删除,然后返回这个siginfo
+    ///
+    /// @return (第一个满足要求的siginfo; 从队列中删除前是否有多个满足条件的siginfo)
+    pub fn find_and_delete(&mut self, sig: SignalNumber) -> (Option<siginfo>, bool) {
+        // 是否存在多个满足条件的siginfo
+        let mut still_pending = false;
+        let mut first = true; // 标记变量,记录当前是否已经筛选出了一个元素
+
+        let filter = |x: &mut siginfo| {
+            if unsafe { x._sinfo.data.si_signo } == sig as i32 {
+                if !first {
+                    // 如果之前已经筛选出了一个元素,则不把当前元素删除
+                    still_pending = true;
+                    return false;
+                } else {
+                    // 当前是第一个被筛选出来的元素
+                    first = false;
+                    return true;
+                }
+            } else {
+                return false;
+            }
+        };
+        // 从sigqueue中过滤出结果
+        let mut filter_result: Vec<siginfo> = self.q.drain_filter(filter).collect();
+        // 筛选出的结果不能大于1个
+        assert!(filter_result.len() <= 1);
+
+        return (filter_result.pop(), still_pending);
+    }
+}
+
+impl Default for SigQueue {
+    fn default() -> Self {
+        Self {
+            q: Default::default(),
+        }
+    }
+}
+
+/// @brief 清除sigset中,某个信号对应的标志位
+#[inline]
+pub fn sigset_del(set: &mut sigset_t, sig: SignalNumber) {
+    let sig = sig as i32 - 1;
+    if _NSIG_U64_CNT == 1 {
+        *set &= !(1 << sig);
+    } else {
+        // 暂时不支持超过64个信号
+        panic!("Unsupported signal number: {:?}", sig);
+    }
+}
+
+/// @brief 将指定的信号在sigset中的对应bit进行置位
+#[inline]
+pub fn sigset_add(set: &mut sigset_t, _sig: SignalNumber) {
+    *set |= 1 << ((_sig as u32) - 1);
+}
+
+/// @brief 将sigset清零
+#[inline]
+pub fn sigset_clear(set: &mut sigset_t) {
+    *set = 0;
+}
+
+#[repr(C)]
+#[derive(Debug, Clone, Copy)]
+pub struct sigframe {
+    /// 指向restorer的地址的指针。(该变量必须放在sigframe的第一位,因为这样才能在handler返回的时候,跳转到对应的代码,执行sigreturn)
+    pub ret_code_ptr: *mut core::ffi::c_void,
+    /// signum
+    pub arg0: u64,
+    /// siginfo pointer
+    pub arg1: usize,
+    /// sigcontext pointer
+    pub arg2: usize,
+
+    pub handler: *mut c_void,
+    pub info: siginfo,
+    pub context: sigcontext,
+}
+
+#[derive(Debug, Clone, Copy)]
+pub struct sigcontext {
+    /// sigcontext的标志位
+    pub sc_flags: u64,
+    pub sc_stack: signal_stack, // 信号处理程序备用栈信息
+
+    pub regs: pt_regs, // 暂存的系统调用/中断返回时,原本要弹出的内核栈帧
+    pub trap_num: u64, // 用来保存线程结构体中的trap_num字段
+    pub oldmask: u64,  // 暂存的执行信号处理函数之前的sigmask
+    pub cr2: u64,      // 用来保存线程结构体中的cr2字段
+    pub err_code: u64, // 用来保存线程结构体中的err_code字段
+    // todo: 支持x87浮点处理器后,在这里增加浮点处理器的状态结构体指针
+    pub reserved_for_x87_state: u64,
+    pub reserved: [u64; 8],
+}
+
+/// @brief 信号处理备用栈的信息
+#[derive(Debug, Clone, Copy)]
+pub struct signal_stack {
+    pub sp: *mut c_void,
+    pub flags: u32,
+    pub size: u32,
+}

+ 1 - 0
kernel/src/lib.rs

@@ -3,6 +3,7 @@
 #![feature(core_intrinsics)] // <2>
 #![feature(alloc_error_handler)]
 #![feature(panic_info_message)]
+#![feature(drain_filter)]// 允许Vec的drain_filter特性
 
 #[allow(non_upper_case_globals)]
 #[allow(non_camel_case_types)]

+ 2 - 2
kernel/src/libs/ffi_convert.rs

@@ -1,9 +1,9 @@
 /// @brief 由bindgen生成的结构体转换成rust原生定义的结构体的特性
 pub trait FFIBind2Rust<T> {
     /// 转换为不可变引用
-    fn convert_ref<'a>(src: *const T) -> Option<&'a Self>;
+    fn convert_ref(src: *const T) -> Option<&'static Self>;
     /// 转换为可变引用
-    fn convert_mut<'a>(src: *mut T) -> Option<&'a mut Self>;
+    fn convert_mut(src: *mut T) -> Option<&'static mut Self>;
 }
 
 

+ 4 - 4
kernel/src/libs/refcount.rs

@@ -15,14 +15,14 @@ impl Default for RefCount{
 
 /// @brief 将给定的来自bindgen的refcount_t解析为Rust的RefCount的引用
 impl FFIBind2Rust<crate::include::bindings::bindings::refcount_struct> for RefCount{
-    fn convert_mut<'a>(
+    fn convert_mut(
         src: *mut crate::include::bindings::bindings::refcount_struct,
-    ) -> Option<&'a mut Self> {
+    ) -> Option<&'static mut Self> {
         return __convert_mut(src);
     }
-    fn convert_ref<'a>(
+    fn convert_ref(
         src: *const crate::include::bindings::bindings::refcount_struct,
-    ) -> Option<&'a Self> {
+    ) -> Option<&'static Self> {
         return __convert_ref(src)
     }
 }

+ 16 - 1
kernel/src/libs/spinlock.rs

@@ -2,9 +2,11 @@
 use core::ptr::read_volatile;
 
 use crate::arch::x86_64::asm::irqflags::{local_irq_restore, local_irq_save};
+use crate::arch::x86_64::interrupt::{cli, sti};
 use crate::include::bindings::bindings::{spin_lock, spin_unlock, spinlock_t};
 
 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
+#[inline]
 pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) {
     local_irq_save(flags);
     unsafe {
@@ -13,7 +15,7 @@ pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) {
 }
 
 /// @brief 恢复rflags以及中断状态并解锁自旋锁
-#[no_mangle]
+#[inline]
 pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) {
     unsafe {
         spin_unlock(lock);
@@ -23,6 +25,7 @@ pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) {
 }
 
 /// 判断一个自旋锁是否已经被加锁
+#[inline]
 pub fn spin_is_locked(lock: &spinlock_t) -> bool {
     let val = unsafe { read_volatile(&lock.lock as *const i8) };
 
@@ -33,4 +36,16 @@ impl Default for spinlock_t {
     fn default() -> Self {
         Self { lock: 1 }
     }
+}
+
+/// @brief 关闭中断并加锁
+pub fn spin_lock_irq(lock: *mut spinlock_t){
+    cli();
+    unsafe{spin_lock(lock);}
+}
+
+/// @brief 解锁并开中断
+pub fn spin_unlock_irq(lock: *mut spinlock_t){
+    unsafe{spin_unlock(lock);}
+    sti();
 }

+ 35 - 8
kernel/src/process/fork.rs

@@ -1,4 +1,4 @@
-use core::ptr::null_mut;
+use core::{ffi::c_void, ptr::null_mut, sync::atomic::compiler_fence};
 
 use alloc::boxed::Box;
 
@@ -8,10 +8,9 @@ use crate::{
         process_control_block, CLONE_CLEAR_SIGHAND, CLONE_SIGHAND, CLONE_THREAD, ENOMEM,
     },
     ipc::{
-        signal::DEFAULT_SIGACTION,
-        signal_types::{sigaction, sighand_struct, signal_struct},
+        signal::{flush_signal_handlers, DEFAULT_SIGACTION},
+        signal_types::{sigaction, sighand_struct, signal_struct, SigQueue},
     },
-    kdebug,
     libs::{
         atomic::atomic_set,
         ffi_convert::FFIBind2Rust,
@@ -22,29 +21,38 @@ use crate::{
 
 #[no_mangle]
 pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
-    kdebug!("process_copy_sighand");
+    // 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);
     }
+
     // 在这里使用Box::leak将动态申请的内存的生命周期转换为static的
     let mut sig: &mut sighand_struct = Box::leak(Box::new(sighand_struct::default()));
     if (sig as *mut sighand_struct) == null_mut() {
         return -(ENOMEM as i32);
     }
+
     // 将新的sighand赋值给pcb
     unsafe {
         (*pcb).sighand = sig as *mut sighand_struct as usize
             as *mut crate::include::bindings::bindings::sighand_struct;
     }
 
+    // kdebug!("DEFAULT_SIGACTION.sa_flags={}", DEFAULT_SIGACTION.sa_flags);
+
     // 拷贝sigaction
     let mut flags: u64 = 0;
+
     spin_lock_irqsave(unsafe { &mut (*current_pcb().sighand).siglock }, &mut flags);
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
+
     for (index, x) in unsafe { (*current_pcb().sighand).action }
         .iter()
         .enumerate()
     {
+        compiler_fence(core::sync::atomic::Ordering::SeqCst);
         if !(x as *const crate::include::bindings::bindings::sigaction).is_null() {
             sig.action[index] =
                 *sigaction::convert_ref(x as *const crate::include::bindings::bindings::sigaction)
@@ -53,20 +61,26 @@ pub extern "C" fn process_copy_sighand(clone_flags: u64, pcb: *mut process_contr
             sig.action[index] = DEFAULT_SIGACTION;
         }
     }
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
 
     spin_unlock_irqrestore(unsafe { &mut (*current_pcb().sighand).siglock }, &flags);
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
 
-    // 将所有屏蔽的信号的处理函数设置为default
+    // 将信号的处理函数设置为default(除了那些被手动屏蔽的)
     if (clone_flags & (CLONE_CLEAR_SIGHAND as u64)) != 0 {
-        todo!();
+        compiler_fence(core::sync::atomic::Ordering::SeqCst);
+
+        flush_signal_handlers(pcb, false);
+        compiler_fence(core::sync::atomic::Ordering::SeqCst);
     }
+    compiler_fence(core::sync::atomic::Ordering::SeqCst);
 
     return 0;
 }
 
 #[no_mangle]
 pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_control_block) -> i32 {
-    kdebug!("process_copy_signal");
+    // kdebug!("process_copy_signal");
     // 如果克隆的是线程,则不拷贝信号(同一进程的各个线程之间共享信号)
     if (clone_flags & (CLONE_THREAD as u64)) != 0 {
         return 0;
@@ -81,6 +95,13 @@ pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_contro
         (*pcb).signal = sig as *mut signal_struct as usize
             as *mut crate::include::bindings::bindings::signal_struct;
     }
+
+    // 创建新的sig_pending->sigqueue
+    unsafe {
+        (*pcb).sig_pending.signal = 0;
+        (*pcb).sig_pending.sigqueue =
+            Box::leak(Box::new(SigQueue::default())) as *mut SigQueue as *mut c_void;
+    }
     return 0;
 }
 
@@ -88,9 +109,15 @@ pub extern "C" fn process_copy_signal(clone_flags: u64, pcb: *mut process_contro
 pub extern "C" fn process_exit_signal(pcb: *mut process_control_block) {
     // 回收进程的信号结构体
     unsafe {
+        // 回收sighand
         let sighand = Box::from_raw((*pcb).sighand as *mut sighand_struct);
+
         drop(sighand);
         (*pcb).sighand = 0 as *mut crate::include::bindings::bindings::sighand_struct;
+
+        // 回收sigqueue
+        let queue = Box::from_raw((*pcb).sig_pending.sigqueue as *mut SigQueue);
+        drop(queue);
     }
 }
 

+ 29 - 3
kernel/src/process/initial_proc.rs

@@ -1,13 +1,17 @@
+use core::ffi::c_void;
+
+use alloc::boxed::Box;
+
 use crate::{
-    include::bindings::bindings::{atomic_t, spinlock_t},
-    ipc::signal::DEFAULT_SIGACTION,
+    include::bindings::bindings::{atomic_t, process_control_block, spinlock_t},
+    ipc::{signal::DEFAULT_SIGACTION, signal_types::SigQueue},
 };
 
 use crate::ipc::signal_types::{sighand_struct, signal_struct, MAX_SIG_NUM};
 
 /// @brief 初始进程的signal结构体
 #[no_mangle]
-pub static INITIAL_SIGNALS: signal_struct = signal_struct {
+pub static mut INITIAL_SIGNALS: signal_struct = signal_struct {
     sig_cnt: atomic_t { value: 0 },
 };
 
@@ -18,3 +22,25 @@ pub static mut INITIAL_SIGHAND: sighand_struct = sighand_struct {
     siglock: spinlock_t { lock: 1 },
     action: [DEFAULT_SIGACTION; MAX_SIG_NUM as usize],
 };
+
+/// @brief 初始化pid=0的进程的信号相关的信息
+#[no_mangle]
+pub extern "C" fn initial_proc_init_signal(pcb: *mut process_control_block) {
+    
+    // 所设置的pcb的pid一定为0
+    assert_eq!(unsafe { (*pcb).pid }, 0);
+    
+    // 设置init进程的sighand和signal
+    unsafe {
+        (*pcb).sighand = &mut INITIAL_SIGHAND as *mut sighand_struct as usize
+            as *mut crate::include::bindings::bindings::sighand_struct;
+        (*pcb).signal = &mut INITIAL_SIGNALS as *mut signal_struct as usize
+            as *mut crate::include::bindings::bindings::signal_struct;
+    }
+    // 创建新的sig_pending->sigqueue
+    unsafe {
+        (*pcb).sig_pending.signal = 0;
+        (*pcb).sig_pending.sigqueue =
+            Box::leak(Box::new(SigQueue::default())) as *mut SigQueue as *mut c_void;
+    }
+}

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

@@ -67,6 +67,7 @@ struct thread_struct
 #define PF_NOFREEZE (1UL << 4) // 当前进程不能被冻结
 #define PF_EXITING (1UL << 5)  // 进程正在退出
 #define PF_WAKEKILL (1UL << 6) // 进程由于接收到终止信号唤醒
+#define PF_SIGNALED (1UL << 7) // 进程由于接收到信号而退出
 /**
  * @brief 进程控制块
  *

+ 5 - 2
kernel/src/process/process.c

@@ -49,6 +49,7 @@ extern struct sighand_struct INITIAL_SIGHAND;
 
 extern void process_exit_sighand(struct process_control_block *pcb);
 extern void process_exit_signal(struct process_control_block *pcb);
+extern void initial_proc_init_signal(struct process_control_block *pcb);
 
 // 设置初始进程的PCB
 #define INITIAL_PROC(proc)                                                                                             \
@@ -439,7 +440,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
         regs->rsi = (uint64_t)dst_argv;
     }
     // kdebug("execve ok");
-
+    // 设置进程的段选择子为用户态可访问
     regs->cs = USER_CS | 3;
     regs->ds = USER_DS | 3;
     regs->ss = USER_DS | 0x3;
@@ -464,7 +465,7 @@ exec_failed:;
 #pragma GCC optimize("O0")
 ul initial_kernel_thread(ul arg)
 {
-    kinfo("initial proc running...\targ:%#018lx", arg);
+    kinfo("initial proc running...\targ:%#018lx, vruntime=%d", arg, current_pcb->virtual_runtime);
 
     scm_enable_double_buffer();
 
@@ -624,6 +625,8 @@ void process_init()
     list_init(&initial_proc_union.pcb.list);
     wait_queue_init(&initial_proc_union.pcb.wait_child_proc_exit, NULL);
 
+    // 初始化init进程的signal相关的信息
+    initial_proc_init_signal(current_pcb);
     // 临时设置IDLE进程的的虚拟运行时间为0,防止下面的这些内核线程的虚拟运行时间出错
     current_pcb->virtual_runtime = 0;
     barrier();

+ 35 - 24
kernel/src/process/ptrace.h

@@ -8,30 +8,41 @@
 
 struct pt_regs
 {
-	unsigned long r15;
-	unsigned long r14;
-	unsigned long r13;
-	unsigned long r12;
-	unsigned long r11;
-	unsigned long r10;
-	unsigned long r9;
-	unsigned long r8;
-	unsigned long rbx;
-	unsigned long rcx;
-	unsigned long rdx;
-	unsigned long rsi;
-	unsigned long rdi;
-	unsigned long rbp;
-	unsigned long ds;
-	unsigned long es;
-	unsigned long rax;
-	unsigned long func;
-	unsigned long errcode;
-	unsigned long rip;
-	unsigned long cs;
-	unsigned long rflags;
-	unsigned long rsp;
-	unsigned long ss;
+    unsigned long r15;
+    unsigned long r14;
+    unsigned long r13;
+    unsigned long r12;
+    unsigned long r11;
+    unsigned long r10;
+    unsigned long r9;
+    unsigned long r8;
+    unsigned long rbx;
+    unsigned long rcx;
+    unsigned long rdx;
+    unsigned long rsi;
+    unsigned long rdi;
+    unsigned long rbp;
+    unsigned long ds;
+    unsigned long es;
+    unsigned long rax;
+    unsigned long func;
+    unsigned long errcode;
+    unsigned long rip;
+    unsigned long cs;
+    unsigned long rflags;
+    unsigned long rsp;
+    unsigned long ss;
 };
 
+/**
+ * @brief 判断pt_regs是否来自用户态
+ * 
+ * @param regs 
+ * @return __always_inline 
+ */
+static inline int user_mode(struct pt_regs *regs)
+{
+    return !!(regs->cs & 3);
+}
+
 #endif

+ 1 - 1
kernel/src/syscall/syscall.c

@@ -372,7 +372,7 @@ uint64_t sys_chdir(struct pt_regs *regs)
 
     // 计算输入的路径长度
     int dest_path_len;
-    if (regs->cs & USER_CS)
+    if (user_mode(regs))
     {
         dest_path_len = strnlen_user(dest_path, PAGE_4K_SIZE);
     }

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

@@ -17,7 +17,7 @@ extern void ret_from_system_call(void); // 导出从系统调用返回的函数
 extern system_call_t system_call_table[MAX_SYSTEM_CALL_NUM];
 
 // 判断系统调用是否来自用户态
-#define SYSCALL_FROM_USER(regs) ((regs)->cs & USER_CS)
+#define SYSCALL_FROM_USER(regs) (user_mode(regs))
 // 判断系统调用是否来自内核态
 #define SYSCALL_FROM_KERNEL(regs) (!SYSCALL_FROM_USER(regs))
 

+ 1 - 1
user/apps/Makefile

@@ -1,5 +1,5 @@
 
-user_apps_sub_dirs=shell about
+user_apps_sub_dirs=shell about test_signal
 
 ECHO:
 	@echo "$@"

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

@@ -467,7 +467,7 @@ int shell_cmd_exec(int argc, char **argv)
 
     if (pid == 0)
     {
-        // printf("child proc\n");
+
         // 子进程
         int path_len = 0;
         char *file_path = get_target_filepath(argv[1], &path_len);
@@ -480,10 +480,13 @@ int shell_cmd_exec(int argc, char **argv)
     }
     else
     {
-        // printf("parent process wait for pid:[ %d ]\n", pid);
-
-        waitpid(pid, &retval, 0);
-        // printf("parent process wait pid [ %d ], exit code=%d\n", pid, retval);
+        // 如果不指定后台运行,则等待退出
+        if (strcmp(argv[argc - 1], "&") != 0)
+            waitpid(pid, &retval, 0);
+        else{
+            // 输出子进程的pid
+            printf("[1] %d\n", pid);
+        }
         free(argv);
     }
 }
@@ -513,8 +516,6 @@ int shell_cmd_kill(int argc, char **argv)
         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);

+ 7 - 0
user/apps/test_signal/Makefile

@@ -0,0 +1,7 @@
+all: main.o
+
+	ld -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_signal  $(shell find . -name "*.o") $(shell find $(sys_libs_dir) -name "*.o") -T link.lds
+
+	objcopy -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_signal $(output_dir)/test_signal.elf
+main.o: main.c
+	$(CC) $(CFLAGS) -c main.c  -o main.o

+ 50 - 0
user/apps/test_signal/link.lds

@@ -0,0 +1,50 @@
+
+OUTPUT_FORMAT("elf64-x86-64","elf64-x86-64","elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+
+SECTIONS
+{
+
+	. = 0x800000;
+	
+	
+	.text :
+	{
+		_text = .;
+		
+		*(.text)
+		
+		_etext = .;
+	}
+	. = ALIGN(8);
+	
+	.data :
+	{
+		_data = .;
+		*(.data)
+		
+		_edata = .;
+	}
+
+
+	rodata_start_pa = .;
+	.rodata :
+	{
+		_rodata = .;	
+		*(.rodata)
+		_erodata = .;
+	}
+
+	
+	.bss :
+	{
+		_bss = .;
+		*(.bss)
+		_ebss = .;
+	}
+
+	_end = .;
+
+
+}

+ 38 - 0
user/apps/test_signal/main.c

@@ -0,0 +1,38 @@
+/**
+ * @file main.c 
+ * @author longjin ([email protected])
+ * @brief 测试signal用的程序
+ * @version 0.1
+ * @date 2022-12-06
+ * 
+ * @copyright Copyright (c) 2022
+ * 
+ */
+
+/**
+ * 测试signal的kill命令的方法:
+ * 1.在DragonOS的控制台输入 exec bin/test_signal.elf &
+ *      请注意,一定要输入末尾的 '&',否则进程不会后台运行
+ * 2.然后kill对应的进程的pid (上一条命令执行后,将会输出这样一行:"[1] 生成的pid")
+ * 
+*/
+
+#include <libc/math.h>
+#include <libc/stdio.h>
+#include <libc/stdlib.h>
+#include <libc/time.h>
+#include <libc/unistd.h>
+
+int main()
+{
+    printf("Test signal running...\n");
+    clock_t last = clock();
+    while (1)
+    {
+        if ((clock()-last)/CLOCKS_PER_SEC >= 1){
+            // printf("Test signal running\n");
+            last = clock();
+        }
+    }
+    return 0;
+}