Browse Source

实现了rtc的抽象,并且把x86的cmos rtc接入到设备驱动模型 (#674)

* 实现了rtc的抽象,并且把x86的cmos rtc接入到设备驱动模型。
LoGin 11 months ago
parent
commit
da15231979

+ 1 - 0
kernel/Cargo.toml

@@ -31,6 +31,7 @@ bit_field = "=0.10"
 bitfield-struct = "=0.5.3"
 bitflags = "=1.3.2"
 bitmap = { path = "crates/bitmap" }
+driver_base_macros = { "path" = "crates/driver_base_macros" }
 # 一个no_std的hashmap、hashset
 elf = { version = "=0.7.2", default-features = false }
 hashbrown = "=0.13.2"

+ 8 - 0
kernel/crates/driver_base_macros/Cargo.toml

@@ -0,0 +1,8 @@
+[package]
+name = "driver_base_macros"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]

+ 20 - 0
kernel/crates/driver_base_macros/src/lib.rs

@@ -0,0 +1,20 @@
+#![no_std]
+
+/// 获取指定字段
+///
+/// 当weak指针的strong count为0的时候,清除弱引用
+#[macro_export]
+macro_rules! get_weak_or_clear {
+    ($field:expr) => {{
+        if let Some(x) = $field.clone() {
+            if x.strong_count() == 0 {
+                $field = None;
+                None
+            } else {
+                Some(x)
+            }
+        } else {
+            None
+        }
+    }};
+}

+ 1 - 0
kernel/src/arch/x86_64/driver/mod.rs

@@ -1,4 +1,5 @@
 pub mod apic;
 pub mod hpet;
+pub mod rtc;
 pub mod tsc;
 pub mod video;

+ 312 - 0
kernel/src/arch/x86_64/driver/rtc.rs

@@ -0,0 +1,312 @@
+use core::any::Any;
+
+use alloc::{
+    string::{String, ToString},
+    sync::{Arc, Weak},
+};
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use crate::{
+    arch::{io::PortIOArch, CurrentIrqArch, CurrentPortIOArch},
+    driver::{
+        base::{
+            class::Class,
+            device::{
+                bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceState,
+                DeviceType, IdTable,
+            },
+            kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
+            kset::KSet,
+            platform::platform_device::{platform_device_manager, PlatformDevice},
+        },
+        rtc::{RtcClassOps, RtcDevice, RtcTime},
+    },
+    exception::InterruptArch,
+    filesystem::kernfs::KernFSInode,
+    init::initcall::INITCALL_DEVICE,
+    kerror,
+    libs::{
+        mutex::Mutex,
+        rwlock::{RwLockReadGuard, RwLockWriteGuard},
+        spinlock::{SpinLock, SpinLockGuard},
+    },
+};
+
+#[derive(Debug)]
+#[cast_to([sync] Device, PlatformDevice, RtcDevice)]
+struct CmosRtcDevice {
+    inner: SpinLock<InnerCmosRtc>,
+    locked_kobjstate: LockedKObjectState,
+    ops_mutex: Mutex<()>,
+}
+
+impl CmosRtcDevice {
+    const NAME: &str = "rtc_cmos";
+    pub fn new() -> Arc<Self> {
+        let r = CmosRtcDevice {
+            inner: SpinLock::new(InnerCmosRtc {
+                device_common: DeviceCommonData::default(),
+                kobject_common: KObjectCommonData::default(),
+                device_state: DeviceState::NotInitialized,
+            }),
+            locked_kobjstate: LockedKObjectState::new(None),
+            ops_mutex: Mutex::new(()),
+        };
+
+        r.inner().device_common.can_match = true;
+
+        Arc::new(r)
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerCmosRtc> {
+        self.inner.lock()
+    }
+
+    ///置位0x70的第7位,禁止不可屏蔽中断
+    #[inline]
+    fn read_cmos(&self, addr: u8) -> u8 {
+        unsafe {
+            CurrentPortIOArch::out8(0x70, 0x80 | addr);
+            return CurrentPortIOArch::in8(0x71);
+        }
+    }
+}
+
+#[derive(Debug)]
+struct InnerCmosRtc {
+    device_common: DeviceCommonData,
+    kobject_common: KObjectCommonData,
+
+    device_state: DeviceState,
+}
+
+impl RtcDevice for CmosRtcDevice {
+    fn class_ops(&self) -> &'static dyn RtcClassOps {
+        &CmosRtcClassOps
+    }
+}
+
+impl PlatformDevice for CmosRtcDevice {
+    fn pdev_name(&self) -> &str {
+        Self::NAME
+    }
+
+    fn set_pdev_id(&self, _id: i32) {
+        todo!()
+    }
+
+    fn set_pdev_id_auto(&self, _id_auto: bool) {
+        todo!()
+    }
+
+    fn is_initialized(&self) -> bool {
+        self.inner().device_state == DeviceState::Initialized
+    }
+
+    fn set_state(&self, set_state: DeviceState) {
+        self.inner().device_state = set_state;
+    }
+}
+
+impl Device for CmosRtcDevice {
+    fn dev_type(&self) -> DeviceType {
+        DeviceType::Rtc
+    }
+
+    fn id_table(&self) -> IdTable {
+        IdTable::new(Self::NAME.to_string(), None)
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner().device_common.bus = bus;
+    }
+
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
+        self.inner().device_common.class = class;
+    }
+
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        self.inner()
+            .device_common
+            .get_class_weak_or_clear()
+            .and_then(|c| c.upgrade())
+    }
+
+    fn driver(&self) -> Option<Arc<dyn Driver>> {
+        self.inner()
+            .device_common
+            .get_driver_weak_or_clear()
+            .and_then(|d| d.upgrade())
+    }
+
+    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
+        self.inner().device_common.driver = driver;
+    }
+
+    fn is_dead(&self) -> bool {
+        self.inner().device_common.dead
+    }
+
+    fn can_match(&self) -> bool {
+        self.inner().device_common.can_match
+    }
+
+    fn set_can_match(&self, can_match: bool) {
+        self.inner().device_common.can_match = can_match;
+    }
+
+    fn state_synced(&self) -> bool {
+        true
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner().device_common.get_bus_weak_or_clear()
+    }
+}
+
+impl KObject for CmosRtcDevice {
+    fn as_any_ref(&self) -> &dyn Any {
+        self
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner().kobject_common.kern_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner().kobject_common.kern_inode.clone()
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner().kobject_common.get_parent_or_clear_weak()
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner().kobject_common.parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner().kobject_common.kset.clone()
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner().kobject_common.kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner().kobject_common.kobj_type
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobject_common.kobj_type = ktype;
+    }
+
+    fn name(&self) -> String {
+        Self::NAME.to_string()
+    }
+
+    fn set_name(&self, _name: String) {
+        // Do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.locked_kobjstate.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.locked_kobjstate.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.locked_kobjstate.write() = state;
+    }
+}
+
+#[derive(Debug)]
+pub struct CmosRtcClassOps;
+
+impl RtcClassOps for CmosRtcClassOps {
+    fn read_time(&self, dev: &Arc<dyn RtcDevice>) -> Result<RtcTime, SystemError> {
+        // 检查是否为cmos rtc
+        let dev = dev
+            .as_any_ref()
+            .downcast_ref::<CmosRtcDevice>()
+            .ok_or(SystemError::EINVAL)?;
+
+        let _guard = dev.ops_mutex.lock();
+
+        // 为防止中断请求打断该过程,需要先关中断
+        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
+        //0x0B
+        let status_register_b: u8 = dev.read_cmos(0x0B); // 读取状态寄存器B
+        let is_24h: bool = (status_register_b & 0x02) != 0;
+        // 判断是否启用24小时模式
+        let is_binary: bool = (status_register_b & 0x04) != 0; // 判断是否为二进制码
+        let mut res = RtcTime::default();
+
+        loop {
+            res.year = dev.read_cmos(CMOSTimeSelector::Year as u8) as i32;
+            res.month = dev.read_cmos(CMOSTimeSelector::Month as u8) as i32;
+            res.mday = dev.read_cmos(CMOSTimeSelector::Day as u8) as i32;
+            res.hour = dev.read_cmos(CMOSTimeSelector::Hour as u8) as i32;
+            res.minute = dev.read_cmos(CMOSTimeSelector::Minute as u8) as i32;
+            res.second = dev.read_cmos(CMOSTimeSelector::Second as u8) as i32;
+
+            if res.second == dev.read_cmos(CMOSTimeSelector::Second as u8) as i32 {
+                break;
+            } // 若读取时间过程中时间发生跳变则重新读取
+        }
+
+        unsafe {
+            CurrentPortIOArch::out8(0x70, 0x00);
+        }
+
+        if !is_binary
+        // 把BCD转为二进制
+        {
+            res.second = (res.second & 0xf) + (res.second >> 4) * 10;
+            res.minute = (res.minute & 0xf) + (res.minute >> 4) * 10;
+            res.hour = ((res.hour & 0xf) + ((res.hour & 0x70) >> 4) * 10) | (res.hour & 0x80);
+            res.mday = (res.mday & 0xf) + ((res.mday / 16) * 10);
+            res.month = (res.month & 0xf) + (res.month >> 4) * 10;
+            res.year = (res.year & 0xf) + (res.year >> 4) * 10;
+        }
+        res.year += 100;
+
+        if (!is_24h) && (res.hour & 0x80) != 0 {
+            res.hour = ((res.hour & 0x7f) + 12) % 24;
+        } // 将十二小时制转为24小时
+
+        res.month -= 1;
+
+        drop(irq_guard);
+
+        return Ok(res);
+    }
+
+    fn set_time(&self, _dev: &Arc<dyn RtcDevice>, _time: &RtcTime) -> Result<(), SystemError> {
+        kerror!("set_time is not implemented for CmosRtcClassOps");
+        Err(SystemError::ENOSYS)
+    }
+}
+
+/// used in the form of u8
+#[repr(u8)]
+enum CMOSTimeSelector {
+    Second = 0x00,
+    Minute = 0x02,
+    Hour = 0x04,
+    Day = 0x07,
+    Month = 0x08,
+    Year = 0x09,
+}
+
+#[unified_init(INITCALL_DEVICE)]
+pub fn cmos_rtc_device_init() -> Result<(), SystemError> {
+    let device = CmosRtcDevice::new();
+    device_manager().device_default_initialize(&(device.clone() as Arc<dyn Device>));
+    platform_device_manager().device_add(device)?;
+
+    return Ok(());
+}

