Browse Source

实现gettimeofday()系统调用和clocksource+timekeeping子模块 (#278)

- 实现gettimeofday()系统调用
- 实现clocksource+timekeeping子模块部分功能
- 实现了timespec转换成日期时间
houmkh 1 year ago
parent
commit
36fd013004

+ 1 - 1
kernel/src/Makefile

@@ -17,7 +17,7 @@ export ASFLAGS := --64
 LD_LIST := head.o
 
 
-kernel_subdirs := common driver process debug arch exception mm smp sched syscall ktest libs ipc io
+kernel_subdirs := common driver process debug arch exception mm smp sched syscall ktest libs ipc io time
 	
 
 

+ 8 - 8
kernel/src/arch/x86_64/asm/irqflags.rs

@@ -1,18 +1,18 @@
-use core::{arch::asm, ptr::read_volatile};
+use core::arch::asm;
 
 #[inline]
-pub fn local_irq_save(flags: &mut u64) {
+pub fn local_irq_save() -> usize {
+    let x: usize;
     unsafe {
-        asm!("pushfq", "pop rax", "mov rax, {0}", "cli", out(reg)(*flags),);
+        asm!("pushfq ; pop {} ; cli", out(reg) x, options(nostack));
     }
+    x
 }
 
 #[inline]
-pub fn local_irq_restore(flags: &u64) {
-    let x = unsafe { read_volatile(flags) };
-
+// 恢复先前保存的rflags的值x
+pub fn local_irq_restore(x: usize) {
     unsafe {
-        asm!("push r15",
-            "popfq", in("r15")(x));
+        asm!("push {} ; popfq", in(reg) x, options(nostack));
     }
 }

+ 4 - 6
kernel/src/arch/x86_64/fpu.rs

@@ -79,8 +79,7 @@ impl FpState {
 /// @brief 从用户态进入内核时,保存浮点寄存器,并关闭浮点功能
 pub fn fp_state_save(pcb: &mut process_control_block) {
     // 该过程中不允许中断
-    let mut rflags: u64 = 0;
-    local_irq_save(&mut rflags);
+    let rflags = local_irq_save();
 
     let fp: &mut FpState = if pcb.fp_state == null_mut() {
         let f = Box::leak(Box::new(FpState::default()));
@@ -112,14 +111,13 @@ pub fn fp_state_save(pcb: &mut process_control_block) {
                                 "mov cr4, rax" */
         )
     }
-    local_irq_restore(&rflags);
+    local_irq_restore(rflags);
 }
 
 /// @brief 从内核态返回用户态时,恢复浮点寄存器,并开启浮点功能
 pub fn fp_state_restore(pcb: &mut process_control_block) {
     // 该过程中不允许中断
-    let mut rflags: u64 = 0;
-    local_irq_save(&mut rflags);
+    let rflags = local_irq_save();
 
     if pcb.fp_state == null_mut() {
         panic!("fp_state_restore: fp_state is null. pid={}", pcb.pid);
@@ -143,5 +141,5 @@ pub fn fp_state_restore(pcb: &mut process_control_block) {
     fp.restore();
     fp.clear();
 
-    local_irq_restore(&rflags);
+    local_irq_restore(rflags);
 }

+ 2 - 3
kernel/src/arch/x86_64/interrupt/mod.rs

@@ -48,8 +48,7 @@ impl InterruptArch for X86_64InterruptArch {
 
     unsafe fn save_and_disable_irq() -> IrqFlagsGuard {
         compiler_fence(Ordering::SeqCst);
-        let mut rflags: u64 = 0;
-        local_irq_save(&mut rflags);
+        let rflags = local_irq_save() as u64;
         let flags = IrqFlags::new(rflags);
         let guard = IrqFlagsGuard::new(flags);
         compiler_fence(Ordering::SeqCst);
@@ -58,7 +57,7 @@ impl InterruptArch for X86_64InterruptArch {
 
     unsafe fn restore_irq(flags: IrqFlags) {
         compiler_fence(Ordering::SeqCst);
-        local_irq_restore(&flags.flags());
+        local_irq_restore(flags.flags() as usize);
         compiler_fence(Ordering::SeqCst);
     }
 }

+ 8 - 1
kernel/src/common/cpu.h

@@ -66,4 +66,11 @@ extern struct cpu_core_info_t cpu_core_info[MAX_CPU_NUM];
  *
  * @return uint32_t 当前cpu核心晶振频率
  */
-uint32_t cpu_get_core_crysral_freq();
+uint32_t cpu_get_core_crysral_freq();
+
+/**
+ * @brief 获取处理器的tsc频率(单位:hz)
+ *
+ * @return uint64_t
+ */
+uint64_t cpu_get_tsc_freq();

+ 4 - 3
kernel/src/driver/timers/HPET/HPET.c

@@ -207,12 +207,13 @@ void HPET_enable()
     // kdebug("[HPET0] conf register after modify=%#018lx", ((*(uint64_t *)(HPET_REG_BASE + TIM0_CONF))));
     // kdebug("[HPET1] conf register =%#018lx", ((*(uint64_t *)(HPET_REG_BASE + TIM1_CONF))));
 
+    // 注册中断
+    irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0");
+    io_mfence();
+    __write8b(HPET_REG_BASE + GEN_CONF, 3); // 置位旧设备中断路由兼容标志位、定时器组使能标志位
     kinfo("HPET0 enabled.");
 
-    __write8b(HPET_REG_BASE + GEN_CONF, 3); // 置位旧设备中断路由兼容标志位、定时器组使能标志位
     io_mfence();
-    // 注册中断
-    irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0");
 }
 
 int HPET_init()

+ 4 - 3
kernel/src/driver/timers/rtc/rtc.rs

@@ -1,5 +1,6 @@
 use crate::{
-    arch::interrupt::{cli, sti},
+    arch::CurrentIrqArch,
+    exception::InterruptArch,
     include::bindings::bindings::{io_in8, io_out8},
     syscall::SystemError,
 };
@@ -33,7 +34,7 @@ impl RtcTime {
     ///@return int 成功则为0
     pub fn get(&mut self) -> Result<i32, SystemError> {
         // 为防止中断请求打断该过程,需要先关中断
-        cli();
+        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
         //0x0B
         let status_register_b: u8 = read_cmos(0x0B); // 读取状态寄存器B
         let is_24h: bool = if (status_register_b & 0x02) != 0 {
@@ -81,7 +82,7 @@ impl RtcTime {
             self.hour = ((self.hour & 0x7f) + 12) % 24;
         } // 将十二小时制转为24小时
 
-        sti();
+        drop(irq_guard);
 
         return Ok(0);
     }

+ 2 - 3
kernel/src/exception/softirq.rs

@@ -225,15 +225,14 @@ impl Softirq {
     }
 
     pub fn raise_softirq(&self, softirq_num: SoftirqNumber) {
-        let mut flags = 0;
-        local_irq_save(&mut flags);
+        let flags = local_irq_save();
         let processor_id = smp_get_processor_id() as usize;
 
         cpu_pending(processor_id).insert(VecStatus::from(softirq_num));
 
         compiler_fence(Ordering::SeqCst);
 
-        local_irq_restore(&flags);
+        local_irq_restore(flags);
         // kdebug!("raise_softirq exited");
     }
     pub unsafe fn clear_softirq_pending(&self, softirq_num: SoftirqNumber) {

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

@@ -46,4 +46,5 @@
 #include <process/process.h>
 #include <sched/sched.h>
 #include <smp/smp.h>
+#include <time/clocksource.h>
 #include <time/sleep.h>

+ 9 - 0
kernel/src/libs/cpu.c

@@ -120,3 +120,12 @@ uint32_t cpu_get_core_crysral_freq()
 
     return c;
 }
+/**
+ * @brief 获取处理器的tsc频率(单位:hz)
+ *
+ * @return uint64_t
+ */
+uint64_t cpu_get_tsc_freq()
+{
+    return Cpu_tsc_freq;
+}

+ 6 - 6
kernel/src/libs/spinlock.rs

@@ -14,7 +14,7 @@ use crate::syscall::SystemError;
 /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
 #[inline]
 pub fn spin_lock_irqsave(lock: *mut spinlock_t, flags: &mut u64) {
-    local_irq_save(flags);
+    *flags = local_irq_save() as u64;
     unsafe {
         spin_lock(lock);
     }
@@ -27,7 +27,7 @@ pub fn spin_unlock_irqrestore(lock: *mut spinlock_t, flags: &u64) {
         spin_unlock(lock);
     }
     // kdebug!("123");
-    local_irq_restore(flags);
+    local_irq_restore(*flags as usize);
 }
 
 /// 判断一个自旋锁是否已经被加锁
@@ -130,14 +130,14 @@ impl RawSpinlock {
 
     /// @brief 保存中断状态到flags中,关闭中断,并对自旋锁加锁
     pub fn lock_irqsave(&self, flags: &mut u64) {
-        local_irq_save(flags);
+        *flags = local_irq_save() as u64;
         self.lock();
     }
 
     /// @brief 恢复rflags以及中断状态并解锁自旋锁
     pub fn unlock_irqrestore(&self, flags: &u64) {
         self.unlock();
-        local_irq_restore(flags);
+        local_irq_restore(*flags as usize);
     }
 
     /// @brief 尝试保存中断状态到flags中,关闭中断,并对自旋锁加锁
@@ -145,11 +145,11 @@ impl RawSpinlock {
     ///         加锁失败->false
     #[inline(always)]
     pub fn try_lock_irqsave(&self, flags: &mut u64) -> bool {
-        local_irq_save(flags);
+        *flags = local_irq_save() as u64;
         if self.try_lock() {
             return true;
         }
-        local_irq_restore(flags);
+        local_irq_restore(*flags as usize);
         return false;
     }
 }

+ 16 - 8
kernel/src/main.c

@@ -51,7 +51,8 @@ void reload_gdt()
     gdtp.size = bsp_gdt_size - 1;
     gdtp.gdt_vaddr = (ul)phys_2_virt((ul)&GDT_Table);
 
-    asm volatile("lgdt (%0)   \n\t" ::"r"(&gdtp) : "memory");
+    asm volatile("lgdt (%0)   \n\t" ::"r"(&gdtp)
+                 : "memory");
 }
 
 void reload_idt()
@@ -62,7 +63,8 @@ void reload_idt()
     // kdebug("gdtvaddr=%#018lx", p.gdt_vaddr);
     // kdebug("gdt size=%d", p.size);
 
-    asm volatile("lidt (%0)   \n\t" ::"r"(&idtp) : "memory");
+    asm volatile("lidt (%0)   \n\t" ::"r"(&idtp)
+                 : "memory");
 }
 
 // 初始化系统各模块
@@ -124,15 +126,21 @@ void system_initialize()
 
     current_pcb->cpu_id = 0;
     current_pcb->preempt_count = 0;
-    // 先初始化系统调用模块
+    
     syscall_init();
 
     io_mfence();
-    //  再初始化进程模块。顺序不能调转
-    // sched_init();
+
+    rs_timekeeping_init();
     io_mfence();
 
     rs_timer_init();
+    io_mfence();
+
+    rs_jiffies_init();
+    io_mfence();
+
+    rs_clocksource_boot_finish();
     // 这里必须加内存屏障,否则会出错
     io_mfence();
     smp_init();
@@ -140,7 +148,7 @@ void system_initialize()
 
     vfs_init();
     rs_tty_init();
-    
+
     cpu_init();
     ps2_keyboard_init();
     // tty_init();
@@ -160,7 +168,7 @@ void system_initialize()
     io_mfence();
     // current_pcb->preempt_count = 0;
     // kdebug("cpu_get_core_crysral_freq()=%ld", cpu_get_core_crysral_freq());
-    
+
     process_init();
     // 启用double buffer
     // scm_enable_double_buffer();  // 因为时序问题, 该函数调用被移到 initial_kernel_thread
@@ -173,7 +181,7 @@ void system_initialize()
 
     apic_timer_init();
     io_mfence();
-   
+
     // 这里不能删除,否则在O1会报错
     // while (1)
     //     pause();

+ 7 - 4
kernel/src/net/net_core.rs

@@ -15,13 +15,16 @@ use super::socket::{SOCKET_SET, SOCKET_WAITQUEUE};
 /// The network poll function, which will be called by timer.
 ///
 /// The main purpose of this function is to poll all network interfaces.
-struct NetWorkPollFunc();
+#[derive(Debug)]
+struct NetWorkPollFunc;
+
 impl TimerFunction for NetWorkPollFunc {
-    fn run(&mut self) {
+    fn run(&mut self) -> Result<(), SystemError> {
         poll_ifaces_try_lock(10).ok();
         let next_time = next_n_ms_timer_jiffies(10);
-        let timer = Timer::new(Box::new(NetWorkPollFunc()), next_time);
+        let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
         timer.activate();
+        return Ok(());
     }
 }
 
@@ -29,7 +32,7 @@ pub fn net_init() -> Result<(), SystemError> {
     dhcp_query()?;
     // Init poll timer function
     let next_time = next_n_ms_timer_jiffies(5);
-    let timer = Timer::new(Box::new(NetWorkPollFunc()), next_time);
+    let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
     timer.activate();
     return Ok(());
 }

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

@@ -859,7 +859,8 @@ void process_exit_thread(struct process_control_block *pcb)
 int process_release_pcb(struct process_control_block *pcb)
 {
     // 释放子进程的页表
-    process_exit_mm(pcb);
+    // BUG 暂时注释process_exit_mm
+    // process_exit_mm(pcb);
     if ((pcb->flags & PF_KTHREAD)) // 释放内核线程的worker private结构体
         free_kthread_struct(pcb);
 

+ 42 - 1
kernel/src/syscall/mod.rs

@@ -16,7 +16,10 @@ use crate::{
     io::SeekFrom,
     kinfo,
     net::syscall::SockAddr,
-    time::TimeSpec,
+    time::{
+        syscall::{PosixTimeZone, PosixTimeval, SYS_TIMEZONE},
+        TimeSpec,
+    },
 };
 
 #[repr(i32)]
@@ -354,6 +357,7 @@ pub const SYS_ACCEPT: usize = 40;
 
 pub const SYS_GETSOCKNAME: usize = 41;
 pub const SYS_GETPEERNAME: usize = 42;
+pub const SYS_GETTIMEOFDAY: usize = 43;
 
 #[derive(Debug)]
 pub struct Syscall;
@@ -867,6 +871,43 @@ impl Syscall {
             SYS_GETPEERNAME => {
                 Self::getpeername(args[0], args[1] as *mut SockAddr, args[2] as *mut u32)
             }
+            SYS_GETTIMEOFDAY => {
+                let timeval = args[0] as *mut PosixTimeval;
+                let timezone_ptr = args[1] as *const PosixTimeZone;
+                let security_check = || {
+                    if unsafe {
+                        verify_area(timeval as u64, core::mem::size_of::<PosixTimeval>() as u64)
+                    } == false
+                    {
+                        return Err(SystemError::EFAULT);
+                    }
+                    if unsafe {
+                        verify_area(
+                            timezone_ptr as u64,
+                            core::mem::size_of::<PosixTimeZone>() as u64,
+                        )
+                    } == false
+                    {
+                        return Err(SystemError::EFAULT);
+                    }
+                    return Ok(());
+                };
+                let r = security_check();
+                if r.is_err() {
+                    Err(r.unwrap_err())
+                } else {
+                    let timezone = if !timezone_ptr.is_null() {
+                        &SYS_TIMEZONE
+                    } else {
+                        unsafe { timezone_ptr.as_ref().unwrap() }
+                    };
+                    if !timeval.is_null() {
+                        Self::gettimeofday(timeval, timezone)
+                    } else {
+                        Err(SystemError::EFAULT)
+                    }
+                }
+            }
             _ => panic!("Unsupported syscall ID: {}", syscall_num),
         };
 

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

@@ -53,3 +53,6 @@
 #define SYS_ACCEPT 40      // 接受一个socket连接
 #define SYS_GETSOCKNAME 41 // 获取socket的名字
 #define SYS_GETPEERNAME 42 // 获取socket的对端名字
+#define SYS_GETTIMEOFDAY 43 // 获取当前时间
+
+#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用

+ 8 - 0
kernel/src/time/Makefile

@@ -0,0 +1,8 @@
+
+CFLAGS += -I .
+
+
+all: clocksource.o
+
+clocksource.o: clocksource.c
+	$(CC) $(CFLAGS) -c clocksource.c -o clocksource.o

+ 8 - 0
kernel/src/time/clocksource.c

@@ -0,0 +1,8 @@
+#include "clocksource.h"
+#include <common/kthread.h>
+
+void run_watchdog_kthread()
+{
+    kdebug("run_watchdog_kthread");
+    kthread_run(rs_clocksource_watchdog_kthread, NULL, "clocksource_watchdog");
+}

+ 8 - 0
kernel/src/time/clocksource.h

@@ -0,0 +1,8 @@
+#pragma once
+
+#include <common/kthread.h>
+
+extern int rs_clocksource_watchdog_kthread(void *_data);
+extern void rs_clocksource_boot_finish();
+
+void run_watchdog_kthread();

+ 850 - 0
kernel/src/time/clocksource.rs

@@ -0,0 +1,850 @@
+use core::{
+    ffi::c_void,
+    fmt::Debug,
+    sync::atomic::{AtomicBool, Ordering},
+};
+
+use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc, vec::Vec};
+use lazy_static::__Deref;
+
+use crate::{
+    include::bindings::bindings::run_watchdog_kthread, kdebug, kinfo, libs::spinlock::SpinLock,
+    syscall::SystemError,
+};
+
+use super::{
+    jiffies::clocksource_default_clock,
+    timer::{clock, Timer, TimerFunction},
+    NSEC_PER_SEC,
+};
+
+lazy_static! {
+    /// linked list with the registered clocksources
+    pub static ref CLOCKSOURCE_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
+        SpinLock::new(LinkedList::new());
+    /// 被监视中的时钟源
+    pub static ref WATCHDOG_LIST: SpinLock<LinkedList<Arc<dyn Clocksource>>> =
+        SpinLock::new(LinkedList::new());
+
+    pub static ref CLOCKSOUCE_WATCHDOG:SpinLock<ClocksouceWatchdog>  = SpinLock::new(ClocksouceWatchdog::new());
+
+    pub static ref OVERRIDE_NAME: SpinLock<String> = SpinLock::new(String::from(""));
+
+
+}
+
+/// 正在被使用时钟源
+pub static CUR_CLOCKSOURCE: SpinLock<Option<Arc<dyn Clocksource>>> = SpinLock::new(None);
+/// 是否完成加载
+pub static mut FINISHED_BOOTING: AtomicBool = AtomicBool::new(false);
+
+/// Interval: 0.5sec Threshold: 0.0625s
+/// 系统节拍率
+pub const HZ: u64 = 1000;
+/// watchdog检查间隔
+pub const WATCHDOG_INTERVAL: u64 = HZ >> 1;
+/// 最大能接受的误差大小
+pub const WATCHDOG_THRESHOLD: u32 = NSEC_PER_SEC >> 4;
+
+// 时钟周期数
+#[derive(Debug, Clone, Copy)]
+#[repr(transparent)]
+pub struct CycleNum(pub u64);
+
+#[allow(dead_code)]
+impl CycleNum {
+    #[inline(always)]
+    pub fn new(cycle: u64) -> Self {
+        Self(cycle)
+    }
+    #[inline(always)]
+    pub fn data(&self) -> u64 {
+        self.0
+    }
+    #[inline(always)]
+    #[allow(dead_code)]
+    pub fn add(&self, other: CycleNum) -> CycleNum {
+        CycleNum(self.data() + other.data())
+    }
+    #[inline(always)]
+    pub fn div(&self, other: CycleNum) -> CycleNum {
+        CycleNum(self.data() - other.data())
+    }
+}
+
+bitflags! {
+
+    #[derive(Default)]
+    pub struct ClocksourceMask: u64 {
+    }
+    /// 时钟状态标记
+    #[derive(Default)]
+    pub struct ClocksourceFlags: u64 {
+        /// 表示时钟设备是连续的
+        const CLOCK_SOURCE_IS_CONTINUOUS = 0x01;
+        /// 表示该时钟源需要经过watchdog检查
+        const CLOCK_SOURCE_MUST_VERIFY = 0x02;
+        /// 表示该时钟源是watchdog
+        const CLOCK_SOURCE_WATCHDOG = 0x10;
+        /// 表示该时钟源是高分辨率的
+        const CLOCK_SOURCE_VALID_FOR_HRES = 0x20;
+        /// 表示该时钟源误差过大
+        const CLOCK_SOURCE_UNSTABLE = 0x40;
+    }
+}
+impl From<u64> for ClocksourceMask {
+    fn from(value: u64) -> Self {
+        if value < 64 {
+            return Self::from_bits_truncate((1 << value) - 1);
+        }
+        return Self::from_bits_truncate(u64::MAX);
+    }
+}
+impl ClocksourceMask {
+    pub fn new(b: u64) -> Self {
+        Self { bits: b }
+    }
+}
+impl ClocksourceFlags {
+    pub fn new(b: u64) -> Self {
+        Self { bits: b }
+    }
+}
+
+#[derive(Debug)]
+pub struct ClocksouceWatchdog {
+    /// 监视器
+    watchdog: Option<Arc<dyn Clocksource>>,
+    /// 检查器是否在工作的标志
+    is_running: bool,
+    /// 上一次检查的时刻
+    last_check: CycleNum,
+    /// 定时监视器的过期时间
+    timer_expires: u64,
+}
+impl ClocksouceWatchdog {
+    pub fn new() -> Self {
+        Self {
+            watchdog: None,
+            is_running: false,
+            last_check: CycleNum(0),
+            timer_expires: 0,
+        }
+    }
+
+    /// 获取watchdog
+    fn get_watchdog(&mut self) -> &mut Option<Arc<dyn Clocksource>> {
+        &mut self.watchdog
+    }
+
+    /// 启用检查器
+    pub fn clocksource_start_watchdog(&mut self) {
+        // 如果watchdog未被设置或者已经启用了就退出
+        let watchdog_list = &WATCHDOG_LIST.lock();
+        if self.is_running || self.watchdog.is_none() || watchdog_list.is_empty() {
+            return;
+        }
+        // 生成一个定时器
+        let wd_timer_func: Box<WatchdogTimerFunc> = Box::new(WatchdogTimerFunc {});
+        self.timer_expires += clock() + WATCHDOG_INTERVAL;
+        self.last_check = self.watchdog.as_ref().unwrap().clone().read();
+        let wd_timer = Timer::new(wd_timer_func, self.timer_expires);
+        wd_timer.activate();
+        self.is_running = true;
+    }
+
+    /// 停止检查器
+    /// list_len WATCHDOG_LIST长度
+    pub fn clocksource_stop_watchdog(&mut self, list_len: usize) {
+        if !self.is_running || (self.watchdog.is_some() && list_len != 0) {
+            return;
+        }
+        // TODO 当实现了周期性的定时器后 需要将监视用的定时器删除
+        self.is_running = false;
+    }
+}
+
+/// 定时检查器
+#[derive(Debug)]
+pub struct WatchdogTimerFunc;
+impl TimerFunction for WatchdogTimerFunc {
+    fn run(&mut self) -> Result<(), SystemError> {
+        return clocksource_watchdog();
+    }
+}
+
+/// 时钟源的特性
+pub trait Clocksource: Send + Sync + Debug {
+    // TODO 返回值类型可能需要改变
+    /// returns a cycle value, passes clocksource as argument
+    fn read(&self) -> CycleNum;
+    /// optional function to enable the clocksource
+    fn enable(&self) -> Result<i32, SystemError> {
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+    /// optional function to disable the clocksource
+    fn disable(&self) -> Result<(), SystemError> {
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+    /// vsyscall based read
+    fn vread(&self) -> Result<CycleNum, SystemError> {
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+    /// suspend function for the clocksource, if necessary
+    fn suspend(&self) -> Result<(), SystemError> {
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+    /// resume function for the clocksource, if necessary
+    fn resume(&self) -> Result<(), SystemError> {
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+    // 获取时钟源数据
+    fn clocksource_data(&self) -> ClocksourceData;
+
+    fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
+        return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
+    }
+    // 获取时钟源
+    fn clocksource(&self) -> Arc<dyn Clocksource>;
+}
+
+/// # 实现整数log2的运算
+///
+/// ## 参数
+///
+/// * `x` - 要计算的数字
+///
+/// ## 返回值
+///
+/// * `u32` - 返回\log_2(x)的值
+fn log2(x: u32) -> u32 {
+    let mut result = 0;
+    let mut x = x;
+
+    if x >= 1 << 16 {
+        x >>= 16;
+        result |= 16;
+    }
+    if x >= 1 << 8 {
+        x >>= 8;
+        result |= 8;
+    }
+    if x >= 1 << 4 {
+        x >>= 4;
+        result |= 4;
+    }
+    if x >= 1 << 2 {
+        x >>= 2;
+        result |= 2;
+    }
+    if x >= 1 << 1 {
+        result |= 1;
+    }
+
+    result
+}
+
+impl dyn Clocksource {
+    /// # 计算时钟源能记录的最大时间跨度
+    pub fn clocksource_max_deferment(&self) -> u64 {
+        let cs_data_guard = self.clocksource_data();
+        let max_nsecs: u64;
+        let mut max_cycles: u64;
+        max_cycles = (1 << (63 - (log2(cs_data_guard.mult) + 1))) as u64;
+        max_cycles = max_cycles.min(cs_data_guard.mask.bits);
+        max_nsecs = clocksource_cyc2ns(
+            CycleNum(max_cycles),
+            cs_data_guard.mult,
+            cs_data_guard.shift,
+        );
+        return max_nsecs - (max_nsecs >> 5);
+    }
+
+    /// # 注册时钟源
+    ///
+    /// ## 返回值
+    ///
+    /// * `Ok(0)` - 时钟源注册成功。
+    /// * `Err(SystemError)` - 时钟源注册失败。
+    pub fn register(&self) -> Result<i32, SystemError> {
+        let ns = self.clocksource_max_deferment();
+        let mut cs_data = self.clocksource_data();
+        cs_data.max_idle_ns = ns as u32;
+        self.update_clocksource_data(cs_data)?;
+        // 将时钟源加入到时钟源队列中
+        self.clocksource_enqueue();
+        // 将时钟源加入到监视队列中
+        self.clocksource_enqueue_watchdog()
+            .expect("register: failed to enqueue watchdog list");
+        // 选择一个最好的时钟源
+        clocksource_select();
+        kdebug!("clocksource_register successfully");
+        return Ok(0);
+    }
+
+    /// # 将时钟源插入时钟源队列
+    pub fn clocksource_enqueue(&self) {
+        // 根据rating由大到小排序
+        let cs_data = self.clocksource_data();
+        let list_guard = &mut CLOCKSOURCE_LIST.lock();
+        let mut spilt_pos: usize = 0;
+        for (pos, ele) in list_guard.iter().enumerate() {
+            if ele.clocksource_data().rating < cs_data.rating {
+                spilt_pos = pos;
+                break;
+            }
+        }
+        let mut temp_list = list_guard.split_off(spilt_pos);
+        let cs = self.clocksource();
+        list_guard.push_back(cs);
+        list_guard.append(&mut temp_list);
+        // kdebug!(
+        //     "CLOCKSOURCE_LIST len = {:?},clocksource_enqueue sccessfully",
+        //     list_guard.len()
+        // );
+    }
+
+    /// # 将时间源插入监控队列
+    ///
+    /// ## 返回值
+    ///
+    /// * `Ok(0)` - 时间源插入监控队列成功
+    /// * `Err(SystemError)` - 时间源插入监控队列失败
+    pub fn clocksource_enqueue_watchdog(&self) -> Result<i32, SystemError> {
+        // BUG 可能需要lock irq
+        let mut cs_data = self.clocksource_data();
+
+        let cs = self.clocksource();
+        if cs_data
+            .flags
+            .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
+        {
+            let mut list_guard = WATCHDOG_LIST.lock_irqsave();
+            // cs是被监视的
+            cs_data
+                .flags
+                .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
+            cs.update_clocksource_data(cs_data)?;
+            list_guard.push_back(cs);
+        } else {
+            // cs是监视器
+            if cs_data
+                .flags
+                .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
+            {
+                // 如果时钟设备是连续的
+                cs_data
+                    .flags
+                    .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
+                cs.update_clocksource_data(cs_data.clone())?;
+            }
+
+            // 将时钟源加入到监控队列中
+            let mut list_guard = WATCHDOG_LIST.lock();
+            list_guard.push_back(cs.clone());
+            drop(list_guard);
+
+            // 对比当前注册的时间源的精度和监视器的精度
+            let cs_watchdog = &mut CLOCKSOUCE_WATCHDOG.lock();
+            if cs_watchdog.watchdog.is_none()
+                || cs_data.rating
+                    > cs_watchdog
+                        .watchdog
+                        .clone()
+                        .unwrap()
+                        .clocksource_data()
+                        .rating
+            {
+                // 当前注册的时间源的精度更高或者没有监视器,替换监视器
+                cs_watchdog.watchdog.replace(cs);
+                clocksource_reset_watchdog();
+            }
+
+            // 启动监视器
+            cs_watchdog.clocksource_start_watchdog();
+        }
+        return Ok(0);
+    }
+
+    /// # 将时钟源标记为unstable
+    ///
+    /// ## 参数
+    /// * `delta` - 时钟源误差
+    pub fn set_unstable(&self, delta: i64) -> Result<i32, SystemError> {
+        let mut cs_data = self.clocksource_data();
+        // 打印出unstable的时钟源信息
+        kdebug!(
+            "clocksource :{:?} is unstable, its delta is {:?}",
+            cs_data.name,
+            delta
+        );
+        cs_data.flags.remove(
+            ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES | ClocksourceFlags::CLOCK_SOURCE_WATCHDOG,
+        );
+        cs_data
+            .flags
+            .insert(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE);
+        self.update_clocksource_data(cs_data)?;
+
+        // 启动watchdog线程 进行后续处理
+        if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } {
+            // TODO 在实现了工作队列后,将启动线程换成schedule work
+            unsafe { run_watchdog_kthread() }
+        }
+        return Ok(0);
+    }
+
+    /// # 将时间源从监视链表中弹出
+    fn clocksource_dequeue_watchdog(&self) {
+        let data = self.clocksource_data();
+        let mut locked_watchdog = CLOCKSOUCE_WATCHDOG.lock();
+        let watchdog = locked_watchdog
+            .get_watchdog()
+            .clone()
+            .unwrap()
+            .clocksource_data();
+
+        let mut list = WATCHDOG_LIST.lock();
+        let mut size = list.len();
+
+        let mut del_pos: usize = size;
+        for (pos, ele) in list.iter().enumerate() {
+            let ele_data = ele.clocksource_data();
+            if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
+                // 记录要删除的时钟源在监视链表中的下标
+                del_pos = pos;
+            }
+        }
+
+        if data
+            .flags
+            .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
+        {
+            // 如果时钟源是需要被检查的,直接删除时钟源
+            if del_pos != size {
+                let mut temp_list = list.split_off(del_pos);
+                temp_list.pop_front();
+                list.append(&mut temp_list);
+            }
+        } else if watchdog.name.eq(&data.name) && watchdog.rating.eq(&data.rating) {
+            // 如果要删除的时钟源是监视器,则需要找到一个新的监视器
+            // TODO 重新设置时钟源
+            // 将链表解锁防止reset中双重加锁 并释放保存的旧的watchdog的数据
+
+            // 代替了clocksource_reset_watchdog()的功能,将所有时钟源的watchdog标记清除
+            for ele in list.iter() {
+                ele.clocksource_data()
+                    .flags
+                    .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
+            }
+
+            // 遍历所有时间源,寻找新的监视器
+            let mut clocksource_list = CLOCKSOURCE_LIST.lock();
+            let mut replace_pos: usize = clocksource_list.len();
+            for (pos, ele) in clocksource_list.iter().enumerate() {
+                let ele_data = ele.clocksource_data();
+
+                if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating)
+                    || ele_data
+                        .flags
+                        .contains(ClocksourceFlags::CLOCK_SOURCE_MUST_VERIFY)
+                {
+                    // 当前时钟源是要被删除的时钟源或没被检查过的时钟源
+                    // 不适合成为监视器
+                    continue;
+                }
+                let watchdog = locked_watchdog.get_watchdog().clone();
+                if watchdog.is_none()
+                    || ele_data.rating > watchdog.unwrap().clocksource_data().rating
+                {
+                    // 如果watchdog不存在或者当前时钟源的精度高于watchdog的精度,则记录当前时钟源的下标
+                    replace_pos = pos;
+                }
+            }
+            // 使用刚刚找到的更好的时钟源替换旧的watchdog
+            if replace_pos < clocksource_list.len() {
+                let mut temp_list = clocksource_list.split_off(replace_pos);
+                let new_wd = temp_list.front().unwrap().clone();
+                clocksource_list.append(&mut temp_list);
+                // 替换watchdog
+                locked_watchdog.watchdog.replace(new_wd);
+                // drop(locked_watchdog);
+            }
+            // 删除时钟源
+            if del_pos != size {
+                let mut temp_list = list.split_off(del_pos);
+                temp_list.pop_front();
+                list.append(&mut temp_list);
+            }
+        }
+
+        // 清除watchdog标记
+        let mut cs_data = self.clocksource_data();
+        cs_data
+            .flags
+            .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
+        self.update_clocksource_data(cs_data)
+            .expect("clocksource_dequeue_watchdog: failed to update clocksource data");
+        size = list.len();
+        // 停止当前的watchdog
+        locked_watchdog.clocksource_stop_watchdog(size - 1);
+    }
+
+    /// # 将时钟源从时钟源链表中弹出
+    fn clocksource_dequeue(&self) {
+        let mut list = CLOCKSOURCE_LIST.lock();
+        let data = self.clocksource_data();
+        let mut del_pos: usize = list.len();
+        for (pos, ele) in list.iter().enumerate() {
+            let ele_data = ele.clocksource_data();
+            if ele_data.name.eq(&data.name) && ele_data.rating.eq(&data.rating) {
+                // 记录时钟源在链表中的下标
+                del_pos = pos;
+            }
+        }
+
+        // 删除时钟源
+        if del_pos != list.len() {
+            let mut temp_list = list.split_off(del_pos);
+            temp_list.pop_front();
+            list.append(&mut temp_list);
+        }
+    }
+
+    /// # 注销时钟源
+    #[allow(dead_code)]
+    pub fn unregister(&self) {
+        // 将时钟源从监视链表中弹出
+        self.clocksource_dequeue_watchdog();
+        // 将时钟源从时钟源链表中弹出
+        self.clocksource_dequeue();
+        // 检查是否有更好的时钟源
+        clocksource_select();
+    }
+    /// # 修改时钟源的精度
+    ///
+    /// ## 参数
+    ///
+    /// * `rating` - 指定的时钟精度
+    fn clocksource_change_rating(&self, rating: i32) {
+        // 将时钟源从链表中弹出
+        self.clocksource_dequeue();
+        let mut data = self.clocksource_data();
+        // 修改时钟源的精度
+        data.set_rating(rating);
+        self.update_clocksource_data(data)
+            .expect("clocksource_change_rating:updata clocksource failed");
+        // 插入时钟源到时钟源链表中
+        self.clocksource_enqueue();
+        // 检查是否有更好的时钟源
+        clocksource_select();
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct ClocksourceData {
+    /// 时钟源名字
+    pub name: String,
+    /// 时钟精度
+    pub rating: i32,
+    pub mask: ClocksourceMask,
+    pub mult: u32,
+    pub shift: u32,
+    pub max_idle_ns: u32,
+    pub flags: ClocksourceFlags,
+    pub watchdog_last: CycleNum,
+}
+
+impl ClocksourceData {
+    #[allow(dead_code)]
+    pub fn new(
+        name: String,
+        rating: i32,
+        mask: ClocksourceMask,
+        mult: u32,
+        shift: u32,
+        max_idle_ns: u32,
+        flags: ClocksourceFlags,
+    ) -> Self {
+        let csd = ClocksourceData {
+            name,
+            rating,
+            mask,
+            mult,
+            shift,
+            max_idle_ns,
+            flags,
+            watchdog_last: CycleNum(0),
+        };
+        return csd;
+    }
+
+    pub fn set_name(&mut self, name: String) {
+        self.name = name;
+    }
+    pub fn set_rating(&mut self, rating: i32) {
+        self.rating = rating;
+    }
+    pub fn set_mask(&mut self, mask: ClocksourceMask) {
+        self.mask = mask;
+    }
+    pub fn set_mult(&mut self, mult: u32) {
+        self.mult = mult;
+    }
+    pub fn set_shift(&mut self, shift: u32) {
+        self.shift = shift;
+    }
+    pub fn set_max_idle_ns(&mut self, max_idle_ns: u32) {
+        self.max_idle_ns = max_idle_ns;
+    }
+    pub fn set_flags(&mut self, flags: ClocksourceFlags) {
+        self.flags = flags;
+    }
+    #[allow(dead_code)]
+    pub fn remove_flags(&mut self, flags: ClocksourceFlags) {
+        self.flags.remove(flags)
+    }
+    #[allow(dead_code)]
+    pub fn insert_flags(&mut self, flags: ClocksourceFlags) {
+        self.flags.insert(flags)
+    }
+}
+
+///  converts clocksource cycles to nanoseconds
+///
+pub fn clocksource_cyc2ns(cycles: CycleNum, mult: u32, shift: u32) -> u64 {
+    return (cycles.data() * mult as u64) >> shift;
+}
+
+/// # 重启所有的时间源
+#[allow(dead_code)]
+pub fn clocksource_resume() {
+    let list = CLOCKSOURCE_LIST.lock();
+    for ele in list.iter() {
+        let data = ele.clocksource_data();
+        match ele.resume() {
+            Ok(_) => continue,
+            Err(_) => {
+                kdebug!("clocksource {:?} resume failed", data.name)
+            }
+        }
+    }
+    clocksource_resume_watchdog();
+}
+
+/// # 暂停所有的时间源
+#[allow(dead_code)]
+pub fn clocksource_suspend() {
+    let list = CLOCKSOURCE_LIST.lock();
+    for ele in list.iter() {
+        let data = ele.clocksource_data();
+        match ele.suspend() {
+            Ok(_) => continue,
+            Err(_) => {
+                kdebug!("clocksource {:?} suspend failed", data.name)
+            }
+        }
+    }
+}
+
+/// # 根据watchdog的精度,来检查被监视的时钟源的误差
+///
+/// ## 返回值
+///
+/// * `Ok()` - 检查完成
+/// * `Err(SystemError)` - 错误码
+pub fn clocksource_watchdog() -> Result<(), SystemError> {
+    let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock();
+
+    // watchdog没有在运行的话直接退出
+    if !cs_watchdog.is_running || cs_watchdog.watchdog.is_none() {
+        return Ok(());
+    }
+    let cur_watchdog = cs_watchdog.watchdog.as_ref().unwrap().clone();
+    let cur_wd_data = cur_watchdog.as_ref().clocksource_data();
+    let cur_wd_nowclock = cur_watchdog.as_ref().read().data();
+
+    let wd_last = cs_watchdog.last_check.data();
+    let wd_dev_nsec = clocksource_cyc2ns(
+        CycleNum((cur_wd_nowclock - wd_last) & cur_wd_data.mask.bits),
+        cur_wd_data.mult,
+        cur_wd_data.shift,
+    );
+    cs_watchdog.last_check = CycleNum(cur_wd_nowclock);
+    drop(cs_watchdog);
+    let watchdog_list = &mut WATCHDOG_LIST.lock();
+    for cs in watchdog_list.iter() {
+        let mut cs_data = cs.clocksource_data();
+        // 判断时钟源是否已经被标记为不稳定
+        if cs_data
+            .flags
+            .contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE)
+        {
+            // 启动watchdog_kthread
+            unsafe { run_watchdog_kthread() };
+            continue;
+        }
+        // 读取时钟源现在的时间
+        let cs_now_clock = cs.read();
+
+        // 如果时钟源没有被监视,则开始监视他
+        if !cs_data
+            .flags
+            .contains(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG)
+        {
+            cs_data
+                .flags
+                .insert(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
+            // 记录此次检查的时刻
+            cs_data.watchdog_last = cs_now_clock;
+            cs.update_clocksource_data(cs_data.clone())?;
+            continue;
+        }
+
+        // 计算时钟源的误差
+        let cs_dev_nsec = clocksource_cyc2ns(
+            CycleNum(cs_now_clock.div(cs_data.watchdog_last).data() & cs_data.mask.bits),
+            cs_data.mult,
+            cs_data.shift,
+        );
+        // 记录此次检查的时刻
+        cs_data.watchdog_last = cs_now_clock;
+        cs.update_clocksource_data(cs_data.clone())?;
+        if cs_dev_nsec.abs_diff(wd_dev_nsec) > WATCHDOG_THRESHOLD.into() {
+            // 误差过大,标记为unstable
+            cs.set_unstable((cs_dev_nsec - wd_dev_nsec).try_into().unwrap())?;
+            continue;
+        }
+
+        // 判断是否要切换为高精度模式
+        if !cs_data
+            .flags
+            .contains(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES)
+            && cs_data
+                .flags
+                .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
+            && cur_wd_data
+                .flags
+                .contains(ClocksourceFlags::CLOCK_SOURCE_IS_CONTINUOUS)
+        {
+            cs_data
+                .flags
+                .insert(ClocksourceFlags::CLOCK_SOURCE_VALID_FOR_HRES);
+            cs.update_clocksource_data(cs_data)?;
+            // TODO 通知tick机制 切换为高精度模式
+        }
+        let mut cs_watchdog = CLOCKSOUCE_WATCHDOG.lock();
+        // FIXME 需要保证所有cpu时间统一
+        cs_watchdog.timer_expires += WATCHDOG_INTERVAL;
+        //创建定时器执行watchdog
+        let watchdog_func = Box::new(WatchdogTimerFunc {});
+        let watchdog_timer = Timer::new(watchdog_func, cs_watchdog.timer_expires);
+        watchdog_timer.activate();
+    }
+    return Ok(());
+}
+
+/// # watchdog线程的逻辑,执行unstable的后续操作
+pub fn clocksource_watchdog_kthread() {
+    let mut del_vec: Vec<usize> = Vec::new();
+    let mut del_clocks: Vec<Arc<dyn Clocksource>> = Vec::new();
+    let wd_list = &mut WATCHDOG_LIST.lock();
+
+    // 将不稳定的时钟源弹出监视链表
+    for (pos, ele) in wd_list.iter().enumerate() {
+        let data = ele.clocksource_data();
+        if data.flags.contains(ClocksourceFlags::CLOCK_SOURCE_UNSTABLE) {
+            del_vec.push(pos);
+            del_clocks.push(ele.clone());
+        }
+    }
+    for pos in del_vec {
+        let mut temp_list = wd_list.split_off(pos);
+        temp_list.pop_front();
+        wd_list.append(&mut temp_list);
+    }
+
+    // 检查是否需要停止watchdog
+    CLOCKSOUCE_WATCHDOG
+        .lock()
+        .clocksource_stop_watchdog(wd_list.len());
+    // 将不稳定的时钟源精度都设置为最低
+    for clock in del_clocks.iter() {
+        clock.clocksource_change_rating(0);
+    }
+}
+
+/// # 清空所有时钟源的watchdog标志位
+pub fn clocksource_reset_watchdog() {
+    let list_guard = WATCHDOG_LIST.lock();
+    for ele in list_guard.iter() {
+        ele.clocksource_data()
+            .flags
+            .remove(ClocksourceFlags::CLOCK_SOURCE_WATCHDOG);
+    }
+}
+
+/// # 重启检查器
+pub fn clocksource_resume_watchdog() {
+    clocksource_reset_watchdog();
+}
+
+/// # 根据精度选择最优的时钟源,或者接受用户指定的时间源
+pub fn clocksource_select() {
+    let list_guard = CLOCKSOURCE_LIST.lock();
+    if unsafe { FINISHED_BOOTING.load(Ordering::Relaxed) } || list_guard.is_empty() {
+        return;
+    }
+    let mut best = list_guard.front().unwrap().clone();
+    let override_name = OVERRIDE_NAME.lock();
+    // 判断是否有用户空间指定的时间源
+    for ele in list_guard.iter() {
+        if ele.clocksource_data().name.eq(override_name.deref()) {
+            // TODO 判断是否是高精度模式
+            // 暂时不支持高精度模式
+            // 如果是高精度模式,但是时钟源不支持高精度模式的话,就要退出循环
+            best = ele.clone();
+            break;
+        }
+    }
+    // 对比当前的时钟源和记录到最好的时钟源的精度
+    if CUR_CLOCKSOURCE.lock().as_ref().is_some() {
+        // 当前时钟源不为空
+        let cur_clocksource = CUR_CLOCKSOURCE.lock().as_ref().unwrap().clone();
+        let best_name = &best.clocksource_data().name;
+        if cur_clocksource.clocksource_data().name.ne(best_name) {
+            kinfo!("Switching to the clocksource {:?}\n", best_name);
+            drop(cur_clocksource);
+            CUR_CLOCKSOURCE.lock().replace(best);
+            // TODO 通知timerkeeping 切换了时间源
+        }
+    } else {
+        // 当前时钟源为空
+        CUR_CLOCKSOURCE.lock().replace(best);
+    }
+    kdebug!(" clocksource_select finish");
+}
+
+/// # clocksource模块加载完成
+pub fn clocksource_boot_finish() {
+    let mut cur_clocksource = CUR_CLOCKSOURCE.lock();
+    cur_clocksource.replace(clocksource_default_clock());
+    unsafe { FINISHED_BOOTING.store(true, Ordering::Relaxed) };
+    // 清除不稳定的时钟源
+    clocksource_watchdog_kthread();
+    kdebug!("clocksource_boot_finish");
+}
+
+// ======== 以下为对C的接口 ========
+/// # 完成对clocksource模块的加载
+#[no_mangle]
+pub extern "C" fn rs_clocksource_boot_finish() {
+    clocksource_boot_finish();
+}
+
+/// # 启动watchdog线程的辅助函数
+#[no_mangle]
+pub extern "C" fn rs_clocksource_watchdog_kthread(_data: c_void) -> i32 {
+    clocksource_watchdog_kthread();
+    return 0;
+}

+ 3 - 0
kernel/src/time/jiffies.h

@@ -0,0 +1,3 @@
+#pragma once
+
+extern void rs_jiffies_init();

+ 100 - 0
kernel/src/time/jiffies.rs

@@ -0,0 +1,100 @@
+use alloc::{
+    string::ToString,
+    sync::{Arc, Weak},
+};
+
+use crate::{kdebug, libs::spinlock::SpinLock, syscall::SystemError};
+
+use super::{
+    clocksource::{Clocksource, ClocksourceData, ClocksourceFlags, ClocksourceMask, CycleNum, HZ},
+    timer::clock,
+    NSEC_PER_SEC,
+};
+lazy_static! {
+    pub static ref DEFAULT_CLOCK: Arc<ClocksourceJiffies> = ClocksourceJiffies::new();
+}
+pub const CLOCK_TICK_RATE: u32 = HZ as u32 * 100000;
+pub const JIFFIES_SHIFT: u32 = 8;
+pub const LATCH: u32 = ((CLOCK_TICK_RATE + (HZ as u32) / 2) / HZ as u32) as u32;
+pub const ACTHZ: u32 = sh_div(CLOCK_TICK_RATE, LATCH, 8);
+pub const NSEC_PER_JIFFY: u32 = ((NSEC_PER_SEC << 8) / ACTHZ) as u32;
+pub const fn sh_div(nom: u32, den: u32, lsh: u32) -> u32 {
+    (((nom) / (den)) << (lsh)) + ((((nom) % (den)) << (lsh)) + (den) / 2) / (den)
+}
+
+#[derive(Debug)]
+pub struct ClocksourceJiffies(SpinLock<InnerJiffies>);
+
+#[derive(Debug)]
+pub struct InnerJiffies {
+    data: ClocksourceData,
+    self_ref: Weak<ClocksourceJiffies>,
+}
+
+impl Clocksource for ClocksourceJiffies {
+    fn read(&self) -> CycleNum {
+        CycleNum(clock())
+    }
+
+    fn clocksource_data(&self) -> ClocksourceData {
+        let inner = self.0.lock();
+        return inner.data.clone();
+    }
+
+    fn clocksource(&self) -> Arc<dyn Clocksource> {
+        self.0.lock().self_ref.upgrade().unwrap()
+    }
+    fn update_clocksource_data(&self, _data: ClocksourceData) -> Result<(), SystemError> {
+        let d = &mut self.0.lock().data;
+        d.set_flags(_data.flags);
+        d.set_mask(_data.mask);
+        d.set_max_idle_ns(_data.max_idle_ns);
+        d.set_mult(_data.mult);
+        d.set_name(_data.name);
+        d.set_rating(_data.rating);
+        d.set_shift(_data.shift);
+        return Ok(());
+    }
+
+    fn enable(&self) -> Result<i32, SystemError> {
+        return Ok(0);
+    }
+}
+impl ClocksourceJiffies {
+    pub fn new() -> Arc<Self> {
+        let data = ClocksourceData {
+            name: "jiffies".to_string(),
+            rating: 1,
+            mask: ClocksourceMask::new(0xffffffff),
+            mult: NSEC_PER_JIFFY << JIFFIES_SHIFT,
+            shift: JIFFIES_SHIFT,
+            max_idle_ns: Default::default(),
+            flags: ClocksourceFlags::new(0),
+            watchdog_last: CycleNum(0),
+        };
+        let jieffies = Arc::new(ClocksourceJiffies(SpinLock::new(InnerJiffies {
+            data,
+            self_ref: Default::default(),
+        })));
+        jieffies.0.lock().self_ref = Arc::downgrade(&jieffies);
+
+        return jieffies;
+    }
+}
+pub fn clocksource_default_clock() -> Arc<ClocksourceJiffies> {
+    DEFAULT_CLOCK.clone()
+}
+
+pub fn jiffies_init() {
+    //注册jiffies
+    let jiffies = clocksource_default_clock() as Arc<dyn Clocksource>;
+    match jiffies.register() {
+        Ok(_) => kdebug!("jiffies_init sccessfully"),
+        Err(_) => kdebug!("jiffies_init failed, no default clock running"),
+    }
+}
+
+#[no_mangle]
+pub extern "C" fn rs_jiffies_init() {
+    jiffies_init();
+}

+ 18 - 1
kernel/src/time/mod.rs

@@ -2,11 +2,14 @@ use core::{fmt, ops};
 
 use self::timekeep::ktime_get_real_ns;
 
+pub mod clocksource;
+pub mod jiffies;
 pub mod sleep;
 pub mod syscall;
+pub mod timeconv;
 pub mod timekeep;
+pub mod timekeeping;
 pub mod timer;
-
 /* Time structures. (Partitially taken from smoltcp)
 
 The `time` module contains structures used to represent both
@@ -18,6 +21,20 @@ absolute and relative time.
 [Instant]: struct.Instant.html
 [Duration]: struct.Duration.html
 */
+#[allow(dead_code)]
+pub const MSEC_PER_SEC: u32 = 1000;
+#[allow(dead_code)]
+pub const USEC_PER_MSEC: u32 = 1000;
+#[allow(dead_code)]
+pub const NSEC_PER_USEC: u32 = 1000;
+#[allow(dead_code)]
+pub const NSEC_PER_MSEC: u32 = 1000000;
+#[allow(dead_code)]
+pub const USEC_PER_SEC: u32 = 1000000;
+#[allow(dead_code)]
+pub const NSEC_PER_SEC: u32 = 1000000000;
+#[allow(dead_code)]
+pub const FSEC_PER_SEC: u64 = 1000000000000000;
 
 /// 表示时间的结构体,符合POSIX标准。
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]

+ 51 - 1
kernel/src/time/syscall.rs

@@ -1,10 +1,42 @@
-use core::ptr::null_mut;
+use core::{
+    ffi::{c_int, c_longlong},
+    ptr::null_mut,
+};
 
 use crate::{
+    kdebug,
     syscall::{Syscall, SystemError},
     time::{sleep::nanosleep, TimeSpec},
 };
 
+use super::timekeeping::do_gettimeofday;
+
+pub type PosixTimeT = c_longlong;
+pub type PosixSusecondsT = c_int;
+
+#[repr(C)]
+#[derive(Default, Debug)]
+pub struct PosixTimeval {
+    pub tv_sec: PosixTimeT,
+    pub tv_usec: PosixSusecondsT,
+}
+
+#[repr(C)]
+#[derive(Default, Debug)]
+/// 当前时区信息
+pub struct PosixTimeZone {
+    /// 格林尼治相对于当前时区相差的分钟数
+    pub tz_minuteswest: c_int,
+    /// DST矫正时差
+    pub tz_dsttime: c_int,
+}
+
+/// 系统时区 暂时写定为东八区
+pub const SYS_TIMEZONE: PosixTimeZone = PosixTimeZone {
+    tz_minuteswest: -480,
+    tz_dsttime: 0,
+};
+
 impl Syscall {
     /// @brief 休眠指定时间(单位:纳秒)(提供给C的接口)
     ///
@@ -44,4 +76,22 @@ impl Syscall {
     pub fn clock() -> Result<usize, SystemError> {
         return Ok(super::timer::clock() as usize);
     }
+
+    pub fn gettimeofday(
+        tv: *mut PosixTimeval,
+        _timezone: &PosixTimeZone,
+    ) -> Result<usize, SystemError> {
+        // TODO; 处理时区信息
+        kdebug!("enter sys_do_gettimeofday");
+        if tv == null_mut() {
+            return Err(SystemError::EFAULT);
+        }
+        let posix_time = do_gettimeofday();
+        unsafe {
+            (*tv).tv_sec = posix_time.tv_sec;
+            (*tv).tv_usec = posix_time.tv_usec;
+        }
+        kdebug!("exit sys_do_gettimeofday");
+        return Ok(0);
+    }
 }

+ 143 - 0
kernel/src/time/timeconv.rs

@@ -0,0 +1,143 @@
+use super::syscall::PosixTimeT;
+/// 一小时所包含的秒数
+const SECS_PER_HOUR: i64 = 60 * 60;
+/// 一天所包含的秒数
+const SECS_PER_DAY: i64 = SECS_PER_HOUR * 24;
+/// 每年中每个月最后一天所对应天数
+const MON_OF_YDAY: [[i64; 13]; 2] = [
+    // 普通年
+    [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365],
+    // 闰年
+    [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366],
+];
+#[derive(Debug)]
+#[allow(dead_code)]
+pub struct CalendarTime {
+    tm_sec: i32,
+    tm_min: i32,
+    tm_hour: i32,
+    tm_mday: i32,
+    tm_mon: i32,
+    tm_wday: i32,
+    tm_yday: i32,
+    tm_year: i32,
+}
+impl CalendarTime {
+    pub fn new() -> Self {
+        CalendarTime {
+            tm_year: Default::default(),
+            tm_sec: Default::default(),
+            tm_min: Default::default(),
+            tm_hour: Default::default(),
+            tm_mday: Default::default(),
+            tm_mon: Default::default(),
+            tm_wday: Default::default(),
+            tm_yday: Default::default(),
+        }
+    }
+}
+
+/// # 判断是否是闰年
+///
+/// ## 参数
+///
+/// * 'year' - 年份
+fn is_leap(year: u32) -> bool {
+    let mut flag = false;
+    if (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 {
+        flag = true;
+    }
+    return flag;
+}
+
+/// # 计算除法
+///
+/// # 参数
+///
+/// * 'left' - 被除数
+/// * 'right' - 除数
+fn math_div(left: u32, right: u32) -> u32 {
+    return left / right;
+}
+
+/// # 计算两年之间的闰年数目
+///
+/// ## 参数
+///
+/// * 'y1' - 起始年份
+/// * 'y2' - 结束年份
+fn leaps_between(y1: u32, y2: u32) -> u32 {
+    // 算出y1之前的闰年数量
+    let y1_leaps = math_div(y1 - 1, 4) - math_div(y1 - 1, 100) + math_div(y1 - 1, 400);
+    // 算出y2之前的闰年数量
+    let y2_leaps = math_div(y2 - 1, 4) - math_div(y2 - 1, 100) + math_div(y2 - 1, 400);
+
+    y2_leaps - y1_leaps
+}
+
+/// # 将秒数转换成日期
+///
+/// ## 参数
+///
+/// * 'totalsecs' - 1970年1月1日 00:00:00 UTC到现在的秒数
+/// * 'offset' - 指定的秒数对应的时间段(含)的偏移量(以秒为单位)
+#[allow(dead_code)]
+pub fn time_to_calendar(totalsecs: PosixTimeT, offset: i32) -> CalendarTime {
+    let mut result = CalendarTime::new();
+    // 计算对应的天数
+    let mut days = totalsecs / SECS_PER_DAY;
+    // 一天中剩余的秒数
+    let mut rem = totalsecs % SECS_PER_DAY;
+
+    // 加入偏移量
+    rem += offset as i64;
+    while rem < 0 {
+        rem += SECS_PER_DAY;
+        days -= 1;
+    }
+    while rem >= SECS_PER_DAY {
+        rem -= SECS_PER_DAY;
+        days += 1;
+    }
+    // 计算对应的小时数
+    result.tm_hour = (rem / SECS_PER_HOUR) as i32;
+    rem = rem % SECS_PER_HOUR;
+
+    // 计算对应的分钟数
+    result.tm_min = (rem / 60) as i32;
+    rem = rem % 60;
+
+    // 秒数
+    result.tm_sec = rem as i32;
+
+    // totalsec是从1970年1月1日 00:00:00 UTC到现在的秒数
+    // 当时是星期四
+    result.tm_wday = ((4 + days) % 7) as i32;
+
+    let mut year = 1970;
+    while days < 0 || (is_leap(year) && days >= 366) || (!is_leap(year) && days >= 365) {
+        // 假设每一年都是365天,计算出大概的年份
+        let guess_year = year + math_div(days.try_into().unwrap(), 365);
+        // 将已经计算过的天数去掉
+        days -= ((guess_year - year) * 365 + leaps_between(year, guess_year)) as i64;
+        year = guess_year;
+    }
+    result.tm_year = (year - 1900) as i32;
+    result.tm_yday = days as i32;
+    let mut il = 0;
+    if is_leap(year) {
+        il = 1
+    };
+    let mut mon = 0;
+    for i in MON_OF_YDAY[il] {
+        if days < i {
+            break;
+        }
+        mon += 1;
+    }
+    days -= MON_OF_YDAY[il][mon - 1];
+    result.tm_mon = (mon - 1) as i32;
+    result.tm_mday = (days + 1) as i32;
+
+    result
+}

+ 3 - 0
kernel/src/time/timekeeping.h

@@ -0,0 +1,3 @@
+#pragma once
+
+extern void rs_timekeeping_init();

+ 312 - 0
kernel/src/time/timekeeping.rs

@@ -0,0 +1,312 @@
+use alloc::sync::Arc;
+use core::sync::atomic::{compiler_fence, AtomicBool, AtomicI64, Ordering};
+use x86_64::align_up;
+
+use crate::{
+    arch::CurrentIrqArch,
+    exception::InterruptArch,
+    kdebug,
+    libs::rwlock::RwLock,
+    time::{jiffies::clocksource_default_clock, timekeep::ktime_get_real_ns, TimeSpec},
+};
+
+use super::{
+    clocksource::{clocksource_cyc2ns, Clocksource, CycleNum, HZ},
+    syscall::PosixTimeval,
+    NSEC_PER_SEC, USEC_PER_SEC,
+};
+/// NTP周期频率
+pub const NTP_INTERVAL_FREQ: u64 = HZ;
+/// NTP周期长度
+pub const NTP_INTERVAL_LENGTH: u64 = NSEC_PER_SEC as u64 / NTP_INTERVAL_FREQ;
+/// NTP转换比例
+pub const NTP_SCALE_SHIFT: u32 = 32;
+
+/// timekeeping休眠标志,false为未休眠
+pub static TIMEKEEPING_SUSPENDED: AtomicBool = AtomicBool::new(false);
+/// 已经递增的微秒数
+static __ADDED_USEC: AtomicI64 = AtomicI64::new(0);
+/// 已经递增的秒数
+static __ADDED_SEC: AtomicI64 = AtomicI64::new(0);
+/// timekeeper全局变量,用于管理timekeeper模块
+static mut __TIMEKEEPER: Option<Timekeeper> = None;
+
+#[derive(Debug)]
+pub struct Timekeeper(RwLock<TimekeeperData>);
+
+#[allow(dead_code)]
+#[derive(Debug)]
+pub struct TimekeeperData {
+    /// 用于计时的当前时钟源。
+    clock: Option<Arc<dyn Clocksource>>,
+    /// 当前时钟源的移位值。
+    shift: i32,
+    /// 一个NTP间隔中的时钟周期数。
+    cycle_interval: CycleNum,
+    /// 一个NTP间隔中时钟移位的纳秒数。
+    xtime_interval: u64,
+    ///
+    xtime_remainder: i64,
+    /// 每个NTP间隔累积的原始纳米秒
+    raw_interval: i64,
+    /// 时钟移位纳米秒余数
+    xtime_nsec: u64,
+    /// 积累时间和ntp时间在ntp位移纳秒量上的差距
+    ntp_error: i64,
+    /// 用于转换时钟偏移纳秒和ntp偏移纳秒的偏移量
+    ntp_error_shift: i32,
+    /// NTP调整时钟乘法器
+    mult: u32,
+    raw_time: TimeSpec,
+    wall_to_monotonic: TimeSpec,
+    total_sleep_time: TimeSpec,
+    xtime: TimeSpec,
+}
+impl TimekeeperData {
+    pub fn new() -> Self {
+        Self {
+            clock: None,
+            shift: Default::default(),
+            cycle_interval: CycleNum(0),
+            xtime_interval: Default::default(),
+            xtime_remainder: Default::default(),
+            raw_interval: Default::default(),
+            xtime_nsec: Default::default(),
+            ntp_error: Default::default(),
+            ntp_error_shift: Default::default(),
+            mult: Default::default(),
+            xtime: TimeSpec {
+                tv_nsec: 0,
+                tv_sec: 0,
+            },
+            wall_to_monotonic: TimeSpec {
+                tv_nsec: 0,
+                tv_sec: 0,
+            },
+            total_sleep_time: TimeSpec {
+                tv_nsec: 0,
+                tv_sec: 0,
+            },
+            raw_time: TimeSpec {
+                tv_nsec: 0,
+                tv_sec: 0,
+            },
+        }
+    }
+}
+impl Timekeeper {
+    /// # 设置timekeeper的参数
+    ///
+    /// ## 参数
+    ///
+    /// * 'clock' - 指定的时钟实际类型。初始为ClocksourceJiffies
+    pub fn timekeeper_setup_internals(&self, clock: Arc<dyn Clocksource>) {
+        let mut timekeeper = self.0.write();
+        // 更新clock
+        let mut clock_data = clock.clocksource_data();
+        clock_data.watchdog_last = clock.read();
+        if clock.update_clocksource_data(clock_data).is_err() {
+            kdebug!("timekeeper_setup_internals:update_clocksource_data run failed");
+        }
+        timekeeper.clock.replace(clock.clone());
+
+        let clock_data = clock.clocksource_data();
+        let mut temp = NTP_INTERVAL_LENGTH << clock_data.shift;
+        let ntpinterval = temp;
+        temp += (clock_data.mult / 2) as u64;
+        // do div
+
+        timekeeper.cycle_interval = CycleNum(temp);
+        timekeeper.xtime_interval = temp * clock_data.mult as u64;
+        timekeeper.xtime_remainder = (ntpinterval - timekeeper.xtime_interval) as i64;
+        timekeeper.raw_interval = (timekeeper.xtime_interval >> clock_data.shift) as i64;
+        timekeeper.xtime_nsec = 0;
+        timekeeper.shift = clock_data.shift as i32;
+
+        timekeeper.ntp_error = 0;
+        timekeeper.ntp_error_shift = (NTP_SCALE_SHIFT - clock_data.shift) as i32;
+
+        timekeeper.mult = clock_data.mult;
+    }
+
+    /// # 获取当前时钟源距离上次检测走过的纳秒数
+    #[allow(dead_code)]
+    pub fn tk_get_ns(&self) -> u64 {
+        let timekeeper = self.0.read();
+        let clock = timekeeper.clock.clone().unwrap();
+        let clock_now = clock.read();
+        let clcok_data = clock.clocksource_data();
+        let clock_delta = clock_now.div(clcok_data.watchdog_last).data() & clcok_data.mask.bits();
+        return clocksource_cyc2ns(CycleNum(clock_delta), clcok_data.mult, clcok_data.shift);
+    }
+}
+pub fn timekeeper() -> &'static Timekeeper {
+    return unsafe { __TIMEKEEPER.as_ref().unwrap() };
+}
+
+pub fn timekeeper_init() {
+    unsafe { __TIMEKEEPER = Some(Timekeeper(RwLock::new(TimekeeperData::new()))) };
+}
+
+/// # 获取1970.1.1至今的UTC时间戳(最小单位:nsec)
+///
+/// ## 返回值
+///
+/// * 'TimeSpec' - 时间戳
+pub fn getnstimeofday() -> TimeSpec {
+    kdebug!("enter getnstimeofday");
+
+    // let mut nsecs: u64 = 0;0
+    let mut _xtime = TimeSpec {
+        tv_nsec: 0,
+        tv_sec: 0,
+    };
+    loop {
+        match timekeeper().0.try_read() {
+            None => continue,
+            Some(tk) => {
+                _xtime = tk.xtime;
+                drop(tk);
+                // nsecs = timekeeper().tk_get_ns();
+                // TODO 不同架构可能需要加上不同的偏移量
+                break;
+            }
+        }
+    }
+    // xtime.tv_nsec += nsecs as i64;
+    let sec = __ADDED_SEC.load(Ordering::SeqCst);
+    _xtime.tv_sec += sec;
+    while _xtime.tv_nsec >= NSEC_PER_SEC.into() {
+        _xtime.tv_nsec -= NSEC_PER_SEC as i64;
+        _xtime.tv_sec += 1;
+    }
+
+    // TODO 将xtime和当前时间源的时间相加
+
+    return _xtime;
+}
+
+/// # 获取1970.1.1至今的UTC时间戳(最小单位:usec)
+///
+/// ## 返回值
+///
+/// * 'PosixTimeval' - 时间戳
+pub fn do_gettimeofday() -> PosixTimeval {
+    let tp = getnstimeofday();
+    return PosixTimeval {
+        tv_sec: tp.tv_sec,
+        tv_usec: (tp.tv_nsec / 1000) as i32,
+    };
+}
+
+/// # 初始化timekeeping模块
+pub fn timekeeping_init() {
+    let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
+    timekeeper_init();
+
+    // TODO 有ntp模块后 在此初始化ntp模块
+
+    let clock = clocksource_default_clock();
+    clock
+        .enable()
+        .expect("clocksource_default_clock enable failed");
+    timekeeper().timekeeper_setup_internals(clock);
+    // 暂时不支持其他架构平台对时间的设置 所以使用x86平台对应值初始化
+    let mut timekeeper = timekeeper().0.write();
+    timekeeper.xtime.tv_nsec = ktime_get_real_ns();
+
+    // 初始化wall time到monotonic的时间
+    let mut nsec = -timekeeper.xtime.tv_nsec;
+    let mut sec = -timekeeper.xtime.tv_sec;
+    // FIXME: 这里有个奇怪的奇怪的bug
+    let num = nsec % NSEC_PER_SEC as i64;
+    nsec += num * NSEC_PER_SEC as i64;
+    sec -= num;
+    timekeeper.wall_to_monotonic.tv_nsec = nsec;
+    timekeeper.wall_to_monotonic.tv_sec = sec;
+
+    __ADDED_USEC.store(0, Ordering::SeqCst);
+    __ADDED_SEC.store(0, Ordering::SeqCst);
+
+    drop(irq_guard);
+    kdebug!("timekeeping_init successfully");
+}
+
+/// # 使用当前时钟源增加wall time
+pub fn update_wall_time() {
+    let rsp = unsafe { crate::include::bindings::bindings::get_rsp() } as usize;
+    let _stack_use = align_up(rsp as u64, 32768) - rsp as u64;
+
+    // kdebug!("enter update_wall_time, stack_use = {:}",stack_use);
+    compiler_fence(Ordering::SeqCst);
+    let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
+    // 如果在休眠那就不更新
+    if TIMEKEEPING_SUSPENDED.load(Ordering::SeqCst) {
+        return;
+    }
+
+    // ===== 请不要删除这些注释 =====
+    // let clock = timekeeper.clock.clone().unwrap();
+    // let clock_data = clock.clocksource_data();
+    // let offset = (clock.read().div(clock_data.watchdog_last).data()) & clock_data.mask.bits();
+
+    // timekeeper.xtime_nsec = (timekeeper.xtime.tv_nsec as u64) << timekeeper.shift;
+    // // TODO 当有ntp模块之后 需要将timekeep与ntp进行同步并检查
+    // timekeeper.xtime.tv_nsec = ((timekeeper.xtime_nsec as i64) >> timekeeper.shift) + 1;
+    // timekeeper.xtime_nsec -= (timekeeper.xtime.tv_nsec as u64) << timekeeper.shift;
+
+    // timekeeper.xtime.tv_nsec += offset as i64;
+    // while unlikely(timekeeper.xtime.tv_nsec >= NSEC_PER_SEC.into()) {
+    //     timekeeper.xtime.tv_nsec -= NSEC_PER_SEC as i64;
+    //     timekeeper.xtime.tv_sec += 1;
+    //     // TODO 需要处理闰秒
+    // }
+    // ================
+    compiler_fence(Ordering::SeqCst);
+    // 一分钟同步一次
+    __ADDED_USEC.fetch_add(500, Ordering::SeqCst);
+    compiler_fence(Ordering::SeqCst);
+    let mut retry = 10;
+
+    let usec = __ADDED_USEC.load(Ordering::SeqCst);
+    if usec % USEC_PER_SEC as i64 == 0 {
+        compiler_fence(Ordering::SeqCst);
+
+        __ADDED_SEC.fetch_add(1, Ordering::SeqCst);
+        compiler_fence(Ordering::SeqCst);
+    }
+    loop {
+        if (usec & !((1 << 26) - 1)) != 0 {
+            if __ADDED_USEC
+                .compare_exchange(usec, 0, Ordering::SeqCst, Ordering::SeqCst)
+                .is_ok()
+                || retry == 0
+            {
+                // 同步时间
+                // 我感觉这里会出问题:多个读者不退出的话,写者就无法写入
+                // 然后这里会超时,导致在中断返回之后,会不断的进入这个中断,最终爆栈。
+                let mut timekeeper = timekeeper().0.write();
+                timekeeper.xtime.tv_nsec = ktime_get_real_ns();
+                timekeeper.xtime.tv_sec = 0;
+                __ADDED_SEC.store(0, Ordering::SeqCst);
+                drop(timekeeper);
+                break;
+            }
+            retry -= 1;
+        } else {
+            break;
+        }
+    }
+    // TODO 需要检查是否更新时间源
+    compiler_fence(Ordering::SeqCst);
+    drop(irq_guard);
+    compiler_fence(Ordering::SeqCst);
+}
+// TODO timekeeping_adjust
+// TODO wall_to_monotic
+
+// ========= 以下为对C的接口 =========
+#[no_mangle]
+pub extern "C" fn rs_timekeeping_init() {
+    timekeeping_init();
+}

+ 1 - 0
kernel/src/time/timer.h

@@ -2,6 +2,7 @@
 
 #include <common/glib.h>
 #include <driver/timers/HPET/HPET.h>
+#include <common/kthread.h>
 
 // 定义LONG_MAX为最大超时时间 - 允许负数
 #define MAX_TIMEOUT (int64_t)((1ul << 63) - 1)

+ 45 - 26
kernel/src/time/timer.rs

@@ -1,4 +1,8 @@
-use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
+use core::{
+    fmt::Debug,
+    intrinsics::unlikely,
+    sync::atomic::{compiler_fence, AtomicBool, AtomicU64, Ordering},
+};
 
 use alloc::{
     boxed::Box,
@@ -7,31 +11,33 @@ use alloc::{
 };
 
 use crate::{
-    arch::{
-        asm::current::current_pcb,
-        interrupt::{cli, sti},
-        sched::sched,
+    arch::{asm::current::current_pcb, sched::sched, CurrentIrqArch},
+    exception::{
+        softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
+        InterruptArch,
     },
-    exception::softirq::{softirq_vectors, SoftirqNumber, SoftirqVec},
-    include::bindings::bindings::{process_control_block, process_wakeup, pt_regs, PROC_RUNNING},
+    include::bindings::bindings::{process_control_block, process_wakeup, PROC_RUNNING},
     kdebug, kerror,
     libs::spinlock::SpinLock,
     syscall::SystemError,
 };
 
+use super::timekeeping::update_wall_time;
+
 const MAX_TIMEOUT: i64 = i64::MAX;
 const TIMER_RUN_CYCLE_THRESHOLD: usize = 20;
-static mut TIMER_JIFFIES: u64 = 0;
+static TIMER_JIFFIES: AtomicU64 = AtomicU64::new(0);
 
 lazy_static! {
     pub static ref TIMER_LIST: SpinLock<LinkedList<Arc<Timer>>> = SpinLock::new(LinkedList::new());
 }
 
 /// 定时器要执行的函数的特征
-pub trait TimerFunction: Send + Sync {
-    fn run(&mut self);
+pub trait TimerFunction: Send + Sync + Debug {
+    fn run(&mut self) -> Result<(), SystemError>;
 }
 
+#[derive(Debug)]
 /// WakeUpHelper函数对应的结构体
 pub struct WakeUpHelper {
     pcb: &'static mut process_control_block,
@@ -44,13 +50,15 @@ impl WakeUpHelper {
 }
 
 impl TimerFunction for WakeUpHelper {
-    fn run(&mut self) {
+    fn run(&mut self) -> Result<(), SystemError> {
         unsafe {
             process_wakeup(self.pcb);
         }
+        return Ok(());
     }
 }
 
+#[derive(Debug)]
 pub struct Timer(SpinLock<InnerTimer>);
 
 impl Timer {
@@ -97,6 +105,7 @@ impl Timer {
                 break;
             }
         }
+
         let mut temp_list: LinkedList<Arc<Timer>> = timer_list.split_off(split_pos);
         timer_list.push_back(inner_guard.self_ref.upgrade().unwrap());
         timer_list.append(&mut temp_list);
@@ -106,11 +115,18 @@ impl Timer {
 
     #[inline]
     fn run(&self) {
-        self.0.lock().timer_func.run();
+        let r = self.0.lock().timer_func.run();
+        if unlikely(r.is_err()) {
+            kerror!(
+                "Failed to run timer function: {self:?} {:?}",
+                r.err().unwrap()
+            );
+        }
     }
 }
 
 /// 定时器类型
+#[derive(Debug)]
 pub struct InnerTimer {
     /// 定时器结束时刻
     pub expire_jiffies: u64,
@@ -179,7 +195,7 @@ impl SoftirqVec for DoTimerSoftirq {
                 continue;
             }
             let timer_list_front_guard = timer_list_front_guard.unwrap();
-            if timer_list_front_guard.expire_jiffies > unsafe { TIMER_JIFFIES as u64 } {
+            if timer_list_front_guard.expire_jiffies > TIMER_JIFFIES.load(Ordering::SeqCst) {
                 drop(timer_list_front_guard);
                 timer_list.push_front(timer_list_front);
                 break;
@@ -205,11 +221,11 @@ pub fn timer_init() {
 
 /// 计算接下来n毫秒对应的定时器时间片
 pub fn next_n_ms_timer_jiffies(expire_ms: u64) -> u64 {
-    return unsafe { TIMER_JIFFIES as u64 } + 1000 * (expire_ms);
+    return TIMER_JIFFIES.load(Ordering::SeqCst) + 1000 * (expire_ms);
 }
 /// 计算接下来n微秒对应的定时器时间片
 pub fn next_n_us_timer_jiffies(expire_us: u64) -> u64 {
-    return unsafe { TIMER_JIFFIES as u64 } + (expire_us);
+    return TIMER_JIFFIES.load(Ordering::SeqCst) + (expire_us);
 }
 
 /// @brief 让pcb休眠timeout个jiffies
@@ -229,15 +245,17 @@ pub fn schedule_timeout(mut timeout: i64) -> Result<i64, SystemError> {
         return Err(SystemError::EINVAL);
     } else {
         // 禁用中断,防止在这段期间发生调度,造成死锁
-        cli();
-        timeout += unsafe { TIMER_JIFFIES } as i64;
+        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
+
+        timeout += TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
         let timer = Timer::new(WakeUpHelper::new(current_pcb()), timeout as u64);
         timer.activate();
         current_pcb().state &= (!PROC_RUNNING) as u64;
-        sti();
+
+        drop(irq_guard);
 
         sched();
-        let time_remaining: i64 = timeout - unsafe { TIMER_JIFFIES } as i64;
+        let time_remaining: i64 = timeout - TIMER_JIFFIES.load(Ordering::SeqCst) as i64;
         if time_remaining >= 0 {
             // 被提前唤醒,返回剩余时间
             return Ok(time_remaining);
@@ -270,21 +288,22 @@ pub fn timer_get_first_expire() -> Result<u64, SystemError> {
 }
 
 pub fn update_timer_jiffies(add_jiffies: u64) -> u64 {
-    unsafe { TIMER_JIFFIES += add_jiffies };
-    return unsafe { TIMER_JIFFIES };
+    let prev = TIMER_JIFFIES.fetch_add(add_jiffies, Ordering::SeqCst);
+    compiler_fence(Ordering::SeqCst);
+    update_wall_time();
+
+    compiler_fence(Ordering::SeqCst);
+    return prev + add_jiffies;
 }
+
 pub fn clock() -> u64 {
-    return unsafe { TIMER_JIFFIES };
+    return TIMER_JIFFIES.load(Ordering::SeqCst);
 }
 // ====== 重构完成后请删掉extern C ======
 #[no_mangle]
 pub extern "C" fn rs_clock() -> u64 {
     clock()
 }
-#[no_mangle]
-pub extern "C" fn sys_clock(_regs: *const pt_regs) -> u64 {
-    clock()
-}
 
 // ====== 以下为给C提供的接口 ======
 #[no_mangle]

+ 25 - 0
user/apps/test_gettimeofday/Makefile

@@ -0,0 +1,25 @@
+CC=$(DragonOS_GCC)/x86_64-elf-gcc
+LD=ld
+OBJCOPY=objcopy
+# 修改这里,把它改为你的relibc的sysroot路径
+RELIBC_OPT=$(DADK_BUILD_CACHE_DIR_RELIBC_0_1_0)
+CFLAGS=-I $(RELIBC_OPT)/include
+
+tmp_output_dir=$(ROOT_PATH)/bin/tmp/user
+output_dir=$(DADK_BUILD_CACHE_DIR_TEST_GETTIMEOFDAY_0_1_0)
+
+LIBC_OBJS:=$(shell find $(RELIBC_OPT)/lib -name "*.o" | sort )
+LIBC_OBJS+=$(RELIBC_OPT)/lib/libc.a
+
+all: main.o
+	mkdir -p $(tmp_output_dir)
+	
+	$(LD) -b elf64-x86-64 -z muldefs -o $(tmp_output_dir)/test_gettimeofday  $(shell find . -name "*.o") $(LIBC_OBJS) -T link.lds
+
+	$(OBJCOPY) -I elf64-x86-64 -R ".eh_frame" -R ".comment" -O elf64-x86-64 $(tmp_output_dir)/test_gettimeofday $(output_dir)/test_gettimeofday.elf
+	mv $(output_dir)/test_gettimeofday.elf $(output_dir)/test_gettimeofday
+main.o: main.c
+	$(CC) $(CFLAGS) -c main.c  -o main.o
+
+clean:
+	rm -f *.o

+ 239 - 0
user/apps/test_gettimeofday/link.lds

@@ -0,0 +1,239 @@
+/* Script for -z combreloc */
+/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
+   Copying and distribution of this script, with or without modification,
+   are permitted in any medium without royalty provided the copyright
+   notice and this notice are preserved.  */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
+              "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
+  .interp         : { *(.interp) }
+  .note.gnu.build-id  : { *(.note.gnu.build-id) }
+  .hash           : { *(.hash) }
+  .gnu.hash       : { *(.gnu.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rela.dyn       :
+    {
+      *(.rela.init)
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+      *(.rela.fini)
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+      *(.rela.ctors)
+      *(.rela.dtors)
+      *(.rela.got)
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+      *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
+      *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
+      *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
+      *(.rela.ifunc)
+    }
+  .rela.plt       :
+    {
+      *(.rela.plt)
+      PROVIDE_HIDDEN (__rela_iplt_start = .);
+      *(.rela.iplt)
+      PROVIDE_HIDDEN (__rela_iplt_end = .);
+    }
+  . = ALIGN(CONSTANT (MAXPAGESIZE));
+  .init           :
+  {
+    KEEP (*(SORT_NONE(.init)))
+  }
+  .plt            : { *(.plt) *(.iplt) }
+.plt.got        : { *(.plt.got) }
+.plt.sec        : { *(.plt.sec) }
+  .text           :
+  {
+    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
+    *(.text.exit .text.exit.*)
+    *(.text.startup .text.startup.*)
+    *(.text.hot .text.hot.*)
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf.em.  */
+    *(.gnu.warning)
+  }
+  .fini           :
+  {
+    KEEP (*(SORT_NONE(.fini)))
+  }
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  . = ALIGN(CONSTANT (MAXPAGESIZE));
+  /* Adjust the address for the rodata segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  .eh_frame_hdr   : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+  .gnu_extab   : ONLY_IF_RO { *(.gnu_extab*) }
+  /* These sections are generated by the Sun/Oracle C++ compiler.  */
+  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
+  /* Exception handling  */
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
+  .gnu_extab      : ONLY_IF_RW { *(.gnu_extab) }
+  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges*) }
+  /* Thread Local Storage sections  */
+  .tdata          :
+   {
+     PROVIDE_HIDDEN (__tdata_start = .);
+     *(.tdata .tdata.* .gnu.linkonce.td.*)
+   }
+  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .preinit_array    :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  }
+  .init_array    :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  }
+  .fini_array    :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  }
+  .ctors          :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*crtbegin?.o(.ctors))
+    /* We don't want to include the .ctor section from
+       the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*crtbegin?.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got) *(.igot) }
+  . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
+  .got.plt        : { *(.got.plt) *(.igot.plt) }
+  .data           :
+  {
+    *(.data .data.* .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  _edata = .; PROVIDE (edata = .);
+  . = .;
+  __bss_start = .;
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.
+      FIXME: Why do we need it? When there is no .bss section, we do not
+      pad the .data section.  */
+   . = ALIGN(. != 0 ? 64 / 8 : 1);
+  }
+  .lbss   :
+  {
+    *(.dynlbss)
+    *(.lbss .lbss.* .gnu.linkonce.lb.*)
+    *(LARGE_COMMON)
+  }
+  . = ALIGN(64 / 8);
+  . = SEGMENT_START("ldata-segment", .);
+  .lrodata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
+  {
+    *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
+  }
+  .ldata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
+  {
+    *(.ldata .ldata.* .gnu.linkonce.l.*)
+    . = ALIGN(. != 0 ? 64 / 8 : 1);
+  }
+  . = ALIGN(64 / 8);
+  _end = .; PROVIDE (end = .);
+  . = DATA_SEGMENT_END (.);
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+  /* DWARF Extension.  */
+  .debug_macro    0 : { *(.debug_macro) }
+  .debug_addr     0 : { *(.debug_addr) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}

+ 25 - 0
user/apps/test_gettimeofday/main.c

@@ -0,0 +1,25 @@
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+// #include <sleep.h>
+#include <unistd.h>
+#include <time.h>
+
+int main()
+{
+    struct timeval *tv = malloc(sizeof(struct timeval));
+    // struct timezone *tz = malloc(sizeof(struct timezone));
+    // for (int i = 0; i < 15; i++)
+    // {
+    //     gettimeofday(tv, NULL);
+    //     printf("%ld.%06ld\n", tv->tv_sec, tv->tv_usec);
+    //     for (int i = 0; i < 10; i++)
+    //     {
+    //         usleep(500000);
+    //     }
+    // }
+    gettimeofday(tv, NULL);
+    printf("tv = %ld.%06ld\n", tv->tv_sec, tv->tv_usec);
+    // printf("tz_minuteswest = %d,tz_dsttime = %d", (*tz).tz_minuteswest, (*tz).tz_dsttime);
+    return 0;
+}

+ 1 - 1
user/dadk/config/relibc-0.1.0.dadk

@@ -27,4 +27,4 @@
       "value": "x86_64-unknown-dragonos"
     }
   ]
-}
+}

+ 28 - 0
user/dadk/config/test_gettimeofday-0.1.0.dadk

@@ -0,0 +1,28 @@
+{
+  "name": "test_gettimeofday",
+  "version": "0.1.0",
+  "description": "一个用来测试gettimeofday能够正常运行的app",
+  "task_type": {
+    "BuildFromSource": {
+      "Local": {
+        "path": "apps/test_gettimeofday"
+      }
+    }
+  },
+  "depends": [
+    {
+      "name": "relibc",
+      "version": "0.1.0"
+    }
+  ],
+  "build": {
+    "build_command": "make"
+  },
+  "install": {
+    "in_dragonos_path": "/bin"
+  },
+  "clean": {
+    "clean_command": "make clean"
+  },
+  "envs": []
+}