+ 6 - 3
kernel/src/arch/x86_64/mm/mod.rs

@@ -404,10 +404,13 @@ impl VirtAddr {
 }
 
 unsafe fn allocator_init() {
-    let virt_offset = BOOTSTRAP_MM_INFO.unwrap().start_brk;
-    let phy_offset =
-        unsafe { MMArch::virt_2_phys(VirtAddr::new(page_align_up(virt_offset))) }.unwrap();
+    let virt_offset = VirtAddr::new(page_align_up(BOOTSTRAP_MM_INFO.unwrap().start_brk));
 
+    let phy_offset = unsafe { MMArch::virt_2_phys(virt_offset) }.unwrap();
+
+    mem_block_manager()
+        .reserve_block(PhysAddr::new(0), phy_offset.data())
+        .expect("Failed to reserve block");
     let mut bump_allocator = BumpAllocator::<X86_64MMArch>::new(phy_offset.data());
     kdebug!(
         "BumpAllocator created, offset={:?}",

+ 2 - 4
kernel/src/driver/base/device/dd.rs

@@ -277,16 +277,14 @@ impl DriverManager {
             .and_then(|bus| bus.upgrade())
             .ok_or(SystemError::EINVAL)?;
         for dev in bus.subsystem().devices().iter() {
-            if self.do_driver_attach(dev, driver) {
-                // 匹配成功
-                return Ok(());
-            }
+            self.do_driver_attach(dev, driver);
         }
 
         return Ok(());
     }
 
     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#1134
+    #[inline(never)]
     fn do_driver_attach(&self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>) -> bool {
         let r = self.match_device(driver, device).unwrap_or(false);
         if !r {

+ 18 - 0
kernel/src/driver/base/device/driver.rs

@@ -109,6 +109,24 @@ pub trait Driver: Sync + Send + Debug + KObject {
     }
 }
 
+#[derive(Debug, Default)]
+pub struct DriverCommonData {
+    pub devices: Vec<Arc<dyn Device>>,
+    pub bus: Option<Weak<dyn Bus>>,
+}
+
+impl DriverCommonData {
+    pub fn push_device(&mut self, device: Arc<dyn Device>) {
+        if !self.devices.iter().any(|d| Arc::ptr_eq(d, &device)) {
+            self.devices.push(device);
+        }
+    }
+
+    pub fn delete_device(&mut self, device: &Arc<dyn Device>) {
+        self.devices.retain(|d| !Arc::ptr_eq(d, device));
+    }
+}
+
 impl dyn Driver {
     pub fn allows_async_probing(&self) -> bool {
         match self.probe_type() {

+ 45 - 0
kernel/src/driver/base/device/mod.rs

@@ -201,6 +201,51 @@ impl dyn Device {
     }
 }
 
+/// 实现了Device trait的设备需要拥有的数据
+#[derive(Debug)]
+pub struct DeviceCommonData {
+    pub bus: Option<Weak<dyn Bus>>,
+    pub class: Option<Weak<dyn Class>>,
+    pub driver: Option<Weak<dyn Driver>>,
+    pub dead: bool,
+    pub can_match: bool,
+}
+
+impl Default for DeviceCommonData {
+    fn default() -> Self {
+        Self {
+            bus: None,
+            class: None,
+            driver: None,
+            dead: false,
+            can_match: true,
+        }
+    }
+}
+
+impl DeviceCommonData {
+    /// 获取bus字段
+    ///
+    /// 当weak指针的strong count为0的时候,清除弱引用
+    pub fn get_bus_weak_or_clear(&mut self) -> Option<Weak<dyn Bus>> {
+        driver_base_macros::get_weak_or_clear!(self.bus)
+    }
+
+    /// 获取class字段
+    ///
+    /// 当weak指针的strong count为0的时候,清除弱引用
+    pub fn get_class_weak_or_clear(&mut self) -> Option<Weak<dyn Class>> {
+        driver_base_macros::get_weak_or_clear!(self.class)
+    }
+
+    /// 获取driver字段
+    ///
+    /// 当weak指针的strong count为0的时候,清除弱引用
+    pub fn get_driver_weak_or_clear(&mut self) -> Option<Weak<dyn Driver>> {
+        driver_base_macros::get_weak_or_clear!(self.driver)
+    }
+}
+
 // 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息
 #[allow(dead_code)]
 #[derive(Debug, Clone)]

+ 16 - 0
kernel/src/driver/base/kobject.rs

@@ -4,6 +4,7 @@ use alloc::{
     string::String,
     sync::{Arc, Weak},
 };
+use driver_base_macros::get_weak_or_clear;
 use intertrait::CastFromSync;
 
 use crate::{
@@ -73,6 +74,21 @@ impl DowncastArc for dyn KObject {
     }
 }
 
+/// kobject的公共数据
+#[derive(Debug, Default)]
+pub struct KObjectCommonData {
+    pub kern_inode: Option<Arc<KernFSInode>>,
+    pub parent: Option<Weak<dyn KObject>>,
+    pub kset: Option<Arc<KSet>>,
+    pub kobj_type: Option<&'static dyn KObjType>,
+}
+
+impl KObjectCommonData {
+    pub fn get_parent_or_clear_weak(&mut self) -> Option<Weak<dyn KObject>> {
+        get_weak_or_clear!(self.parent)
+    }
+}
+
 pub trait KObjType: Debug + Send + Sync {
     /// 当指定的kobject被释放时,设备驱动模型会调用此方法
     fn release(&self, _kobj: Arc<dyn KObject>) {}

+ 0 - 1
kernel/src/driver/base/platform/platform_device.rs

@@ -61,7 +61,6 @@ pub trait PlatformDevice: Device {
     /// 设置id是否为自动分配
     fn set_pdev_id_auto(&self, id_auto: bool);
 
-    fn compatible_table(&self) -> CompatibleTable;
     /// @brief: 判断设备是否初始化
     /// @parameter: None
     /// @return: 如果已经初始化,返回true,否则,返回false

+ 1 - 5
kernel/src/driver/input/serio/i8042/i8042_device.rs

@@ -9,7 +9,7 @@ use crate::{
         device::{bus::Bus, driver::Driver, Device, DeviceState, DeviceType, IdTable},
         kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
         kset::KSet,
-        platform::{platform_device::PlatformDevice, CompatibleTable},
+        platform::platform_device::PlatformDevice,
     },
     filesystem::kernfs::KernFSInode,
     libs::{
@@ -184,10 +184,6 @@ impl PlatformDevice for I8042PlatformDevice {
         self.inner.lock().pdev_id_auto = id_auto;
     }
 
-    fn compatible_table(&self) -> CompatibleTable {
-        todo!()
-    }
-
     fn is_initialized(&self) -> bool {
         self.inner.lock().device_state == DeviceState::Initialized
     }

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

@@ -8,6 +8,7 @@ pub mod keyboard;
 pub mod net;
 pub mod open_firmware;
 pub mod pci;
+pub mod rtc;
 pub mod serial;
 pub mod timers;
 pub mod tty;

+ 109 - 0
kernel/src/driver/rtc/class.rs

@@ -0,0 +1,109 @@
+use alloc::{
+    string::ToString,
+    sync::{Arc, Weak},
+};
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use crate::{
+    driver::base::{
+        class::{class_manager, Class},
+        device::{device_manager, sys_dev_char_kset},
+        kobject::KObject,
+        subsys::SubSysPrivate,
+    },
+    init::initcall::INITCALL_SUBSYS,
+    time::{timekeeping::do_settimeofday64, TimeSpec},
+};
+
+use super::{interface::rtc_read_time, register_default_rtc, sysfs::RtcGeneralDevice};
+
+/// `/sys/class/rtc` 的 class 实例
+static mut CLASS_RTC_INSTANCE: Option<Arc<RtcClass>> = None;
+
+/// 获取 `/sys/class/rtc` 的 class 实例
+#[inline(always)]
+#[allow(dead_code)]
+pub fn sys_class_rtc_instance() -> Option<&'static Arc<RtcClass>> {
+    unsafe { CLASS_RTC_INSTANCE.as_ref() }
+}
+
+/// 初始化帧缓冲区子系统
+#[unified_init(INITCALL_SUBSYS)]
+pub fn fbmem_init() -> Result<(), SystemError> {
+    let rtc_class = RtcClass::new();
+    class_manager().class_register(&(rtc_class.clone() as Arc<dyn Class>))?;
+
+    unsafe {
+        CLASS_RTC_INSTANCE = Some(rtc_class);
+    }
+
+    return Ok(());
+}
+
+/// `/sys/class/rtc` 类
+#[derive(Debug)]
+pub struct RtcClass {
+    subsystem: SubSysPrivate,
+}
+
+impl RtcClass {
+    const NAME: &'static str = "rtc";
+    pub fn new() -> Arc<Self> {
+        let r = Self {
+            subsystem: SubSysPrivate::new(Self::NAME.to_string(), None, None, &[]),
+        };
+        let r = Arc::new(r);
+        r.subsystem()
+            .set_class(Some(Arc::downgrade(&r) as Weak<dyn Class>));
+
+        return r;
+    }
+}
+
+impl Class for RtcClass {
+    fn name(&self) -> &'static str {
+        return Self::NAME;
+    }
+
+    fn dev_kobj(&self) -> Option<Arc<dyn KObject>> {
+        Some(sys_dev_char_kset() as Arc<dyn KObject>)
+    }
+
+    fn set_dev_kobj(&self, _kobj: Arc<dyn KObject>) {
+        unimplemented!("RtcClass::set_dev_kobj");
+    }
+
+    fn subsystem(&self) -> &SubSysPrivate {
+        return &self.subsystem;
+    }
+}
+
+/// 注册rtc通用设备
+pub(super) fn rtc_register_device(dev: &Arc<RtcGeneralDevice>) -> Result<(), SystemError> {
+    device_manager().add_device(dev.clone())?;
+    register_default_rtc(dev.clone());
+    // 把硬件时间同步到系统时间
+    rtc_hctosys(dev);
+    return Ok(());
+}
+
+fn rtc_hctosys(dev: &Arc<RtcGeneralDevice>) {
+    let r = rtc_read_time(dev);
+    if let Err(e) = r {
+        dev.set_hc2sys_result(Err(e));
+        return;
+    }
+
+    let time = r.unwrap();
+    let timespec64: TimeSpec = time.into();
+    let r = do_settimeofday64(timespec64);
+    dev.set_hc2sys_result(r);
+
+    kinfo!(
+        "Setting system clock to {} {} UTC ({})",
+        time.date_string(),
+        time.time_string(),
+        timespec64.tv_sec
+    );
+}

+ 31 - 0
kernel/src/driver/rtc/interface.rs

@@ -0,0 +1,31 @@
+use alloc::sync::Arc;
+use system_error::SystemError;
+
+use crate::driver::base::kobject::KObject;
+
+use super::{global_default_rtc, sysfs::RtcGeneralDevice, utils::kobj2rtc_device, RtcTime};
+
+/// 根据rtc general device, 读取真实时间
+pub fn rtc_read_time(general_dev: &Arc<RtcGeneralDevice>) -> Result<RtcTime, SystemError> {
+    let class_ops = general_dev.class_ops().ok_or(SystemError::EINVAL)?;
+
+    let real_dev = general_dev
+        .parent()
+        .and_then(|p| p.upgrade())
+        .ok_or(SystemError::ENODEV)?;
+
+    let real_dev = kobj2rtc_device(real_dev).ok_or(SystemError::EINVAL)?;
+
+    let time = class_ops.read_time(&real_dev)?;
+
+    if !time.valid() {
+        return Err(SystemError::EINVAL);
+    }
+
+    return Ok(time);
+}
+
+/// 从全局默认的rtc时钟那里读取时间
+pub fn rtc_read_time_default() -> Result<RtcTime, SystemError> {
+    rtc_read_time(&global_default_rtc().ok_or(SystemError::ENODEV)?)
+}

+ 169 - 0
kernel/src/driver/rtc/mod.rs

@@ -0,0 +1,169 @@
+use core::fmt::Debug;
+
+use alloc::{string::String, sync::Arc};
+use system_error::SystemError;
+
+use crate::{
+    libs::rwlock::RwLock,
+    time::{Instant, TimeSpec, NSEC_PER_SEC},
+};
+
+use self::sysfs::RtcGeneralDevice;
+
+use super::base::device::Device;
+
+pub mod class;
+pub mod interface;
+pub mod rtc_cmos;
+mod sysfs;
+mod utils;
+
+/// 全局默认rtc
+static GLOBAL_DEFAULT_RTC: RwLock<Option<Arc<RtcGeneralDevice>>> = RwLock::new(None);
+
+/// 获取全局的默认的rtc
+fn global_default_rtc() -> Option<Arc<RtcGeneralDevice>> {
+    GLOBAL_DEFAULT_RTC.read().clone()
+}
+
+/// 注册默认的rtc
+fn register_default_rtc(general_device: Arc<RtcGeneralDevice>) -> bool {
+    let upg = GLOBAL_DEFAULT_RTC.upgradeable_read();
+    if let Some(old_dev) = upg.as_ref() {
+        if old_dev.priority() >= general_device.priority() {
+            return false;
+        }
+    }
+
+    let mut write = upg.upgrade();
+
+    write.replace(general_device);
+
+    return true;
+}
+
+/// RTC设备的trait
+pub trait RtcDevice: Device {
+    fn class_ops(&self) -> &'static dyn RtcClassOps;
+}
+
+pub trait RtcClassOps: Send + Sync + Debug {
+    fn read_time(&self, dev: &Arc<dyn RtcDevice>) -> Result<RtcTime, SystemError>;
+    fn set_time(&self, dev: &Arc<dyn RtcDevice>, time: &RtcTime) -> Result<(), SystemError>;
+}
+
+#[derive(Default, Debug, Clone, Copy)]
+pub struct RtcTime {
+    /// `second`: 秒,范围从 0 到 59
+    pub second: i32,
+    /// `minute`: 分钟,范围从 0 到 59
+    pub minute: i32,
+    /// `hour`: 小时,范围从 0 到 23
+    pub hour: i32,
+    /// `mday`: 一个月中的第几天,范围从 1 到 31
+    pub mday: i32,
+    /// `month`: 月份,范围从 0 到 11
+    pub month: i32,
+    /// `year`: 年份(相对于1900年)
+    pub year: i32,
+    /// `wday`: 一周中的第几天,范围从 0(周日)到 6(周六)
+    pub wday: i32,
+    /// `yday`: 一年中的第几天,范围从 1 到 366
+    pub yday: i32,
+    /// `isdst`: 表示是否为夏令时,通常如果是夏令时,此值为正,否则为零或负
+    pub isdst: i32,
+}
+
+impl RtcTime {
+    /// 返回一个格式化的日期字符串
+    ///
+    /// 例如,如果日期为2021年1月1日,则返回"2021-01-01"
+    pub fn date_string(&self) -> String {
+        format!(
+            "{:04}-{:02}-{:02}",
+            self.year_real(),
+            self.month_real(),
+            self.mday
+        )
+    }
+
+    /// 返回一个格式化的时间字符串
+    ///
+    /// 例如,如果时间为12:00:00,则返回"12:00:00"
+    pub fn time_string(&self) -> String {
+        format!("{:02}:{:02}:{:02}", self.hour, self.minute, self.second)
+    }
+
+    pub fn valid(&self) -> bool {
+        !(self.year < 70
+            || self.year > (i32::MAX - 1900)
+            || self.month >= 12
+            || self.month < 0
+            || self.mday < 1
+            || self.mday > self.month_days()
+            || self.hour >= 24
+            || self.hour < 0
+            || self.minute >= 60
+            || self.minute < 0
+            || self.second >= 60
+            || self.second < 0)
+    }
+
+    /// 获取当月有多少天
+    pub fn month_days(&self) -> i32 {
+        let days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+        let month = self.month as usize;
+        let mut days = days_in_month[month];
+
+        if month == 1 && self.is_leap_year() {
+            days += 1;
+        }
+
+        days
+    }
+
+    /// 判断当前是否为闰年
+    pub fn is_leap_year(&self) -> bool {
+        let year = self.year + 1900;
+        (year % 4 == 0 && year % 100 != 0) || year % 400 == 0
+    }
+
+    pub fn year_real(&self) -> i32 {
+        self.year + 1900
+    }
+
+    pub fn month_real(&self) -> i32 {
+        self.month + 1
+    }
+}
+
+impl From<RtcTime> for TimeSpec {
+    fn from(val: RtcTime) -> Self {
+        let instant = Instant::mktime64(
+            val.year_real() as u32,
+            (val.month + 1) as u32,
+            (val.mday) as u32,
+            val.hour as u32,
+            val.minute as u32,
+            val.second as u32,
+        );
+
+        /* 注意:RTC 仅存储完整的秒数。它是任意的,它存储的是最接近的值还是
+         * 分割秒数截断的值。然而,重要的是我们使用它来存储截断的值。这是因为
+         * 否则在 RTC 同步函数中,需要读取 both xtime.tv_sec 和 xtime.tv_nsec。
+         * 在某些处理器上(例如 ARM),对 >32位的原子读取是不可行的。所以,
+         * 存储最接近的值会减慢同步 API 的速度。因此,这里我们存储截断的值
+         * 并在后面加上 0.5s 的最佳猜测。
+         */
+        TimeSpec::new(instant.secs(), (NSEC_PER_SEC >> 1).into())
+    }
+}
+
+/// 全局默认rtc的优先级
+#[allow(dead_code)]
+#[derive(Debug, Default, PartialEq, PartialOrd, Clone, Copy)]
+pub enum GeneralRtcPriority {
+    #[default]
+    L0 = 0,
+    L1,
+}

+ 227 - 0
kernel/src/driver/rtc/rtc_cmos.rs

@@ -0,0 +1,227 @@
+use alloc::{
+    string::{String, ToString},
+    sync::{Arc, Weak},
+    vec::Vec,
+};
+use intertrait::cast::CastArc;
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
+use super::{
+    class::rtc_register_device,
+    sysfs::{rtc_general_device_create, RtcGeneralDevice},
+    RtcClassOps, RtcDevice, RtcTime,
+};
+use crate::{
+    driver::base::{
+        device::{
+            bus::Bus,
+            driver::{Driver, DriverCommonData},
+            Device, IdTable,
+        },
+        kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
+        kset::KSet,
+        platform::{
+            platform_device::PlatformDevice,
+            platform_driver::{platform_driver_manager, PlatformDriver},
+        },
+    },
+    filesystem::kernfs::KernFSInode,
+    init::initcall::INITCALL_DEVICE,
+    libs::{
+        rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
+        spinlock::{SpinLock, SpinLockGuard},
+    },
+};
+
+static CMOS_RTC_GENERAL_DEVICE: RwLock<Option<Arc<RtcGeneralDevice>>> = RwLock::new(None);
+
+#[derive(Debug)]
+#[cast_to([sync] Driver, PlatformDriver)]
+struct CmosPlatformDriver {
+    inner: SpinLock<InnerCmosPlatformDriver>,
+    locked_kobjstate: LockedKObjectState,
+}
+
+impl CmosPlatformDriver {
+    const NAME: &str = "rtc_cmos";
+
+    fn new() -> Arc<Self> {
+        Arc::new(CmosPlatformDriver {
+            inner: SpinLock::new(InnerCmosPlatformDriver {
+                driver_common: DriverCommonData::default(),
+                kobject_common: KObjectCommonData::default(),
+            }),
+            locked_kobjstate: LockedKObjectState::new(None),
+        })
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerCmosPlatformDriver> {
+        self.inner.lock()
+    }
+}
+
+#[derive(Debug)]
+struct InnerCmosPlatformDriver {
+    driver_common: DriverCommonData,
+    kobject_common: KObjectCommonData,
+}
+
+impl PlatformDriver for CmosPlatformDriver {
+    fn probe(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        let dev = device
+            .clone()
+            .arc_any()
+            .cast::<dyn RtcDevice>()
+            .map_err(|_| SystemError::ENODEV)?;
+
+        if dev.id_table() != self.id_table().unwrap() {
+            return Err(SystemError::ENODEV);
+        }
+
+        if CMOS_RTC_GENERAL_DEVICE.read().is_some() {
+            return Err(SystemError::EBUSY);
+        }
+
+        let mut guard = CMOS_RTC_GENERAL_DEVICE.write();
+
+        // 再次检查
+        if guard.is_some() {
+            return Err(SystemError::EBUSY);
+        }
+
+        let general_rtc_device: Arc<RtcGeneralDevice> = rtc_general_device_create(&dev, None);
+        guard.replace(general_rtc_device.clone());
+
+        general_rtc_device.set_class_ops(&CmosRtcClassOps);
+        drop(guard);
+
+        rtc_register_device(&general_rtc_device)
+            .expect("cmos_rtc: register general rtc device failed");
+
+        return Ok(());
+    }
+
+    fn remove(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        // todo: remove
+        Err(SystemError::ENOSYS)
+    }
+
+    fn shutdown(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        unimplemented!("cmos platform driver shutdown")
+    }
+
+    fn suspend(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        todo!("cmos platform driver suspend")
+    }
+
+    fn resume(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
+        todo!("cmos platform driver resume")
+    }
+}
+
+impl Driver for CmosPlatformDriver {
+    fn id_table(&self) -> Option<IdTable> {
+        Some(IdTable::new(Self::NAME.to_string(), None))
+    }
+
+    fn devices(&self) -> Vec<Arc<dyn Device>> {
+        self.inner().driver_common.devices.clone()
+    }
+
+    fn add_device(&self, device: Arc<dyn Device>) {
+        self.inner().driver_common.push_device(device);
+    }
+
+    fn delete_device(&self, device: &Arc<dyn Device>) {
+        self.inner().driver_common.delete_device(device);
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner().driver_common.bus = bus;
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner().driver_common.bus.clone()
+    }
+}
+
+impl KObject for CmosPlatformDriver {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner().kobject_common.kern_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner().kobject_common.kern_inode.clone()
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner().kobject_common.parent.clone()
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner().kobject_common.parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner().kobject_common.kset.clone()
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner().kobject_common.kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner().kobject_common.kobj_type
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobject_common.kobj_type = ktype;
+    }
+
+    fn name(&self) -> String {
+        Self::NAME.to_string()
+    }
+
+    fn set_name(&self, _name: String) {
+        // do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.locked_kobjstate.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.locked_kobjstate.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.locked_kobjstate.write() = state;
+    }
+}
+
+#[unified_init(INITCALL_DEVICE)]
+pub fn cmos_rtc_driver_init() -> Result<(), SystemError> {
+    let driver = CmosPlatformDriver::new();
+
+    platform_driver_manager().register(driver)?;
+
+    return Ok(());
+}
+
+#[derive(Debug)]
+struct CmosRtcClassOps;
+
+impl RtcClassOps for CmosRtcClassOps {
+    fn read_time(&self, dev: &Arc<dyn RtcDevice>) -> Result<RtcTime, SystemError> {
+        dev.class_ops().read_time(dev)
+    }
+
+    fn set_time(&self, dev: &Arc<dyn RtcDevice>, time: &RtcTime) -> Result<(), SystemError> {
+        dev.class_ops().set_time(dev, time)
+    }
+}

+ 379 - 0
kernel/src/driver/rtc/sysfs.rs

@@ -0,0 +1,379 @@
+use alloc::{
+    string::String,
+    sync::{Arc, Weak},
+};
+use ida::IdAllocator;
+use system_error::SystemError;
+
+use crate::{
+    driver::base::{
+        class::Class,
+        device::{
+            bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable,
+        },
+        kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
+        kset::KSet,
+    },
+    filesystem::{
+        kernfs::KernFSInode,
+        sysfs::{
+            file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO,
+        },
+        vfs::syscall::ModeType,
+    },
+    libs::{
+        rwlock::{RwLockReadGuard, RwLockWriteGuard},
+        spinlock::{SpinLock, SpinLockGuard},
+    },
+};
+
+use super::{
+    class::sys_class_rtc_instance,
+    interface::rtc_read_time,
+    utils::{kobj2rtc_device, kobj2rtc_general_device},
+    GeneralRtcPriority, RtcClassOps, RtcDevice,
+};
+
+static RTC_GENERAL_DEVICE_IDA: IdAllocator = IdAllocator::new(0, usize::MAX);
+
+pub(super) const RTC_HCTOSYS_DEVICE: &str = "rtc0";
+
+#[derive(Debug)]
+#[cast_to([sync] KObject, Device, RtcDevice)]
+pub struct RtcGeneralDevice {
+    name: String,
+    id: usize,
+    inner: SpinLock<InnerRtcGeneralDevice>,
+    kobj_state: LockedKObjectState,
+    priority: GeneralRtcPriority,
+}
+
+#[derive(Debug)]
+struct InnerRtcGeneralDevice {
+    device_common: DeviceCommonData,
+    kobject_common: KObjectCommonData,
+
+    class_ops: Option<&'static dyn RtcClassOps>,
+    /// 上一次调用`rtc_hctosys()`把时间同步到timekeeper的时候的返回值
+    hc2sysfs_result: Result<(), SystemError>,
+}
+
+impl RtcGeneralDevice {
+    /// 创建一个新的通用RTC设备实例
+    ///
+    /// 注意,由于还需要进行其他的初始化操作,因此这个函数并不是公开的构造函数。
+    fn new(priority: GeneralRtcPriority) -> Arc<Self> {
+        let id = RTC_GENERAL_DEVICE_IDA.alloc().unwrap();
+        let name = format!("rtc{}", id);
+        Arc::new(Self {
+            name,
+            id,
+            inner: SpinLock::new(InnerRtcGeneralDevice {
+                device_common: DeviceCommonData::default(),
+                kobject_common: KObjectCommonData::default(),
+                class_ops: None,
+                hc2sysfs_result: Err(SystemError::ENODEV),
+            }),
+            kobj_state: LockedKObjectState::new(None),
+            priority,
+        })
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerRtcGeneralDevice> {
+        self.inner.lock()
+    }
+
+    pub fn set_class_ops(&self, class_ops: &'static dyn RtcClassOps) {
+        self.inner().class_ops = Some(class_ops);
+    }
+
+    pub fn class_ops(&self) -> Option<&'static dyn RtcClassOps> {
+        self.inner().class_ops
+    }
+
+    pub fn priority(&self) -> GeneralRtcPriority {
+        self.priority
+    }
+
+    pub(super) fn set_hc2sys_result(&self, val: Result<(), SystemError>) {
+        self.inner().hc2sysfs_result = val;
+    }
+
+    pub(super) fn hc2sysfs_result(&self) -> Result<(), SystemError> {
+        self.inner().hc2sysfs_result.clone()
+    }
+}
+
+impl Drop for RtcGeneralDevice {
+    fn drop(&mut self) {
+        RTC_GENERAL_DEVICE_IDA.free(self.id);
+    }
+}
+
+impl RtcDevice for RtcGeneralDevice {
+    fn class_ops(&self) -> &'static dyn super::RtcClassOps {
+        todo!()
+    }
+}
+
+impl Device for RtcGeneralDevice {
+    fn dev_type(&self) -> DeviceType {
+        DeviceType::Rtc
+    }
+
+    fn id_table(&self) -> IdTable {
+        IdTable::new(self.name.clone(), None)
+    }
+
+    fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
+        self.inner().device_common.bus = bus;
+    }
+
+    fn bus(&self) -> Option<Weak<dyn Bus>> {
+        self.inner().device_common.get_bus_weak_or_clear()
+    }
+
+    fn set_class(&self, class: Option<Weak<dyn Class>>) {
+        self.inner().device_common.class = class;
+    }
+
+    fn class(&self) -> Option<Arc<dyn Class>> {
+        self.inner()
+            .device_common
+            .get_class_weak_or_clear()
+            .and_then(|x| x.upgrade())
+    }
+
+    fn driver(&self) -> Option<Arc<dyn Driver>> {
+        self.inner()
+            .device_common
+            .get_driver_weak_or_clear()
+            .and_then(|x| x.upgrade())
+    }
+
+    fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
+        self.inner().device_common.driver = driver;
+    }
+
+    fn is_dead(&self) -> bool {
+        false
+    }
+
+    fn can_match(&self) -> bool {
+        false
+    }
+
+    fn set_can_match(&self, _can_match: bool) {
+        // do nothing
+    }
+
+    fn state_synced(&self) -> bool {
+        true
+    }
+    fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
+        Some(&[&RtcAttrGroup])
+    }
+}
+
+impl KObject for RtcGeneralDevice {
+    fn as_any_ref(&self) -> &dyn core::any::Any {
+        self
+    }
+
+    fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
+        self.inner().kobject_common.kern_inode = inode;
+    }
+
+    fn inode(&self) -> Option<Arc<KernFSInode>> {
+        self.inner().kobject_common.kern_inode.clone()
+    }
+
+    fn parent(&self) -> Option<Weak<dyn KObject>> {
+        self.inner().kobject_common.parent.clone()
+    }
+
+    fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
+        self.inner().kobject_common.parent = parent;
+    }
+
+    fn kset(&self) -> Option<Arc<KSet>> {
+        self.inner().kobject_common.kset.clone()
+    }
+
+    fn set_kset(&self, kset: Option<Arc<KSet>>) {
+        self.inner().kobject_common.kset = kset;
+    }
+
+    fn kobj_type(&self) -> Option<&'static dyn KObjType> {
+        self.inner().kobject_common.kobj_type
+    }
+
+    fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
+        self.inner().kobject_common.kobj_type = ktype;
+    }
+
+    fn name(&self) -> String {
+        self.name.clone()
+    }
+
+    fn set_name(&self, _name: String) {
+        // do nothing
+    }
+
+    fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
+        self.kobj_state.read()
+    }
+
+    fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
+        self.kobj_state.write()
+    }
+
+    fn set_kobj_state(&self, state: KObjectState) {
+        *self.kobj_state_mut() = state;
+    }
+}
+
+///
+/// 用于创建一个通用的RTC设备实例。
+///
+/// ## 参数
+///
+/// - `real_dev`: 一个对实际RTC设备的引用,这个设备将作为通用RTC设备的父设备。
+pub fn rtc_general_device_create(
+    real_dev: &Arc<dyn RtcDevice>,
+    priority: Option<GeneralRtcPriority>,
+) -> Arc<RtcGeneralDevice> {
+    let dev = RtcGeneralDevice::new(priority.unwrap_or_default());
+    device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>));
+    dev.set_parent(Some(Arc::downgrade(real_dev) as Weak<dyn KObject>));
+    dev.set_class(Some(Arc::downgrade(
+        &(sys_class_rtc_instance().cloned().unwrap() as Arc<dyn Class>),
+    )));
+
+    return dev;
+}
+
+#[derive(Debug)]
+struct RtcAttrGroup;
+
+impl AttributeGroup for RtcAttrGroup {
+    fn name(&self) -> Option<&str> {
+        None
+    }
+
+    fn attrs(&self) -> &[&'static dyn Attribute] {
+        &[&AttrName, &AttrDate, &AttrTime, &AttrHcToSys]
+    }
+
+    fn is_visible(
+        &self,
+        _kobj: Arc<dyn KObject>,
+        attr: &'static dyn Attribute,
+    ) -> Option<ModeType> {
+        // todo: https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/rtc/sysfs.c#280
+
+        return Some(attr.mode());
+    }
+}
+
+#[derive(Debug)]
+struct AttrName;
+
+impl Attribute for AttrName {
+    fn name(&self) -> &str {
+        "name"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let rtc_device = kobj
+            .parent()
+            .and_then(|x| x.upgrade())
+            .ok_or(SystemError::ENODEV)?;
+        let rtc_device = kobj2rtc_device(rtc_device).ok_or(SystemError::EINVAL)?;
+
+        let driver_name = rtc_device.driver().ok_or(SystemError::ENODEV)?.name();
+        let device_name = rtc_device.name();
+        sysfs_emit_str(buf, &format!("{} {}\n", driver_name, device_name))
+    }
+}
+
+#[derive(Debug)]
+struct AttrDate;
+
+impl Attribute for AttrDate {
+    fn name(&self) -> &str {
+        "date"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let rtc_device: Arc<RtcGeneralDevice> =
+            kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?;
+        let time = rtc_read_time(&rtc_device)?;
+        sysfs_emit_str(buf, &time.date_string())
+    }
+}
+
+#[derive(Debug)]
+struct AttrTime;
+
+impl Attribute for AttrTime {
+    fn name(&self) -> &str {
+        "time"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let rtc_device = kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?;
+        let time = rtc_read_time(&rtc_device)?;
+        sysfs_emit_str(buf, &time.time_string())
+    }
+}
+
+#[derive(Debug)]
+struct AttrHcToSys;
+
+impl Attribute for AttrHcToSys {
+    fn name(&self) -> &str {
+        "hctosys"
+    }
+
+    fn mode(&self) -> ModeType {
+        SYSFS_ATTR_MODE_RO
+    }
+
+    fn support(&self) -> SysFSOpsSupport {
+        SysFSOpsSupport::ATTR_SHOW
+    }
+
+    fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
+        let rtc_device = kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?;
+        if rtc_device.hc2sysfs_result().is_ok() && rtc_device.name().eq(RTC_HCTOSYS_DEVICE) {
+            return sysfs_emit_str(buf, "1\n");
+        }
+
+        return sysfs_emit_str(buf, "0\n");
+    }
+}

+ 16 - 0
kernel/src/driver/rtc/utils.rs

@@ -0,0 +1,16 @@
+use alloc::sync::Arc;
+use intertrait::cast::CastArc;
+
+use crate::driver::base::kobject::KObject;
+
+use super::{sysfs::RtcGeneralDevice, RtcDevice};
+
+#[inline]
+pub fn kobj2rtc_device(kobj: Arc<dyn KObject>) -> Option<Arc<dyn RtcDevice>> {
+    kobj.arc_any().cast::<dyn RtcDevice>().ok()
+}
+
+#[inline]
+pub fn kobj2rtc_general_device(kobj: Arc<dyn KObject>) -> Option<Arc<RtcGeneralDevice>> {
+    kobj.arc_any().downcast().ok()
+}

+ 0 - 4
kernel/src/driver/serial/serial8250/mod.rs

@@ -177,10 +177,6 @@ impl Serial8250ISADevices {
 }
 
 impl PlatformDevice for Serial8250ISADevices {
-    fn compatible_table(&self) -> crate::driver::base::platform::CompatibleTable {
-        unimplemented!()
-    }
-
     fn pdev_id(&self) -> (i32, bool) {
         return (
             self.id.load(Ordering::SeqCst),

+ 0 - 1
kernel/src/driver/timers/mod.rs

@@ -1,2 +1 @@
 pub mod hpet;
-pub mod rtc;

+ 0 - 2
kernel/src/driver/timers/rtc/mod.rs

@@ -1,2 +0,0 @@
-#[allow(clippy::module_inception)]
-pub mod rtc;

+ 0 - 90
kernel/src/driver/timers/rtc/rtc.rs

@@ -1,90 +0,0 @@
-use system_error::SystemError;
-
-use crate::{
-    arch::{io::PortIOArch, CurrentIrqArch, CurrentPortIOArch},
-    exception::InterruptArch,
-};
-
-#[derive(Default)]
-pub struct RtcTime {
-    pub second: i32,
-    pub minute: i32,
-    pub hour: i32,
-    pub day: i32,
-    pub month: i32,
-    pub year: i32,
-}
-
-impl RtcTime {
-    ///@brief 从主板cmos中获取时间
-    ///
-    ///@param self time结构体
-    ///@return int 成功则为0
-    pub fn get(&mut self) -> Result<i32, SystemError> {
-        // 为防止中断请求打断该过程,需要先关中断
-        let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
-        //0x0B
-        let status_register_b: u8 = read_cmos(0x0B); // 读取状态寄存器B
-        let is_24h: bool = (status_register_b & 0x02) != 0;
-        // 判断是否启用24小时模式
-
-        let is_binary: bool = (status_register_b & 0x04) != 0; // 判断是否为二进制码
-
-        loop {
-            self.year = read_cmos(CMOSTimeSelector::Year as u8) as i32;
-            self.month = read_cmos(CMOSTimeSelector::Month as u8) as i32;
-            self.day = read_cmos(CMOSTimeSelector::Day as u8) as i32;
-            self.hour = read_cmos(CMOSTimeSelector::Hour as u8) as i32;
-            self.minute = read_cmos(CMOSTimeSelector::Minute as u8) as i32;
-            self.second = read_cmos(CMOSTimeSelector::Second as u8) as i32;
-
-            if self.second == read_cmos(CMOSTimeSelector::Second as u8) as i32 {
-                break;
-            } // 若读取时间过程中时间发生跳变则重新读取
-        }
-
-        unsafe {
-            CurrentPortIOArch::out8(0x70, 0x00);
-        }
-
-        if !is_binary
-        // 把BCD转为二进制
-        {
-            self.second = (self.second & 0xf) + (self.second >> 4) * 10;
-            self.minute = (self.minute & 0xf) + (self.minute >> 4) * 10;
-            self.hour = ((self.hour & 0xf) + ((self.hour & 0x70) >> 4) * 10) | (self.hour & 0x80);
-            self.day = (self.day & 0xf) + ((self.day / 16) * 10);
-            self.month = (self.month & 0xf) + (self.month >> 4) * 10;
-            self.year = (self.year & 0xf) + (self.year >> 4) * 10;
-        }
-        self.year += 2000;
-
-        if (!is_24h) && (self.hour & 0x80) != 0 {
-            self.hour = ((self.hour & 0x7f) + 12) % 24;
-        } // 将十二小时制转为24小时
-
-        drop(irq_guard);
-
-        return Ok(0);
-    }
-}
-
-///置位0x70的第7位,禁止不可屏蔽中断
-#[inline]
-fn read_cmos(addr: u8) -> u8 {
-    unsafe {
-        CurrentPortIOArch::out8(0x70, 0x80 | addr);
-        return CurrentPortIOArch::in8(0x71);
-    }
-}
-
-/// used in the form of u8
-#[repr(u8)]
-enum CMOSTimeSelector {
-    Second = 0x00,
-    Minute = 0x02,
-    Hour = 0x04,
-    Day = 0x07,
-    Month = 0x08,
-    Year = 0x09,
-}

+ 4 - 2
kernel/src/driver/tty/virtual_terminal/virtual_console.rs

@@ -26,11 +26,13 @@ lazy_static! {
     /// 是否已经添加了软光标
     pub(super) static ref SOFTCURSOR_ORIGINAL: RwLock<Option<VcCursor>> = RwLock::new(None);
 
-    pub static ref CURRENT_VCNUM: AtomicIsize = AtomicIsize::new(-1);
 
-    pub static ref CONSOLE_BLANKED: AtomicBool = AtomicBool::new(false);
 }
 
+pub static CURRENT_VCNUM: AtomicIsize = AtomicIsize::new(-1);
+
+pub static CONSOLE_BLANKED: AtomicBool = AtomicBool::new(false);
+
 /// ## 虚拟控制台的信息
 #[derive(Debug, Clone)]
 pub struct VirtualConsoleData {

+ 0 - 5
kernel/src/driver/video/fbdev/vesafb.rs

@@ -25,7 +25,6 @@ use crate::{
             platform::{
                 platform_device::{platform_device_manager, PlatformDevice},
                 platform_driver::{platform_driver_manager, PlatformDriver},
-                CompatibleTable,
             },
         },
         serial::serial8250::send_to_default_serial8250_port,
@@ -159,10 +158,6 @@ impl PlatformDevice for VesaFb {
         self.inner.lock().pdev_id_auto = id_auto;
     }
 
-    fn compatible_table(&self) -> CompatibleTable {
-        todo!()
-    }
-
     fn is_initialized(&self) -> bool {
         self.inner.lock().device_state == DeviceState::Initialized
     }

+ 56 - 0
kernel/src/time/mod.rs

@@ -16,6 +16,7 @@ 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
@@ -124,6 +125,61 @@ pub struct Instant {
 impl Instant {
     pub const ZERO: Instant = Instant::from_micros_const(0);
 
+    /// mktime64 - 将日期转换为秒。
+    ///
+    /// ## 参数
+    ///
+    /// - year0: 要转换的年份
+    /// - mon0: 要转换的月份
+    /// - day: 要转换的天
+    /// - hour: 要转换的小时
+    /// - min: 要转换的分钟
+    /// - sec: 要转换的秒
+    ///
+    /// 将公历日期转换为1970-01-01 00:00:00以来的秒数。
+    /// 假设输入为正常的日期格式,即1980-12-31 23:59:59 => 年份=1980, 月=12, 日=31, 时=23, 分=59, 秒=59。
+    ///
+    /// [For the Julian calendar(俄罗斯在1917年之前使用,英国及其殖民地在大西洋1752年之前使用,
+    /// 其他地方在1582年之前使用,某些社区仍然在使用)省略-year/100+year/400项,
+    /// 并在结果上加10。]
+    ///
+    /// 这个算法最初由高斯(我认为是)发表。
+    ///
+    /// 要表示闰秒,可以通过将sec设为60(在ISO 8601允许)来调用此函数。
+    /// 闰秒与随后的秒一样处理,因为它们在UNIX时间中不存在。
+    ///
+    /// 支持将午夜作为当日末尾的24:00:00编码 - 即明天的午夜(在ISO 8601允许)。
+    ///
+    /// ## 返回
+    ///
+    /// 返回:给定输入日期自1970-01-01 00:00:00以来的秒数
+    pub fn mktime64(year0: u32, mon0: u32, day: u32, hour: u32, min: u32, sec: u32) -> Self {
+        let mut mon: i64 = mon0.into();
+        let mut year: u64 = year0.into();
+        let day: u64 = day.into();
+        let hour: u64 = hour.into();
+        let min: u64 = min.into();
+        let sec: u64 = sec.into();
+
+        mon -= 2;
+        /* 1..12 -> 11,12,1..10 */
+        if mon <= 0 {
+            /* Puts Feb last since it has leap day */
+            mon += 12;
+            year -= 1;
+        }
+        let mon = mon as u64;
+
+        let secs = ((((year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) + year * 365
+            - 719499)
+            * 24 + hour) /* now have hours - midnight tomorrow handled here */
+            * 60 + min)/* now have minutes */
+            * 60
+            + sec; /* finally seconds */
+
+        Self::from_secs(secs as i64)
+    }
+
     /// Create a new `Instant` from a number of microseconds.
     pub fn from_micros<T: Into<i64>>(micros: T) -> Instant {
         Instant {

+ 11 - 39
kernel/src/time/timekeep.rs

@@ -1,6 +1,10 @@
 #![allow(dead_code)]
 
-use crate::driver::timers::rtc::rtc::RtcTime;
+use system_error::SystemError;
+
+use crate::driver::rtc::interface::rtc_read_time_default;
+
+use super::TimeSpec;
 
 #[allow(non_camel_case_types)]
 pub type ktime_t = i64;
@@ -14,48 +18,16 @@ fn ktime_to_ns(kt: ktime_t) -> i64 {
 /// @brief 从RTC获取当前时间,然后计算时间戳。
 /// 时间戳为从UTC+0 1970-01-01 00:00到当前UTC+0时间,所经过的纳秒数。
 /// 注意,由于当前未引入时区,因此本函数默认时区为UTC+8来计算
-fn ktime_get_real() -> ktime_t {
-    let mut rtc_time: RtcTime = RtcTime::default();
-
-    {
-        let r = rtc_time.get();
-        // 返回错误码
-        if let Err(e) = r {
-            return e as ktime_t;
-        }
-    }
-
-    let mut day_count: i32 = 0;
-    for year in 1970..rtc_time.year {
-        let leap: bool = (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0);
-        if leap {
-            day_count += 366;
-        } else {
-            day_count += 365;
-        }
-    }
-    for month in 1..rtc_time.month {
-        match month {
-            1 | 3 | 5 | 7 | 8 | 10 | 12 => day_count += 31,
-            2 => day_count += 28,
-            4 | 6 | 9 | 11 => day_count += 30,
-            _ => day_count += 0,
-        }
-    }
-
-    day_count += rtc_time.day - 1;
-    //转换成纳秒
-    let timestamp: ktime_t = day_count as i64 * 86_400_000_000_000i64
-        + (rtc_time.hour - 8) as i64 * 3_600_000_000_000i64
-        + rtc_time.minute as i64 * 60_000_000_000i64
-        + rtc_time.second as i64 * 1_000_000_000u64 as ktime_t;
-
-    return timestamp;
+fn ktime_get_real() -> Result<ktime_t, SystemError> {
+    let rtc_time = rtc_read_time_default()?;
+    let time_spec: TimeSpec = rtc_time.into();
+    let r = time_spec.tv_sec * 1_000_000_000 + time_spec.tv_nsec;
+    return Ok(r);
 }
 
 /// @brief 暴露给外部使用的接口,返回一个时间戳
 #[inline]
 pub fn ktime_get_real_ns() -> i64 {
-    let kt: ktime_t = ktime_get_real();
+    let kt: ktime_t = ktime_get_real().unwrap_or(0);
     return ktime_to_ns(kt);
 }

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

@@ -1,5 +1,6 @@
 use alloc::sync::Arc;
 use core::sync::atomic::{compiler_fence, AtomicBool, AtomicI64, Ordering};
+use system_error::SystemError;
 
 use crate::{
     arch::CurrentIrqArch,
@@ -207,6 +208,13 @@ pub fn do_gettimeofday() -> PosixTimeval {
     };
 }
 
+pub fn do_settimeofday64(time: TimeSpec) -> Result<(), SystemError> {
+    timekeeper().0.write_irqsave().xtime = time;
+    // todo: 模仿linux,实现时间误差校准。
+    // https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/time/timekeeping.c?fi=do_settimeofday64#1312
+    return Ok(());
+}
+
 /// # 初始化timekeeping模块
 #[inline(never)]
 pub fn timekeeping_init() {