From 06d5e247267cb65b84a80f219853ccd0f384b16e Mon Sep 17 00:00:00 2001 From: LoGin Date: Wed, 11 Oct 2023 00:53:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=AE=BE=E5=A4=87=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=E6=A8=A1=E5=9E=8B=EF=BC=8C=E5=9F=BA=E4=BA=8Ekset?= =?UTF-8?q?=E3=80=81kobj=E6=9D=A5=E7=BB=B4=E6=8A=A4=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E4=B9=8B=E9=97=B4=E7=9A=84=E5=85=B3=E7=B3=BB=20(#401)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 使用kobj和kset管理/sys文件夹下的对象 * 修改notifier,把action从u64换为泛型。 * 完善设备驱动模型,基于kset、kobj来维护对象之间的关系 --- kernel/src/driver/acpi/glue.rs | 8 + kernel/src/driver/acpi/mod.rs | 1 + kernel/src/driver/base/block/block_device.rs | 7 +- kernel/src/driver/base/c_adapter.rs | 10 + kernel/src/driver/base/char/mod.rs | 16 +- kernel/src/driver/base/class.rs | 26 + kernel/src/driver/base/device/bus.rs | 574 ++++++++++++---- kernel/src/driver/base/device/dd.rs | 210 ++++++ kernel/src/driver/base/device/driver.rs | 101 +-- kernel/src/driver/base/device/init.rs | 80 ++- kernel/src/driver/base/device/mod.rs | 454 ++++++++++--- kernel/src/driver/base/firmware.rs | 26 + kernel/src/driver/base/hypervisor.rs | 26 + kernel/src/driver/base/init.rs | 19 + kernel/src/driver/base/kobject.rs | 211 ++++++ kernel/src/driver/base/kset.rs | 229 +++++++ kernel/src/driver/base/map/mod.rs | 5 +- kernel/src/driver/base/mod.rs | 9 + kernel/src/driver/base/platform/mod.rs | 367 ++--------- .../driver/base/platform/platform_device.rs | 217 +++++- kernel/src/driver/base/platform/subsys.rs | 65 ++ kernel/src/driver/base/subsys.rs | 150 +++++ kernel/src/driver/base/swnode.rs | 8 + kernel/src/driver/disk/ahci/ahcidisk.rs | 84 ++- kernel/src/driver/mod.rs | 21 +- kernel/src/driver/net/virtio_net.rs | 82 ++- kernel/src/driver/uart/uart_device.rs | 173 +++-- kernel/src/driver/uart/uart_driver.rs | 82 ++- kernel/src/filesystem/kernfs/callback.rs | 36 + kernel/src/filesystem/kernfs/mod.rs | 130 +++- kernel/src/filesystem/sysfs/bus.rs | 89 --- kernel/src/filesystem/sysfs/class.rs | 69 -- kernel/src/filesystem/sysfs/devices.rs | 33 - kernel/src/filesystem/sysfs/dir.rs | 125 +++- kernel/src/filesystem/sysfs/file.rs | 285 +++++++- kernel/src/filesystem/sysfs/fs.rs | 33 - kernel/src/filesystem/sysfs/group.rs | 200 ++++++ kernel/src/filesystem/sysfs/mod.rs | 616 ++++-------------- kernel/src/filesystem/sysfs/symlink.rs | 38 ++ kernel/src/filesystem/vfs/file.rs | 4 +- kernel/src/filesystem/vfs/mod.rs | 6 + kernel/src/filesystem/vfs/syscall.rs | 13 + kernel/src/lib.rs | 1 + kernel/src/libs/notifier.rs | 74 ++- kernel/src/main.c | 5 +- user/apps/shell/cmd.c | 4 +- 46 files changed, 3492 insertions(+), 1530 deletions(-) create mode 100644 kernel/src/driver/acpi/glue.rs create mode 100644 kernel/src/driver/base/c_adapter.rs create mode 100644 kernel/src/driver/base/class.rs create mode 100644 kernel/src/driver/base/device/dd.rs create mode 100644 kernel/src/driver/base/firmware.rs create mode 100644 kernel/src/driver/base/hypervisor.rs create mode 100644 kernel/src/driver/base/init.rs create mode 100644 kernel/src/driver/base/kobject.rs create mode 100644 kernel/src/driver/base/kset.rs create mode 100644 kernel/src/driver/base/platform/subsys.rs create mode 100644 kernel/src/driver/base/subsys.rs create mode 100644 kernel/src/driver/base/swnode.rs delete mode 100644 kernel/src/filesystem/sysfs/bus.rs delete mode 100644 kernel/src/filesystem/sysfs/class.rs delete mode 100644 kernel/src/filesystem/sysfs/devices.rs delete mode 100644 kernel/src/filesystem/sysfs/fs.rs create mode 100644 kernel/src/filesystem/sysfs/group.rs create mode 100644 kernel/src/filesystem/sysfs/symlink.rs diff --git a/kernel/src/driver/acpi/glue.rs b/kernel/src/driver/acpi/glue.rs new file mode 100644 index 00000000..6bb194a5 --- /dev/null +++ b/kernel/src/driver/acpi/glue.rs @@ -0,0 +1,8 @@ +use alloc::sync::Arc; + +use crate::driver::base::device::Device; + +/// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/acpi/glue.c#352 +pub fn acpi_device_notify(_dev: &Arc) { + return; +} diff --git a/kernel/src/driver/acpi/mod.rs b/kernel/src/driver/acpi/mod.rs index 58eec677..640ff303 100644 --- a/kernel/src/driver/acpi/mod.rs +++ b/kernel/src/driver/acpi/mod.rs @@ -15,6 +15,7 @@ use crate::{ }; mod c_adapter; +pub mod glue; pub mod old; extern crate acpi; diff --git a/kernel/src/driver/base/block/block_device.rs b/kernel/src/driver/base/block/block_device.rs index 68e4f173..460f21fc 100644 --- a/kernel/src/driver/base/block/block_device.rs +++ b/kernel/src/driver/base/block/block_device.rs @@ -1,7 +1,7 @@ /// 引入Module use crate::{ driver::base::{ - device::{mkdev, Device, DeviceNumber, IdTable, BLOCKDEVS, DEVICE_MANAGER}, + device::{mkdev, Device, DeviceError, DeviceNumber, IdTable, BLOCKDEVS}, map::{ DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, DEV_MAJOR_DYN_EXT_START, DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, MINOR_MASK, @@ -475,11 +475,12 @@ impl BlockDeviceOps { /// range: 次设备号范围 /// @return: none #[allow(dead_code)] - pub fn bdev_add(bdev: Arc, id_table: IdTable) { + pub fn bdev_add(_bdev: Arc, id_table: IdTable) -> Result<(), DeviceError> { if Into::::into(id_table.device_number()) == 0 { kerror!("Device number can't be 0!\n"); } - DEVICE_MANAGER.add_device(id_table, bdev.device()) + todo!("bdev_add") + // return device_manager().add_device(bdev.id_table(), bdev.device()); } /// @brief: block设备注销 diff --git a/kernel/src/driver/base/c_adapter.rs b/kernel/src/driver/base/c_adapter.rs new file mode 100644 index 00000000..ec9be85c --- /dev/null +++ b/kernel/src/driver/base/c_adapter.rs @@ -0,0 +1,10 @@ +use super::init::driver_init; + +#[no_mangle] +unsafe extern "C" fn rs_driver_init() -> i32 { + let result = driver_init() + .map(|_| 0) + .unwrap_or_else(|e| e.to_posix_errno()); + + return result; +} diff --git a/kernel/src/driver/base/char/mod.rs b/kernel/src/driver/base/char/mod.rs index ec8f07f6..ab9885fd 100644 --- a/kernel/src/driver/base/char/mod.rs +++ b/kernel/src/driver/base/char/mod.rs @@ -3,7 +3,7 @@ use alloc::sync::Arc; use crate::{kerror, syscall::SystemError}; use super::{ - device::{mkdev, Device, DeviceNumber, IdTable, CHARDEVS, DEVICE_MANAGER, DEVMAP}, + device::{device_manager, mkdev, Device, DeviceNumber, IdTable, CHARDEVS, DEVMAP}, map::{ kobj_map, kobj_unmap, DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, DEV_MAJOR_DYN_EXT_START, DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, MINOR_MASK, @@ -189,17 +189,23 @@ impl CharDevOps { /// range: 次设备号范围 /// @return: none #[allow(dead_code)] - pub fn cdev_add(cdev: Arc, id_table: IdTable, range: usize) { + pub fn cdev_add( + cdev: Arc, + id_table: IdTable, + range: usize, + ) -> Result<(), SystemError> { if Into::::into(id_table.device_number()) == 0 { kerror!("Device number can't be 0!\n"); } - DEVICE_MANAGER.add_device(id_table.clone(), cdev.clone()); + device_manager().add_device(cdev.clone())?; kobj_map( DEVMAP.clone(), id_table.device_number(), range, cdev.clone(), - ) + ); + + return Ok(()); } /// @brief: 字符设备注销 @@ -208,7 +214,7 @@ impl CharDevOps { /// @return: none #[allow(dead_code)] pub fn cdev_del(id_table: IdTable, range: usize) { - DEVICE_MANAGER.remove_device(&id_table); + device_manager().remove_device(&id_table); kobj_unmap(DEVMAP.clone(), id_table.device_number(), range); } } diff --git a/kernel/src/driver/base/class.rs b/kernel/src/driver/base/class.rs new file mode 100644 index 00000000..fb45be36 --- /dev/null +++ b/kernel/src/driver/base/class.rs @@ -0,0 +1,26 @@ +use alloc::{string::ToString, sync::Arc}; + +use crate::syscall::SystemError; + +use super::kset::KSet; + +/// `/sys/class`的kset +static mut CLASS_KSET_INSTANCE: Option> = None; + +#[inline(always)] +#[allow(dead_code)] +pub fn sys_class_kset() -> Arc { + unsafe { CLASS_KSET_INSTANCE.clone().unwrap() } +} + +/// 初始化`/sys/class`的kset +pub(super) fn classes_init() -> Result<(), SystemError> { + let class_kset = KSet::new("class".to_string()); + class_kset + .register(None) + .expect("register class kset failed"); + unsafe { + CLASS_KSET_INSTANCE = Some(class_kset); + } + return Ok(()); +} diff --git a/kernel/src/driver/base/device/bus.rs b/kernel/src/driver/base/device/bus.rs index bb0b38c0..b37b0966 100644 --- a/kernel/src/driver/base/device/bus.rs +++ b/kernel/src/driver/base/device/bus.rs @@ -1,25 +1,41 @@ -use super::{ - device_register, device_unregister, - driver::{driver_register, driver_unregister, DriverError}, - Device, DeviceError, DeviceState, IdTable, -}; +use super::{sys_devices_kset, Device, DeviceMatchName, DeviceMatcher, DeviceState}; use crate::{ - driver::Driver, + driver::base::{device::device_manager, kobject::KObject, kset::KSet, subsys::SubSysPrivate}, filesystem::{ - sysfs::{ - bus::{sys_bus_init, sys_bus_register}, - SYS_BUS_INODE, - }, - vfs::IndexNode, + sysfs::{file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOpsSupport}, + vfs::syscall::ModeType, }, - libs::spinlock::SpinLock, + libs::rwlock::RwLock, + syscall::SystemError, }; -use alloc::{collections::BTreeMap, sync::Arc}; -use core::fmt::Debug; -use lazy_static::lazy_static; +use alloc::{ + string::{String, ToString}, + sync::Arc, +}; +use core::{ffi::CStr, fmt::Debug, intrinsics::unlikely}; +use hashbrown::HashMap; -lazy_static! { - pub static ref BUS_MANAGER: Arc = Arc::new(LockedBusManager::new()); +/// `/sys/bus`的kset +static mut BUS_KSET_INSTANCE: Option> = None; +/// `/sys/devices/system`的kset +static mut DEVICES_SYSTEM_KSET_INSTANCE: Option> = None; + +static mut BUS_MANAGER_INSTANCE: Option = None; + +#[inline(always)] +pub fn sys_bus_kset() -> Arc { + unsafe { BUS_KSET_INSTANCE.clone().unwrap() } +} + +#[inline(always)] +#[allow(dead_code)] +pub fn sys_devices_system_kset() -> Arc { + unsafe { DEVICES_SYSTEM_KSET_INSTANCE.clone().unwrap() } +} + +#[inline(always)] +pub fn bus_manager() -> &'static BusManager { + unsafe { BUS_MANAGER_INSTANCE.as_ref().unwrap() } } /// @brief: 总线状态 @@ -63,151 +79,431 @@ impl From for DeviceState { } } -/// @brief: 总线驱动trait,所有总线驱动都应实现该trait -pub trait BusDriver: Driver { - /// @brief: 判断总线是否为空 - /// @parameter: None - /// @return: 如果总线上设备和驱动的数量都为0,则返回true,否则,返回false - fn is_empty(&self) -> bool; +/// 总线子系统的trait,所有总线都应实现该trait +/// +/// 请注意,这个trait是用于实现总线子系统的,而不是总线驱动/总线设备。 +/// https://opengrok.ringotek.cn/xref/linux-6.1.9/include/linux/device/bus.h#84 +pub trait Bus: Debug + Send + Sync { + fn name(&self) -> String; + fn dev_name(&self) -> String; + fn root_device(&self) -> Option> { + None + } + + /// 总线上的设备的默认属性组 + fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] { + &[] + } + + /// 总线的默认属性组 + fn bus_groups(&self) -> &'static [&'static dyn AttributeGroup] { + &[] + } + + /// 总线上的驱动的默认属性组 + fn drv_groups(&self) -> &'static [&'static dyn AttributeGroup] { + &[] + } + + fn subsystem(&self) -> &SubSysPrivate; + + /// 对当前总线操作的时候需要获取父级总线的锁 + fn need_parent_lock(&self) -> bool { + false + } } -/// @brief: 总线设备trait,所有总线都应实现该trait -pub trait Bus: Device {} +impl dyn Bus { + /// 在bus上,根据条件寻找一个特定的设备 + /// + /// ## 参数 + /// + /// - `matcher` - 匹配器 + /// - `data` - 传给匹配器的数据 + pub fn find_device( + &self, + matcher: &dyn DeviceMatcher, + data: T, + ) -> Option> { + let subsys = self.subsystem(); + let guard = subsys.devices().read(); + for dev in guard.iter() { + let dev = dev.upgrade(); + if let Some(dev) = dev { + if matcher.match_device(&dev, data) { + return Some(dev.clone()); + } + } + } + return None; + } + + /// 根据名称匹配设备 + /// + /// ## 参数 + /// + /// - name 设备名称 + pub fn find_device_by_name(&self, name: &str) -> Option> { + return self.find_device(&DeviceMatchName, name); + } +} /// @brief: 总线管理结构体 -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct BusManager { - buses: BTreeMap>, // 总线设备表 - bus_drvs: BTreeMap>, // 总线驱动表 - sys_info: Option>, // 总线inode + /// 存储总线bus的kset结构体与bus实例的映射(用于在sysfs callback的时候,根据kset找到bus实例) + kset_bus_map: RwLock, Arc>>, } -/// @brief: bus管理(锁) -pub struct LockedBusManager(SpinLock); - -/// @brief: 总线管理方法集 -impl LockedBusManager { - /// @brief: 创建总线管理实例 - /// @parameter: None - /// @return: 总线管理实例 - #[inline] - #[allow(dead_code)] +impl BusManager { pub fn new() -> Self { - LockedBusManager(SpinLock::new(BusManager { - buses: BTreeMap::new(), - bus_drvs: BTreeMap::new(), - sys_info: Some(SYS_BUS_INODE()), - })) + return Self { + kset_bus_map: RwLock::new(HashMap::new()), + }; } - /// @brief: 添加总线 - /// @parameter id_table: 总线标识符,用于唯一标识该总线 - /// @parameter bus_dev: 总线实例 - /// @return: None - #[inline] - #[allow(dead_code)] - pub fn add_bus(&self, id_table: IdTable, bus_dev: Arc) { - let mut bus_manager = self.0.lock(); - bus_manager.buses.insert(id_table, bus_dev); + /// + /// bus_register - register a driver-core subsystem + /// + /// ## 参数 + /// - `bus` - bus to register + /// + /// Once we have that, we register the bus with the kobject + /// infrastructure, then register the children subsystems it has: + /// the devices and drivers that belong to the subsystem. + /// + /// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?fi=bus_register#783 + /// + /// todo: 增加错误处理逻辑 + pub fn register(&self, bus: Arc) -> Result<(), SystemError> { + bus.subsystem().set_bus(Arc::downgrade(&bus)); + + let subsys_kset = bus.subsystem().subsys(); + subsys_kset.set_name(bus.name()); + bus.subsystem().set_drivers_autoprobe(true); + + subsys_kset.register(Some(sys_bus_kset()))?; + + let devices_kset = + KSet::new_and_add("devices".to_string(), None, Some(subsys_kset.clone()))?; + bus.subsystem().set_devices_kset(devices_kset); + let drivers_kset = + KSet::new_and_add("drivers".to_string(), None, Some(subsys_kset.clone()))?; + bus.subsystem().set_drivers_kset(drivers_kset); + + self.add_probe_files(&bus)?; + let bus_groups = bus.bus_groups(); + self.add_groups(&bus, bus_groups)?; + // 把bus实例添加到总线管理器中(方便在sysfs callback的时候,根据kset找到bus实例) + self.kset_bus_map.write().insert(subsys_kset, bus.clone()); + return Ok(()); } - /// @brief: 添加总线驱动 - /// @parameter id_table: 总线驱动标识符,用于唯一标识该总线驱动 - /// @parameter bus_dev: 总线驱动实例 - /// @return: None - #[inline] - #[allow(dead_code)] - pub fn add_driver(&self, id_table: IdTable, bus_drv: Arc) { - let mut bus_manager = self.0.lock(); - bus_manager.bus_drvs.insert(id_table, bus_drv); + pub fn unregister(&self, _bus: Arc) -> Result<(), SystemError> { + todo!("bus_unregister") } - /// @brief: 卸载总线 - /// @parameter id_table: 总线标识符,用于唯一标识该总线 - /// @return: None - #[inline] - #[allow(dead_code)] - pub fn remove_bus(&self, id_table: &IdTable) { - let mut bus_manager = self.0.lock(); - bus_manager.buses.remove(id_table); - } + fn add_probe_files(&self, bus: &Arc) -> Result<(), SystemError> { + self.create_file(bus, &BusAttrDriversProbe)?; + let r = self.create_file(bus, &BusAttrDriversAutoprobe); - /// @brief: 卸载总线驱动 - /// @parameter id_table: 总线驱动标识符,用于唯一标识该总线驱动 - /// @return: None - #[inline] - #[allow(dead_code)] - pub fn remove_bus_driver(&self, id_table: &IdTable) { - let mut bus_manager = self.0.lock(); - bus_manager.bus_drvs.remove(id_table); - } - - /// @brief: 获取总线设备 - /// @parameter id_table: 总线标识符,用于唯一标识该总线 - /// @return: 总线设备实例 - #[inline] - #[allow(dead_code)] - pub fn get_bus(&self, id_table: &IdTable) -> Option> { - let bus_manager = self.0.lock(); - bus_manager.buses.get(id_table).cloned() - } - - /// @brief: 获取总线驱动 - /// @parameter id_table: 总线驱动标识符,用于唯一标识该总线驱动 - /// @return: 总线驱动实例 - #[inline] - #[allow(dead_code)] - pub fn get_driver(&self, id_table: &IdTable) -> Option> { - let bus_manager = self.0.lock(); - return bus_manager.bus_drvs.get(id_table).cloned(); - } - - /// @brief: 获取总线管理器的sys information - /// @parameter None - /// @return: sys inode - #[inline] - #[allow(dead_code)] - fn sys_info(&self) -> Option> { - return self.0.lock().sys_info.clone(); - } -} - -/// @brief: 总线注册,将总线加入全局总线管理器中,并根据id table在sys/bus和sys/devices下生成文件夹 -/// @parameter bus: Bus设备实体 -/// @return: 成功:() 失败:DeviceError -pub fn bus_register(bus: Arc) -> Result<(), DeviceError> { - BUS_MANAGER.add_bus(bus.id_table(), bus.clone()); - match sys_bus_register(&bus.id_table().name()) { - Ok(inode) => { - let _ = sys_bus_init(&inode); - return device_register(bus); + if r.is_err() { + self.remove_file(bus, &BusAttrDriversProbe); } - Err(_) => Err(DeviceError::RegisterError), + return r; + } + + #[allow(dead_code)] + fn remove_probe_files(&self, bus: &Arc) { + self.remove_file(bus, &BusAttrDriversAutoprobe); + self.remove_file(bus, &BusAttrDriversProbe); + } + + fn create_file( + &self, + bus: &Arc, + attr: &'static dyn Attribute, + ) -> Result<(), SystemError> { + let bus_kobj = bus.subsystem().subsys() as Arc; + return sysfs_instance().create_file(&bus_kobj, attr); + } + + fn remove_file(&self, bus: &Arc, attr: &'static dyn Attribute) { + let bus_kobj = bus.subsystem().subsys() as Arc; + sysfs_instance().remove_file(&bus_kobj, attr); + } + + #[inline] + fn add_groups( + &self, + bus: &Arc, + groups: &[&'static dyn AttributeGroup], + ) -> Result<(), SystemError> { + let bus_kobj = bus.subsystem().subsys() as Arc; + return sysfs_instance().create_groups(&bus_kobj, groups); + } + + /// 根据bus的kset找到bus实例 + fn get_bus_by_kset(&self, kset: &Arc) -> Option> { + return self.kset_bus_map.read().get(kset).map(|bus| bus.clone()); + } + + /// 为bus上的设备选择可能的驱动程序 + /// + /// 这个函数会扫描总线上的所有没有驱动的设备,然后为它们选择可能的驱动程序。 + /// + /// ## 参数 + /// + /// - `bus` - bus实例 + #[allow(dead_code)] + pub fn rescan_devices(&self, bus: &Arc) -> Result<(), SystemError> { + for dev in bus.subsystem().devices().read().iter() { + let dev = dev.upgrade(); + if let Some(dev) = dev { + rescan_devices_helper(dev)?; + } + } + return Ok(()); + } + + /// 为新设备探测驱动 + /// + /// Automatically probe for a driver if the bus allows it. + pub fn probe_device(&self, dev: &Arc) { + let bus = dev.bus(); + if bus.is_none() { + return; + } + let bus = bus.unwrap(); + if bus.subsystem().drivers_autoprobe() { + device_manager().device_initial_probe(dev).ok(); + } + for interface in bus.subsystem().interfaces() { + interface.add_device(dev).ok(); + } + } + + /// 在bus上,根据条件寻找一个特定的设备 + /// + /// ## 参数 + /// + /// - `matcher` - 匹配器 + /// - `data` - 传给匹配器的数据 + #[inline] + #[allow(dead_code)] + pub fn find_device( + &self, + bus: &Arc, + matcher: &dyn DeviceMatcher, + data: T, + ) -> Option> { + return bus.find_device(matcher, data); } } -/// @brief: 总线注销,将总线从全局总线管理器中删除,并在sys/bus和sys/devices下删除文件夹 +/// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?r=&mo=5649&fi=241#684 +fn rescan_devices_helper(dev: Arc) -> Result<(), SystemError> { + if dev.driver().is_none() { + let need_parent_lock = dev.bus().map(|bus| bus.need_parent_lock()).unwrap_or(false); + if unlikely(need_parent_lock) { + // todo: lock device parent + unimplemented!() + } + device_manager().device_attach(&dev)?; + } + return Ok(()); +} + +/// +/// bus_register - register a driver-core subsystem +/// +/// ## 参数 +/// - `bus` - bus to register +/// +/// Once we have that, we register the bus with the kobject +/// infrastructure, then register the children subsystems it has: +/// the devices and drivers that belong to the subsystem. +pub fn bus_register(bus: Arc) -> Result<(), SystemError> { + return bus_manager().register(bus); +} + +/// @brief: 总线注销,并在sys/bus和sys/devices下删除文件夹 /// @parameter bus: Bus设备实体 -/// @return: 成功:() 失败:DeviceError +/// @return: 成功:() 失败:SystemError #[allow(dead_code)] -pub fn bus_unregister(bus: Arc) -> Result<(), DeviceError> { - BUS_MANAGER.remove_bus(&bus.id_table()); - return device_unregister(bus); +pub fn bus_unregister(bus: Arc) -> Result<(), SystemError> { + return bus_manager().unregister(bus); } -/// @brief: 总线驱动注册,将总线驱动加入全局总线管理器中 -/// @parameter bus: Bus设备驱动实体 -/// @return: 成功:() 失败:DeviceError -pub fn bus_driver_register(bus_driver: Arc) -> Result<(), DriverError> { - BUS_MANAGER.add_driver(bus_driver.id_table(), bus_driver.clone()); - return driver_register(bus_driver); +pub fn buses_init() -> Result<(), SystemError> { + let bus_kset = KSet::new("bus".to_string()); + bus_kset.register(None).expect("bus kset register failed"); + unsafe { + BUS_KSET_INSTANCE = Some(bus_kset); + } + + // 初始化 /sys/devices/system + { + let devices_system_kset = KSet::new("system".to_string()); + let parent = sys_devices_kset() as Arc; + devices_system_kset.set_parent(Some(Arc::downgrade(&parent))); + devices_system_kset + .register(Some(sys_devices_kset())) + .expect("devices system kset register failed"); + } + + // 初始化总线管理器 + { + let bus_manager = BusManager::new(); + unsafe { + BUS_MANAGER_INSTANCE = Some(bus_manager); + } + } + return Ok(()); } -/// @brief: 总线驱动注销,将总线从全局总线管理器中删除 -/// @parameter bus: Bus设备驱动实体 -/// @return: 成功:() 失败:DeviceError -#[allow(dead_code)] -pub fn bus_driver_unregister(bus_driver: Arc) -> Result<(), DriverError> { - BUS_MANAGER.remove_bus_driver(&bus_driver.id_table()); - return driver_unregister(bus_driver); +/// 把一个设备添加到总线上 +/// +/// ## 描述 +/// +/// - 添加一个设备的与bus相关的属性 +/// - 在bus和设备文件夹下,创建软链接 +/// - 把设备添加到它的总线的设备列表中 +/// +/// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?fi=bus_add_device#441 +/// +/// ## 参数 +/// +/// - `dev` - 要被添加的设备 +pub fn bus_add_device(dev: &Arc) -> Result<(), SystemError> { + let bus = dev.bus(); + if let Some(bus) = bus { + device_manager().add_groups(dev, bus.dev_groups())?; + // todo: 增加符号链接 + todo!("bus_add_device") + } + return Ok(()); +} + +/// 自动为设备在总线上寻找可用的驱动程序 +/// +/// Automatically probe for a driver if the bus allows it. +/// +/// ## 参数 +/// +/// - `dev` - 要被添加的设备 +/// +/// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?fi=bus_probe_device#478 +pub fn bus_probe_device(dev: &Arc) { + bus_manager().probe_device(dev); +} + +#[derive(Debug)] +struct BusAttrDriversProbe; + +impl Attribute for BusAttrDriversProbe { + fn mode(&self) -> ModeType { + return ModeType::S_IWUSR; + } + + fn name(&self) -> &str { + return "drivers_probe"; + } + + fn support(&self) -> SysFSOpsSupport { + return SysFSOpsSupport::STORE; + } + + /// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?r=&mo=5649&fi=241#241 + fn store(&self, kobj: Arc, buf: &[u8]) -> Result { + let kset: Arc = kobj.arc_any().downcast().map_err(|_| SystemError::EINVAL)?; + let bus = bus_manager() + .get_bus_by_kset(&kset) + .ok_or(SystemError::EINVAL)?; + + let name = CStr::from_bytes_with_nul(buf) + .map_err(|_| SystemError::EINVAL)? + .to_str() + .map_err(|_| SystemError::EINVAL)?; + + let device = bus.find_device_by_name(name).ok_or(SystemError::ENODEV)?; + + if rescan_devices_helper(device).is_ok() { + return Ok(buf.len()); + } + + return Err(SystemError::EINVAL); + } +} + +#[derive(Debug)] +struct BusAttrDriversAutoprobe; + +impl Attribute for BusAttrDriversAutoprobe { + fn mode(&self) -> ModeType { + return ModeType::from_bits_truncate(0o644); + } + + fn name(&self) -> &str { + return "drivers_autoprobe"; + } + + fn support(&self) -> SysFSOpsSupport { + return SysFSOpsSupport::STORE | SysFSOpsSupport::SHOW; + } + + /// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?r=&mo=5649&fi=241#231 + fn store(&self, kobj: Arc, buf: &[u8]) -> Result { + if buf.len() == 0 { + return Ok(0); + } + + let kset: Arc = kobj.arc_any().downcast().map_err(|_| SystemError::EINVAL)?; + let bus = bus_manager() + .get_bus_by_kset(&kset) + .ok_or(SystemError::EINVAL)?; + + if buf[0] == '0' as u8 { + bus.subsystem().set_drivers_autoprobe(false); + } else { + bus.subsystem().set_drivers_autoprobe(true); + } + + return Ok(buf.len()); + } + + /// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?r=&mo=5649&fi=241#226 + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let kset: Arc = kobj.arc_any().downcast().map_err(|_| SystemError::EINVAL)?; + let bus = bus_manager() + .get_bus_by_kset(&kset) + .ok_or(SystemError::EINVAL)?; + let val = if bus.subsystem().drivers_autoprobe() { + 1 + } else { + 0 + }; + return sysfs_emit_str(buf, format!("{val}\n").as_str()); + } +} + +#[allow(dead_code)] +#[derive(Debug, Clone, Copy)] +pub enum BusNotifyEvent { + /// 一个设备被添加到总线上 + AddDevice, + /// 一个设备将要被移除 + DelDevice, + /// 一个设备已经被移除 + RemovedDevice, + /// 一个驱动将要被绑定 + BindDriver, + /// 一个驱动已经被绑定 + BoundDriver, + /// 一个驱动将要被解绑 + UnbindDriver, + /// 一个驱动已经被解绑 + UnboundDriver, + /// 驱动绑定失败 + DriverNotBound, } diff --git a/kernel/src/driver/base/device/dd.rs b/kernel/src/driver/base/device/dd.rs new file mode 100644 index 00000000..9dcc777b --- /dev/null +++ b/kernel/src/driver/base/device/dd.rs @@ -0,0 +1,210 @@ +use core::intrinsics::unlikely; + +use alloc::sync::Arc; + +use crate::{driver::Driver, syscall::SystemError}; + +use super::{bus::BusNotifyEvent, driver::driver_manager, Device, DeviceManager}; + +impl DeviceManager { + /// 尝试把一个设备与一个驱动匹配 + /// + /// 当前函数会遍历整个bus的驱动列表,并且尝试把设备与每一个驱动进行匹配。 + /// 一旦有一个驱动匹配成功,就会返回。 + /// + /// ## 参数 + /// + /// - `dev`: 设备 + /// + /// ## 返回 + /// + /// - Ok(true): 匹配成功 + /// - Ok(false): 没有匹配成功 + /// - Err(SystemError::ENODEV): 设备还没被注册 + /// + /// ## 参考 + /// + /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#1049 + pub fn device_attach(&self, dev: &Arc) -> Result { + return self.do_device_attach(dev, false); + } + + pub fn device_initial_probe(&self, dev: &Arc) -> Result { + return self.do_device_attach(dev, true); + } + + /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#978 + fn do_device_attach( + &self, + dev: &Arc, + allow_async: bool, + ) -> Result { + if unlikely(allow_async) { + todo!("do_device_attach: allow_async") + } + if dev.is_dead() { + return Ok(false); + } + + let mut do_async = false; + let mut r = Ok(false); + + if dev.driver().is_some() { + if self.device_is_bound(dev) { + return Ok(true); + } + + if self.device_bind_driver(dev).is_ok() { + return Ok(true); + } else { + dev.set_driver(None); + return Ok(false); + } + } else { + let bus = dev.bus().ok_or(SystemError::EINVAL)?; + let mut data = DeviceAttachData::new(dev.clone(), allow_async, false); + let mut flag = true; + for driver in bus.subsystem().drivers().read().iter() { + if let Some(driver) = driver.upgrade() { + let r = self.do_device_attach_driver(&driver, &mut data); + if unlikely(r.is_err()) { + flag = false; + break; + } + } + } + + if flag { + r = Ok(true); + } + + if !flag && allow_async && data.have_async { + // If we could not find appropriate driver + // synchronously and we are allowed to do + // async probes and there are drivers that + // want to probe asynchronously, we'll + // try them. + + do_async = true; + kdebug!( + "do_device_attach: try scheduling asynchronous probe for device: {}", + dev.name() + ); + } + } + + if do_async { + todo!("do_device_attach: do_async") + } + return r; + } + + /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#899 + fn do_device_attach_driver( + &self, + _driver: &Arc, + _data: &mut DeviceAttachData, + ) -> Result<(), SystemError> { + todo!("do_device_attach_driver") + } + + /// 检查设备是否绑定到驱动程序 + /// + /// ## 参数 + /// + /// - `dev`: 设备 + /// + /// ## 返回 + /// + /// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。 + pub fn device_is_bound(&self, dev: &Arc) -> bool { + if dev.driver().is_some() { + return true; + } else { + return false; + } + } + + /// 把一个驱动绑定到设备上 + /// + /// 允许手动绑定驱动到设备上。调用者需要设置好dev.driver(),保证其不为None + /// + /// ## 参数 + /// + /// - `dev`: 设备 + /// + /// ## 建议 + /// + /// 使用device_manager().driver_attach()会更好 + /// + /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#496 + pub fn device_bind_driver(&self, dev: &Arc) -> Result<(), SystemError> { + let r = driver_manager().driver_sysfs_add(dev); + if let Err(e) = r { + self.device_links_force_bind(dev); + self.driver_bound(dev); + return Err(e); + } else { + if let Some(bus) = dev.bus() { + bus.subsystem().bus_notifier().call_chain( + BusNotifyEvent::DriverNotBound, + Some(dev), + None, + ); + } + } + return r; + } + + /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#393 + fn driver_bound(&self, _dev: &Arc) { + todo!("driver_bound") + } +} + +/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#866 +#[derive(Debug)] +#[allow(dead_code)] +struct DeviceAttachData { + dev: Arc, + + /// Indicates whether we are considering asynchronous probing or + /// not. Only initial binding after device or driver registration + /// (including deferral processing) may be done asynchronously, the + /// rest is always synchronous, as we expect it is being done by + /// request from userspace. + check_async: bool, + + /// Indicates if we are binding synchronous or asynchronous drivers. + /// When asynchronous probing is enabled we'll execute 2 passes + /// over drivers: first pass doing synchronous probing and second + /// doing asynchronous probing (if synchronous did not succeed - + /// most likely because there was no driver requiring synchronous + /// probing - and we found asynchronous driver during first pass). + /// The 2 passes are done because we can't shoot asynchronous + /// probe for given device and driver from bus_for_each_drv() since + /// driver pointer is not guaranteed to stay valid once + /// bus_for_each_drv() iterates to the next driver on the bus. + want_async: bool, + + /// We'll set have_async to 'true' if, while scanning for matching + /// driver, we'll encounter one that requests asynchronous probing. + have_async: bool, +} + +impl DeviceAttachData { + pub fn new(dev: Arc, check_async: bool, want_async: bool) -> Self { + Self { + dev, + check_async, + want_async, + have_async: false, + } + } + + #[allow(dead_code)] + #[inline(always)] + fn set_have_async(&mut self) { + self.have_async = true; + } +} diff --git a/kernel/src/driver/base/device/driver.rs b/kernel/src/driver/base/device/driver.rs index 9ac4d9a7..d6afc34f 100644 --- a/kernel/src/driver/base/device/driver.rs +++ b/kernel/src/driver/base/device/driver.rs @@ -1,14 +1,8 @@ -use super::IdTable; -use crate::{ - driver::Driver, filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError, -}; -use alloc::{collections::BTreeMap, sync::Arc}; +use super::Device; +use crate::syscall::SystemError; +use alloc::sync::Arc; use core::fmt::Debug; -lazy_static! { - pub static ref DRIVER_MANAGER: Arc = Arc::new(LockedDriverManager::new()); -} - /// @brief: Driver error #[allow(dead_code)] #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -32,93 +26,18 @@ impl Into for DriverError { } } -/// @brief: 驱动管理器(锁) -#[derive(Debug)] -pub struct LockedDriverManager(SpinLock); - -impl LockedDriverManager { - /// @brief: 创建一个新的驱动管理器(锁) - /// @parameter None - /// @return: LockedDriverManager实体 - #[inline] - fn new() -> LockedDriverManager { - LockedDriverManager(SpinLock::new(DriverManager::new())) - } - - /// @brief: 添加驱动 - /// @parameter id_table: 驱动标识符,用于唯一标识该驱动 - /// @parameter drv: 驱动实例 - /// @return: None - #[inline] - #[allow(dead_code)] - pub fn add_driver(&self, id_table: IdTable, drv: Arc) { - let mut driver_manager = self.0.lock(); - driver_manager.drivers.insert(id_table, drv); - } - - /// @brief: 卸载驱动 - /// @parameter id_table: 驱动标识符,用于唯一标识该驱动 - /// @return: None - #[inline] - #[allow(dead_code)] - pub fn remove_driver(&self, id_table: &IdTable) { - let mut driver_manager = self.0.lock(); - driver_manager.drivers.remove(id_table); - } - - /// @brief: 获取驱动 - /// @parameter id_table: 驱动标识符,用于唯一标识该驱动 - /// @return: 驱动实例 - #[inline] - #[allow(dead_code)] - pub fn get_driver(&self, id_table: &IdTable) -> Option> { - let driver_manager = self.0.lock(); - driver_manager.drivers.get(id_table).cloned() - } - - /// @brief: 获取驱动管理器的sys information - /// @parameter id_table: 设备标识符,用于唯一标识该驱动 - /// @return: 驱动实例 - #[inline] - #[allow(dead_code)] - fn get_sys_info(&self) -> Option> { - return self.0.lock().sys_info.clone(); - } +#[inline(always)] +pub fn driver_manager() -> &'static DriverManager { + &DriverManager } /// @brief: 驱动管理器 #[derive(Debug, Clone)] -pub struct DriverManager { - drivers: BTreeMap>, // 所有驱动 - sys_info: Option>, // sys information -} +pub struct DriverManager; impl DriverManager { - /// @brief: 创建一个新的设备管理器 - /// @parameter: None - /// @return: Manager实体 - #[inline] - fn new() -> DriverManager { - DriverManager { - drivers: BTreeMap::new(), - sys_info: None, - } + /// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#434 + pub fn driver_sysfs_add(&self, _dev: &Arc) -> Result<(), SystemError> { + todo!("DriverManager::driver_sysfs_add()"); } } - -/// @brief: 驱动注册 -/// @parameter: name: 驱动名 -/// @return: 操作成功,返回(),操作失败,返回错误码 -pub fn driver_register(driver: Arc) -> Result<(), DriverError> { - DRIVER_MANAGER.add_driver(driver.id_table(), driver); - return Ok(()); -} - -/// @brief: 驱动卸载 -/// @parameter: name: 驱动名 -/// @return: 操作成功,返回(),操作失败,返回错误码 -#[allow(dead_code)] -pub fn driver_unregister(driver: Arc) -> Result<(), DriverError> { - DRIVER_MANAGER.remove_driver(&driver.id_table()); - return Ok(()); -} diff --git a/kernel/src/driver/base/device/init.rs b/kernel/src/driver/base/device/init.rs index 09395250..65b8f4eb 100644 --- a/kernel/src/driver/base/device/init.rs +++ b/kernel/src/driver/base/device/init.rs @@ -1,16 +1,78 @@ -use crate::{driver::uart::uart_device::uart_init, kinfo, syscall::SystemError}; +use alloc::{string::ToString, sync::Arc}; -#[no_mangle] -pub extern "C" fn rs_device_init() -> i32 { - let result = device_init() - .map(|_| 0) - .unwrap_or_else(|e| e.to_posix_errno()); - - return result; -} +use crate::{ + driver::{ + base::{ + device::{ + sys_dev_kset, DeviceManager, DEVICES_KSET_INSTANCE, DEVICE_MANAGER, + DEV_KSET_INSTANCE, + }, + kobject::KObject, + kset::KSet, + }, + uart::uart_device::uart_init, + }, + kdebug, kinfo, + syscall::SystemError, +}; pub fn device_init() -> Result<(), SystemError> { uart_init()?; kinfo!("device init success"); return Ok(()); } + +pub fn devices_init() -> Result<(), SystemError> { + // 创建 `/sys/devices` 目录 + { + let devices_kset = KSet::new("devices".to_string()); + devices_kset + .register(None) + .expect("register devices kset failed"); + + unsafe { + DEVICES_KSET_INSTANCE = Some(devices_kset); + // 初始化全局设备管理器 + DEVICE_MANAGER = Some(DeviceManager::new()); + } + } + + // 创建 `/sys/dev` 目录 + { + let dev_kset = KSet::new("dev".to_string()); + dev_kset.register(None).expect("register dev kset failed"); + unsafe { + DEV_KSET_INSTANCE = Some(dev_kset); + } + } + + // 创建 `/sys/dev/block` 目录 + { + kdebug!("create /sys/dev/block"); + let dev_kset = sys_dev_kset(); + let dev_block_kset = KSet::new("block".to_string()); + let parent = dev_kset.clone() as Arc; + dev_block_kset.set_parent(Some(Arc::downgrade(&parent))); + + dev_block_kset + .register(Some(dev_kset)) + .expect("register dev block kset failed"); + } + + // 创建 `/sys/dev/char` 目录 + { + kdebug!("create /sys/dev/char"); + let dev_kset = sys_dev_kset(); + let dev_char_kset = KSet::new("char".to_string()); + let parent = dev_kset.clone() as Arc; + dev_char_kset.set_parent(Some(Arc::downgrade(&parent))); + + dev_char_kset + .register(Some(dev_kset)) + .expect("register dev char kset failed"); + } + + kinfo!("devices init success"); + device_init()?; + return Ok(()); +} diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index 84a12879..98ad788b 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/kernel/src/driver/base/device/mod.rs @@ -1,32 +1,45 @@ use alloc::{ - collections::BTreeMap, string::{String, ToString}, sync::Arc, }; +use intertrait::cast::CastArc; use crate::{ - driver::base::map::{LockedDevsMap, LockedKObjMap}, - filesystem::{ - sysfs::{ - devices::{sys_device_register, sys_device_unregister}, - SYS_DEVICES_INODE, - }, - vfs::IndexNode, + driver::{ + acpi::glue::acpi_device_notify, + base::map::{LockedDevsMap, LockedKObjMap}, + Driver, + }, + filesystem::{ + sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport}, + vfs::syscall::ModeType, }, - libs::spinlock::SpinLock, syscall::SystemError, }; -use core::{any::Any, fmt::Debug}; +use core::fmt::Debug; +use core::intrinsics::unlikely; -use super::platform::CompatibleTable; +use self::bus::{bus_add_device, bus_probe_device, Bus}; + +use super::{ + kobject::{KObjType, KObject, KObjectManager}, + kset::KSet, + platform::CompatibleTable, + swnode::software_node_notify, +}; pub mod bus; +pub mod dd; pub mod driver; pub mod init; -lazy_static! { - pub static ref DEVICE_MANAGER: Arc = Arc::new(LockedDeviceManager::new()); +static mut DEVICE_MANAGER: Option = None; + +#[inline(always)] +pub fn device_manager() -> &'static DeviceManager { + unsafe { DEVICE_MANAGER.as_ref().unwrap() } } + lazy_static! { // 全局字符设备号管理实例 pub static ref CHARDEVS: Arc = Arc::new(LockedDevsMap::default()); @@ -39,12 +52,47 @@ lazy_static! { } -pub trait KObject: Any + Send + Sync + Debug {} -/// @brief 设备应该实现的操作 -/// @usage Device::read_at() +/// `/sys/devices` 的 kset 实例 +static mut DEVICES_KSET_INSTANCE: Option> = None; +/// `/sys/dev` 的 kset 实例 +static mut DEV_KSET_INSTANCE: Option> = None; +/// `/sys/dev/block` 的 kset 实例 +static mut DEV_BLOCK_KSET_INSTANCE: Option> = None; +/// `/sys/dev/char` 的 kset 实例 +static mut DEV_CHAR_KSET_INSTANCE: Option> = None; + +#[inline(always)] +pub(super) fn sys_devices_kset() -> Arc { + unsafe { DEVICES_KSET_INSTANCE.as_ref().unwrap().clone() } +} + +#[inline(always)] +pub(super) fn sys_dev_kset() -> Arc { + unsafe { DEV_KSET_INSTANCE.as_ref().unwrap().clone() } +} + +#[inline(always)] +#[allow(dead_code)] +pub(super) fn sys_dev_block_kset() -> Arc { + unsafe { DEV_BLOCK_KSET_INSTANCE.as_ref().unwrap().clone() } +} + +#[inline(always)] +pub(self) fn sys_dev_char_kset() -> Arc { + unsafe { DEV_CHAR_KSET_INSTANCE.as_ref().unwrap().clone() } +} + +/// 设备应该实现的操作 +/// +/// ## 注意 +/// +/// 由于设备驱动模型需要从Arc转换为Arc, +/// 因此,所有的实现了Device trait的结构体,都应该在结构体上方标注`#[[sync] Device]`, +/// +/// 否则在释放设备资源的时候,会由于无法转换为Arc而导致资源泄露,并且release回调函数也不会被调用。 pub trait Device: KObject { // TODO: 待实现 open, close - fn as_any_ref(&self) -> &dyn core::any::Any; + /// @brief: 获取设备类型 /// @parameter: None /// @return: 实现该trait的设备所属类型 @@ -55,15 +103,27 @@ pub trait Device: KObject { /// @return: 该设备唯一标识 fn id_table(&self) -> IdTable; - /// @brief: 设置sysfs info - /// @parameter: None - /// @return: 该设备唯一标识 - fn set_sys_info(&self, _sys_info: Option>); + /// 设备释放时的回调函数 + fn release(&self) { + let name = self.name(); + kwarn!( + "device {} does not have a release() function, it is broken and must be fixed.", + name + ); + } - /// @brief: 获取设备的sys information - /// @parameter id_table: 设备标识符,用于唯一标识该设备 - /// @return: 设备实例 - fn sys_info(&self) -> Option>; + /// 获取当前设备所属的总线 + fn bus(&self) -> Option> { + return None; + } + + /// 返回已经与当前设备匹配好的驱动程序 + fn driver(&self) -> Option>; + + fn set_driver(&self, driver: Option>); + + /// 当前设备是否已经挂掉了 + fn is_dead(&self) -> bool; } // 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息 @@ -155,14 +215,14 @@ impl DeviceNumber { /// @parameter: none /// @return: 主设备号 pub fn major(&self) -> usize { - (self.0 >> 20) & 0xfff + (self.0 >> 8) & 0xffffff } /// @brief: 获取次设备号 /// @parameter: none /// @return: 次设备号 pub fn minor(&self) -> usize { - self.0 & 0xfffff + self.0 & 0xff } pub fn from_major_minor(major: usize, minor: usize) -> usize { @@ -211,7 +271,7 @@ impl IdTable { /// @parameter None /// @return: 设备名 pub fn name(&self) -> String { - return format!("{}:{:?}", self.0, self.1 .0); + return format!("{}:{}", self.0, self.1 .0); } pub fn device_number(&self) -> DeviceNumber { @@ -285,24 +345,115 @@ impl From for u32 { } } -/// @brief Device管理器(锁) #[derive(Debug)] -pub struct LockedDeviceManager(SpinLock); +pub struct DeviceKObjType; -impl LockedDeviceManager { - fn new() -> LockedDeviceManager { - LockedDeviceManager(SpinLock::new(DeviceManager::new())) +impl KObjType for DeviceKObjType { + // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#2307 + fn release(&self, kobj: Arc) { + let dev = kobj.cast::().unwrap(); + /* + * Some platform devices are driven without driver attached + * and managed resources may have been acquired. Make sure + * all resources are released. + * + * Drivers still can add resources into device after device + * is deleted but alive, so release devres here to avoid + * possible memory leak. + */ + + // todo: 在引入devres之后再实现 + // devres_release_all(kobj); + dev.release(); + } + + fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { + None + } + + fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { + Some(&DeviceSysFSOps) + } +} + +#[derive(Debug)] +pub(super) struct DeviceSysFSOps; + +impl SysFSOps for DeviceSysFSOps { + fn store( + &self, + kobj: Arc, + attr: &dyn Attribute, + buf: &[u8], + ) -> Result { + return attr.store(kobj, buf); + } + + fn show( + &self, + kobj: Arc, + attr: &dyn Attribute, + buf: &mut [u8], + ) -> Result { + return attr.show(kobj, buf); + } +} + +/// @brief Device管理器 +#[derive(Debug)] +pub struct DeviceManager; + +impl DeviceManager { + /// @brief: 创建一个新的设备管理器 + /// @parameter: None + /// @return: DeviceManager实体 + #[inline] + const fn new() -> DeviceManager { + return Self; } /// @brief: 添加设备 /// @parameter id_table: 总线标识符,用于唯一标识该总线 /// @parameter dev: 设备实例 /// @return: None + /// + /// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3398 + /// + /// todo: 完善错误处理逻辑:如果添加失败,需要将之前添加的内容全部回滚 #[inline] #[allow(dead_code)] - pub fn add_device(&self, id_table: IdTable, dev: Arc) { - let mut device_manager = self.0.lock(); - device_manager.devices.insert(id_table, dev); + pub fn add_device(&self, device: Arc) -> Result<(), SystemError> { + // todo: 引入class后,在这里处理与parent相关的逻辑 + + KObjectManager::add_kobj(device.clone() as Arc, None).map_err(|e| { + kerror!("add device '{:?}' failed: {:?}", device.name(), e); + e + })?; + + self.device_platform_notify(&device); + + self.add_class_symlinks(&device)?; + + self.add_attrs(&device)?; + + bus_add_device(&device)?; + + if device.id_table().device_number().major() != 0 { + self.create_file(&device, &DeviceAttrDev)?; + + self.create_sys_dev_entry(&device)?; + } + + // todo: Notify clients of device addition.This call must come + // after dpm_sysfs_add() and before kobject_uevent(). + // 参考:https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3491 + + // todo: 发送uevent + + // probe drivers for a new device + bus_probe_device(&device); + + return Ok(()); } /// @brief: 卸载设备 @@ -310,9 +461,8 @@ impl LockedDeviceManager { /// @return: None #[inline] #[allow(dead_code)] - pub fn remove_device(&self, id_table: &IdTable) { - let mut device_manager = self.0.lock(); - device_manager.devices.remove(id_table); + pub fn remove_device(&self, _id_table: &IdTable) { + todo!() } /// @brief: 获取设备 @@ -320,65 +470,205 @@ impl LockedDeviceManager { /// @return: 设备实例 #[inline] #[allow(dead_code)] - pub fn get_device(&self, id_table: &IdTable) -> Option> { - let device_manager = self.0.lock(); - device_manager.devices.get(id_table).cloned() + pub fn find_device_by_idtable(&self, _id_table: &IdTable) -> Option> { + todo!("find_device_by_idtable") } - /// @brief: 获取设备管理器的sys information - /// @parameter id_table: 设备标识符,用于唯一标识该设备 - /// @return: 设备实例 - #[inline] - #[allow(dead_code)] - fn sys_info(&self) -> Option> { - return self.0.lock().sys_info.clone(); + fn device_platform_notify(&self, dev: &Arc) { + acpi_device_notify(dev); + software_node_notify(dev); } -} -/// @brief Device管理器 -#[derive(Debug, Clone)] -pub struct DeviceManager { - devices: BTreeMap>, // 所有设备 - sys_info: Option>, // sys information -} + fn add_class_symlinks(&self, _dev: &Arc) -> Result<(), SystemError> { + // todo: 引入class后,在这里处理与class相关的逻辑 + // https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3224 -impl DeviceManager { - /// @brief: 创建一个新的设备管理器 - /// @parameter: None - /// @return: DeviceManager实体 - #[inline] - fn new() -> DeviceManager { - DeviceManager { - devices: BTreeMap::new(), - sys_info: Some(SYS_DEVICES_INODE()), + return Ok(()); + } + + /// 在sysfs中,为指定的设备创建属性文件 + /// + /// ## 参数 + /// + /// - `dev`: 设备 + fn add_attrs(&self, dev: &Arc) -> Result<(), SystemError> { + let kobj_type = dev.kobj_type(); + if kobj_type.is_none() { + return Ok(()); } + + let kobj_type = kobj_type.unwrap(); + + let attr_groups = kobj_type.attribute_groups(); + + if attr_groups.is_none() { + return Ok(()); + } + + self.add_groups(dev, attr_groups.unwrap())?; + + return Ok(()); + } + + /// 在sysfs中,为指定的设备创建属性组,以及属性组中的属性文件 + /// + /// ## 参数 + /// + /// - `dev`: 设备 + /// - `attr_groups`: 属性组 + pub fn add_groups( + &self, + dev: &Arc, + attr_groups: &'static [&dyn AttributeGroup], + ) -> Result<(), SystemError> { + let dev = dev.clone(); + let binding = dev.arc_any(); + let kobj: &Arc = binding.downcast_ref().unwrap(); + return sysfs_instance().create_groups(kobj, attr_groups); + } + + /// 为设备在sysfs中创建属性文件 + /// + /// ## 参数 + /// + /// - `dev`: 设备 + /// - `attr`: 属性 + pub fn create_file( + &self, + dev: &Arc, + attr: &'static dyn Attribute, + ) -> Result<(), SystemError> { + if unlikely( + attr.mode().contains(ModeType::S_IRUGO) + && (!attr.support().contains(SysFSOpsSupport::SHOW)), + ) { + kwarn!( + "Attribute '{}': read permission without 'show'", + attr.name() + ); + } + if unlikely( + attr.mode().contains(ModeType::S_IWUGO) + && (!attr.support().contains(SysFSOpsSupport::STORE)), + ) { + kwarn!( + "Attribute '{}': write permission without 'store'", + attr.name() + ); + } + + let kobj = dev.clone() as Arc; + + return sysfs_instance().create_file(&kobj, attr); + } + + /// 在/sys/dev下,或者设备所属的class下,为指定的设备创建链接 + fn create_sys_dev_entry(&self, dev: &Arc) -> Result<(), SystemError> { + let target_kobj = self.device_to_dev_kobj(dev); + let name = dev.id_table().name(); + let current_kobj = dev.clone() as Arc; + return sysfs_instance().create_link(¤t_kobj, &target_kobj, name); + } + + /// Delete symlink for device in `/sys/dev` or `/sys/class/` + #[allow(dead_code)] + fn remove_sys_dev_entry(&self, dev: &Arc) -> Result<(), SystemError> { + let kobj = self.device_to_dev_kobj(dev); + let name = dev.id_table().name(); + return sysfs_instance().remove_link(&kobj, name); + } + + /// device_to_dev_kobj - select a /sys/dev/ directory for the device + /// + /// By default we select char/ for new entries. + /// + /// ## 参数 + /// + /// - `dev`: 设备 + fn device_to_dev_kobj(&self, _dev: &Arc) -> Arc { + // todo: 处理class的逻辑 + let kobj = sys_dev_char_kset().as_kobject(); + return kobj; + } + + /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_links_force_bind#1226 + pub fn device_links_force_bind(&self, _dev: &Arc) { + todo!("device_links_force_bind") } } /// @brief: 设备注册 /// @parameter: name: 设备名 /// @return: 操作成功,返回(),操作失败,返回错误码 -pub fn device_register(device: Arc) -> Result<(), DeviceError> { - DEVICE_MANAGER.add_device(device.id_table(), device.clone()); - match sys_device_register(&device.id_table().name()) { - Ok(sys_info) => { - device.set_sys_info(Some(sys_info)); - return Ok(()); - } - Err(_) => Err(DeviceError::RegisterError), - } +pub fn device_register(device: Arc) -> Result<(), SystemError> { + return device_manager().add_device(device); } /// @brief: 设备卸载 /// @parameter: name: 设备名 /// @return: 操作成功,返回(),操作失败,返回错误码 -pub fn device_unregister(device: Arc) -> Result<(), DeviceError> { - DEVICE_MANAGER.add_device(device.id_table(), device.clone()); - match sys_device_unregister(&device.id_table().name()) { - Ok(_) => { - device.set_sys_info(None); - return Ok(()); - } - Err(_) => Err(DeviceError::RegisterError), +pub fn device_unregister(_device: Arc) { + // DEVICE_MANAGER.add_device(device.id_table(), device.clone()); + // match sys_device_unregister(&device.id_table().name()) { + // Ok(_) => { + // device.set_inode(None); + // return Ok(()); + // } + // Err(_) => Err(DeviceError::RegisterError), + // } + todo!("device_unregister") +} + +/// 设备文件夹下的`dev`文件的属性 +#[derive(Debug, Clone, Copy)] +pub struct DeviceAttrDev; + +impl Attribute for DeviceAttrDev { + fn mode(&self) -> ModeType { + // 0o444 + return ModeType::S_IRUGO; + } + + fn name(&self) -> &str { + "dev" + } + + fn show(&self, kobj: Arc, _buf: &mut [u8]) -> Result { + let dev = kobj.cast::().map_err(|kobj| { + kerror!( + "Intertrait casting not implemented for kobj: {}", + kobj.name() + ); + SystemError::EOPNOTSUPP_OR_ENOTSUP + })?; + + return Ok(dev.id_table().device_number().into()); + } + + fn support(&self) -> SysFSOpsSupport { + SysFSOpsSupport::SHOW + } +} + +/// 设备匹配器 +/// +/// 用于匹配设备是否符合某个条件 +/// +/// ## 参数 +/// +/// - `T` - 匹配器的数据类型 +/// - `data` - 匹配器的数据 +pub trait DeviceMatcher: Debug { + fn match_device(&self, device: &Arc, data: T) -> bool; +} + +/// 用于根据名称匹配设备的匹配器 +#[derive(Debug)] +pub struct DeviceMatchName; + +impl DeviceMatcher<&str> for DeviceMatchName { + #[inline] + fn match_device(&self, device: &Arc, data: &str) -> bool { + return device.name() == data; } } diff --git a/kernel/src/driver/base/firmware.rs b/kernel/src/driver/base/firmware.rs new file mode 100644 index 00000000..5bb597c8 --- /dev/null +++ b/kernel/src/driver/base/firmware.rs @@ -0,0 +1,26 @@ +use alloc::{string::ToString, sync::Arc}; + +use crate::syscall::SystemError; + +use super::kset::KSet; + +/// `/sys/firmware`的kset +static mut FIRMWARE_KSET_INSTANCE: Option> = None; + +#[inline(always)] +#[allow(dead_code)] +pub fn sys_firmware_kset() -> Arc { + unsafe { FIRMWARE_KSET_INSTANCE.clone().unwrap() } +} + +/// 初始化`/sys/firmware`的kset +pub(super) fn firmware_init() -> Result<(), SystemError> { + let firmware_kset = KSet::new("firmware".to_string()); + firmware_kset + .register(None) + .expect("register firmware kset failed"); + unsafe { + FIRMWARE_KSET_INSTANCE = Some(firmware_kset); + } + return Ok(()); +} diff --git a/kernel/src/driver/base/hypervisor.rs b/kernel/src/driver/base/hypervisor.rs new file mode 100644 index 00000000..a7aff481 --- /dev/null +++ b/kernel/src/driver/base/hypervisor.rs @@ -0,0 +1,26 @@ +use alloc::{string::ToString, sync::Arc}; + +use crate::syscall::SystemError; + +use super::kset::KSet; + +/// `/sys/hypervisor`的kset +static mut HYPERVISOR_KSET_INSTANCE: Option> = None; + +#[inline(always)] +#[allow(dead_code)] +pub fn sys_hypervisor_kset() -> Arc { + unsafe { HYPERVISOR_KSET_INSTANCE.clone().unwrap() } +} + +/// 初始化`/sys/hypervisor`的kset +pub(super) fn hypervisor_init() -> Result<(), SystemError> { + let hypervisor_kset = KSet::new("hypervisor".to_string()); + hypervisor_kset + .register(None) + .expect("register hypervisor kset failed"); + unsafe { + HYPERVISOR_KSET_INSTANCE = Some(hypervisor_kset); + } + return Ok(()); +} diff --git a/kernel/src/driver/base/init.rs b/kernel/src/driver/base/init.rs new file mode 100644 index 00000000..62c40737 --- /dev/null +++ b/kernel/src/driver/base/init.rs @@ -0,0 +1,19 @@ +use crate::syscall::SystemError; + +use super::{ + class::classes_init, + device::{bus::buses_init, init::devices_init}, + firmware::firmware_init, + hypervisor::hypervisor_init, + platform::platform_bus_init, +}; + +pub(super) fn driver_init() -> Result<(), SystemError> { + devices_init()?; + buses_init()?; + classes_init()?; + firmware_init()?; + hypervisor_init()?; + platform_bus_init()?; + return Ok(()); +} diff --git a/kernel/src/driver/base/kobject.rs b/kernel/src/driver/base/kobject.rs new file mode 100644 index 00000000..e845a8c1 --- /dev/null +++ b/kernel/src/driver/base/kobject.rs @@ -0,0 +1,211 @@ +use core::{any::Any, fmt::Debug, hash::Hash, ops::Deref}; + +use alloc::{ + string::String, + sync::{Arc, Weak}, +}; +use intertrait::CastFromSync; + +use crate::{ + filesystem::{ + kernfs::KernFSInode, + sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport}, + }, + kerror, + libs::{ + casting::DowncastArc, + rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, + }, + syscall::SystemError, +}; + +use super::kset::KSet; + +pub trait KObject: Any + Send + Sync + Debug + CastFromSync { + fn as_any_ref(&self) -> &dyn core::any::Any; + + /// 设置当前kobject对应的sysfs inode(类型为KernFSInode) + fn set_inode(&self, inode: Option>); + + /// 获取当前kobject对应的sysfs inode(类型为KernFSInode) + fn inode(&self) -> Option>; + + fn parent(&self) -> Option>; + + /// 设置当前kobject的parent kobject(不一定与kset相同) + fn set_parent(&self, parent: Option>); + + /// 当前kobject属于哪个kset + fn kset(&self) -> Option>; + + /// 设置当前kobject所属的kset + fn set_kset(&self, kset: Option>); + + fn kobj_type(&self) -> Option<&'static dyn KObjType>; + + fn name(&self) -> String; + + fn set_name(&self, name: String); + + fn kobj_state(&self) -> RwLockReadGuard; + + fn kobj_state_mut(&self) -> RwLockWriteGuard; + + fn set_kobj_state(&self, state: KObjectState); +} + +impl dyn KObject { + /// 更新kobject的状态 + pub fn update_kobj_state(&self, insert: Option, remove: Option) { + let insert = insert.unwrap_or(KObjectState::empty()); + let remove = remove.unwrap_or(KObjectState::empty()); + let mut state = self.kobj_state_mut(); + *state = (*state | insert) & !remove; + } +} + +impl DowncastArc for dyn KObject { + fn as_any_arc(self: Arc) -> Arc { + self + } +} + +pub trait KObjType: Debug { + fn release(&self, _kobj: Arc) {} + fn sysfs_ops(&self) -> Option<&dyn SysFSOps>; + + fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]>; +} + +bitflags! { + pub struct KObjectState: u32 { + const IN_SYSFS = 1 << 0; + const ADD_UEVENT_SENT = 1 << 1; + const REMOVE_UEVENT_SENT = 1 << 2; + const INITIALIZED = 1 << 3; + } + +} + +#[derive(Debug)] +pub struct LockedKObjectState(RwLock); + +impl LockedKObjectState { + pub const fn new(state: KObjectState) -> LockedKObjectState { + LockedKObjectState(RwLock::new(state)) + } +} + +impl Deref for LockedKObjectState { + type Target = RwLock; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub trait KObjectAttribute: Attribute { + fn support(&self) -> SysFSOpsSupport; + + fn show(&self, kobj: &dyn KObject, buf: &mut [u8]) -> Result; + fn store(&self, kobj: &dyn KObject, buf: &[u8]) -> Result; +} + +#[derive(Debug)] +pub struct KObjectSysFSOps; + +impl SysFSOps for KObjectSysFSOps { + fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport { + return attr.support(); + } + + fn show( + &self, + kobj: Arc, + attr: &dyn Attribute, + buf: &mut [u8], + ) -> Result { + let r = attr.show(kobj, buf).map_err(|e| { + if e == SystemError::EOPNOTSUPP_OR_ENOTSUP { + SystemError::EIO + } else { + e + } + }); + + return r; + } + + fn store( + &self, + kobj: Arc, + attr: &dyn Attribute, + buf: &[u8], + ) -> Result { + let r = attr.store(kobj, buf).map_err(|e| { + if e == SystemError::EOPNOTSUPP_OR_ENOTSUP { + SystemError::EIO + } else { + e + } + }); + + return r; + } +} + +#[derive(Debug)] +pub struct KObjectManager; + +impl KObjectManager { + pub fn add_kobj( + kobj: Arc, + join_kset: Option>, + ) -> Result<(), SystemError> { + if join_kset.is_some() { + let kset = join_kset.unwrap(); + kset.join(&kobj); + // 如果kobject没有parent,那么就将这个kset作为parent + if kobj.parent().is_none() { + kobj.set_parent(Some(Arc::downgrade(&(kset as Arc)))); + } + } + + let r = Self::create_dir(kobj.clone()); + + if let Err(e) = r { + // https://opengrok.ringotek.cn/xref/linux-6.1.9/lib/kobject.c?r=&mo=10426&fi=394#224 + if let Some(kset) = kobj.kset() { + kset.leave(&kobj); + } + kobj.set_parent(None); + if e == SystemError::EEXIST { + kerror!("KObjectManager::add_kobj() failed with error: {e:?}, kobj:{kobj:?}"); + } + + return Err(e); + } + + kobj.update_kobj_state(Some(KObjectState::IN_SYSFS), None); + return Ok(()); + } + + fn create_dir(kobj: Arc) -> Result<(), SystemError> { + // create dir in sysfs + sysfs_instance().create_dir(kobj.clone())?; + + // create default attributes in sysfs + if let Some(ktype) = kobj.kobj_type() { + let groups = ktype.attribute_groups(); + if let Some(groups) = groups { + let r = sysfs_instance().create_groups(&kobj, groups); + if let Err(e) = r { + sysfs_instance().remove_dir(&kobj); + return Err(e); + } + } + } + + return Ok(()); + } +} diff --git a/kernel/src/driver/base/kset.rs b/kernel/src/driver/base/kset.rs new file mode 100644 index 00000000..a59898bb --- /dev/null +++ b/kernel/src/driver/base/kset.rs @@ -0,0 +1,229 @@ +use alloc::{ + string::String, + sync::{Arc, Weak}, + vec::Vec, +}; + +use core::hash::Hash; + +use crate::{ + filesystem::{ + kernfs::KernFSInode, + sysfs::{AttributeGroup, SysFSOps}, + }, + libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}, + syscall::SystemError, +}; + +use super::kobject::{ + KObjType, KObject, KObjectManager, KObjectState, KObjectSysFSOps, LockedKObjectState, +}; + +#[derive(Debug)] +pub struct KSet { + /// 属于当前kset的kobject + kobjects: RwLock>>, + /// 节点的一些信息 + inner: RwLock, + /// kobject的状态 + kobj_state: LockedKObjectState, + /// 与父节点有关的一些信息 + parent_data: RwLock, + self_ref: Weak, +} + +impl Hash for KSet { + fn hash(&self, state: &mut H) { + self.self_ref.as_ptr().hash(state); + self.inner.read().name.hash(state); + } +} + +impl core::cmp::Eq for KSet {} + +impl core::cmp::PartialEq for KSet { + fn eq(&self, other: &Self) -> bool { + self.self_ref.as_ptr() == other.self_ref.as_ptr() + } +} + +impl KSet { + pub fn new(name: String) -> Arc { + let r = Self { + kobjects: RwLock::new(Vec::new()), + inner: RwLock::new(InnerKSet::new(name)), + kobj_state: LockedKObjectState::new(KObjectState::empty()), + parent_data: RwLock::new(KSetParentData::new(None, None)), + self_ref: Weak::default(), + }; + + let r = Arc::new(r); + + unsafe { + let p = r.as_ref() as *const Self as *mut Self; + (*p).self_ref = Arc::downgrade(&r); + } + + return r; + } + + /// 创建一个kset,并且设置它的父亲为parent_kobj。然后把这个kset注册到sysfs + /// + /// ## 参数 + /// + /// - name: kset的名字 + /// - parent_kobj: 父亲kobject + /// - join_kset: 如果不为None,那么这个kset会加入到join_kset中 + pub fn new_and_add( + name: String, + parent_kobj: Option>, + join_kset: Option>, + ) -> Result, SystemError> { + let kset = KSet::new(name); + if let Some(parent_kobj) = parent_kobj { + kset.set_parent(Some(Arc::downgrade(&parent_kobj))); + } + kset.register(join_kset)?; + return Ok(kset); + } + + pub fn register(&self, join_kset: Option>) -> Result<(), SystemError> { + return KObjectManager::add_kobj(self.self_ref.upgrade().unwrap(), join_kset); + // todo: 引入uevent之后,发送uevent + } + + /// 把一个kobject加入到当前kset中。 + /// + /// 该函数不会修改kobj的parent,需要调用者自己视情况修改。 + /// + /// ## Panic + /// + /// 这个kobject的kset必须是None,否则会panic + pub fn join(&self, kobj: &Arc) { + assert!(kobj.kset().is_none()); + kobj.set_kset(self.self_ref.upgrade()); + self.kobjects.write().push(Arc::downgrade(&kobj)); + } + + /// 把一个kobject从当前kset中移除。 + pub fn leave(&self, kobj: &Arc) { + let mut kobjects = self.kobjects.write(); + let index = kobjects.iter().position(|x| { + if let Some(x) = x.upgrade() { + return Arc::ptr_eq(&x, kobj); + } + return false; + }); + if let Some(index) = index { + let x = kobjects.remove(index); + let x = x.upgrade().unwrap(); + drop(kobjects); + x.set_kset(None); + } + } + + /// 清除所有已经被释放的kobject + #[allow(dead_code)] + pub fn cleanup_weak(&self) { + let mut kobjects = self.kobjects.write(); + kobjects.drain_filter(|x| x.upgrade().is_none()); + } + + pub fn as_kobject(&self) -> Arc { + return self.self_ref.upgrade().unwrap(); + } +} + +impl KObject for KSet { + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + fn inode(&self) -> Option> { + self.inner.read().kern_inode.clone() + } + + fn set_inode(&self, inode: Option>) { + self.inner.write().kern_inode = inode; + } + + fn parent(&self) -> Option> { + self.parent_data.read().parent.clone() + } + + fn set_parent(&self, parent: Option>) { + self.parent_data.write().parent = parent; + } + + fn kobj_state(&self) -> RwLockReadGuard { + self.kobj_state.read() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + self.kobj_state.write() + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + Some(&KSetKObjType) + } + + fn kset(&self) -> Option> { + self.parent_data.read().kset.clone() + } + + fn set_kset(&self, kset: Option>) { + self.parent_data.write().kset = kset; + } + + fn name(&self) -> String { + return self.inner.read().name.clone(); + } + + fn set_name(&self, name: String) { + self.inner.write().name = name; + } + + fn set_kobj_state(&self, state: KObjectState) { + *self.kobj_state.write() = state; + } +} + +#[derive(Debug)] +struct KSetParentData { + parent: Option>, + kset: Option>, +} + +impl KSetParentData { + fn new(parent: Option>, kset: Option>) -> Self { + Self { parent, kset } + } +} + +#[derive(Debug)] +struct InnerKSet { + kern_inode: Option>, + name: String, +} + +impl InnerKSet { + fn new(name: String) -> Self { + Self { + kern_inode: None, + name, + } + } +} + +#[derive(Debug)] +pub struct KSetKObjType; + +impl KObjType for KSetKObjType { + fn sysfs_ops(&self) -> Option<&dyn SysFSOps> { + Some(&KObjectSysFSOps) + } + + fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { + None + } +} diff --git a/kernel/src/driver/base/map/mod.rs b/kernel/src/driver/base/map/mod.rs index d74caa37..eee439cd 100644 --- a/kernel/src/driver/base/map/mod.rs +++ b/kernel/src/driver/base/map/mod.rs @@ -1,6 +1,9 @@ use core::ops::{Deref, DerefMut}; -use super::device::{mkdev, DeviceNumber, KObject}; +use super::{ + device::{mkdev, DeviceNumber}, + kobject::KObject, +}; use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use alloc::{collections::BTreeMap, sync::Arc, vec::Vec}; diff --git a/kernel/src/driver/base/mod.rs b/kernel/src/driver/base/mod.rs index e1efc6c1..52b86e44 100644 --- a/kernel/src/driver/base/mod.rs +++ b/kernel/src/driver/base/mod.rs @@ -1,5 +1,14 @@ pub mod block; +pub mod c_adapter; pub mod char; +pub mod class; pub mod device; +pub mod firmware; +pub mod hypervisor; +pub mod init; +pub mod kobject; +pub mod kset; pub mod map; pub mod platform; +pub mod subsys; +pub mod swnode; diff --git a/kernel/src/driver/base/platform/mod.rs b/kernel/src/driver/base/platform/mod.rs index 3643d320..7c00f5b3 100644 --- a/kernel/src/driver/base/platform/mod.rs +++ b/kernel/src/driver/base/platform/mod.rs @@ -1,24 +1,34 @@ -use super::device::{ - bus::{bus_driver_register, bus_register, Bus, BusDriver, BusState}, - driver::DriverError, - Device, DeviceError, DeviceNumber, DevicePrivateData, DeviceResource, DeviceType, IdTable, - KObject, -}; -use crate::{ - driver::Driver, filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError, -}; -use alloc::{ - collections::{BTreeMap, BTreeSet}, - string::ToString, - sync::Arc, - vec::Vec, +use self::{platform_device::PlatformBusDevice, subsys::PlatformBus}; + +use super::{ + device::{ + bus::{bus_register, Bus, BusState}, + device_unregister, sys_devices_kset, DeviceNumber, DevicePrivateData, IdTable, + }, + kobject::KObject, }; +use crate::{driver::base::device::device_register, syscall::SystemError}; +use alloc::{collections::BTreeSet, string::ToString, sync::Arc, vec::Vec}; use core::fmt::Debug; -use platform_device::PlatformDevice; -use platform_driver::PlatformDriver; pub mod platform_device; pub mod platform_driver; +pub mod subsys; + +static mut PLATFORM_BUS_DEVICE: Option> = None; +static mut PLATFORM_BUS: Option> = None; + +#[allow(dead_code)] +#[inline(always)] +pub fn platform_bus_device() -> Arc { + unsafe { PLATFORM_BUS_DEVICE.clone().unwrap() } +} + +#[allow(dead_code)] +#[inline(always)] +pub fn platform_bus() -> Arc { + unsafe { PLATFORM_BUS.clone().unwrap() } +} /// @brief: platform总线匹配表 /// 总线上的设备和驱动都存在一份匹配表 @@ -55,317 +65,34 @@ impl CompatibleTable { } } -#[derive(Debug)] -pub struct LockedPlatformBusDriver(SpinLock); - -impl LockedPlatformBusDriver { - /// @brief: 创建一个platform总线加锁驱动,该驱动用于匹配plaform总线 - /// @parameter: None - /// @return: platfor总线驱动 - #[inline] - #[allow(dead_code)] - pub fn new() -> LockedPlatformBusDriver { - LockedPlatformBusDriver(SpinLock::new(PlatformBusDriver::new())) - } - - /// @brief: 获取该驱动的匹配表 - /// @parameter: None - /// @return: 驱动的匹配表 - #[inline] - #[allow(dead_code)] - fn get_compatible_table(&self) -> CompatibleTable { - CompatibleTable::new(vec!["platform"]) - } - - /// @brief: 根据设备标识符获取platform总线上的设备 - /// @parameter id_table: 设备标识符 - /// @return: 总线上的设备 - #[inline] - #[allow(dead_code)] - fn get_device(&self, id_table: &IdTable) -> Option> { - let device_map = &self.0.lock().devices; - return device_map.get(id_table).cloned(); - } - - /// @brief: 根据设备驱动标识符获取platform总线上的驱动 - /// @parameter id_table: 设备驱动标识符 - /// @return: 总线上的驱动 - #[inline] - #[allow(dead_code)] - fn get_driver(&self, id_table: &IdTable) -> Option> { - let driver_map = &self.0.lock().drivers; - return driver_map.get(id_table).cloned(); - } - - /// @brief: 注册platform类型驱动 - /// @parameter driver: platform类型驱动,该驱动需要实现PlatformDriver trait - /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型 - #[allow(dead_code)] - fn register_platform_driver(&self, driver: Arc) -> Result<(), DeviceError> { - let id_table = driver.id_table(); - - let drivers = &mut self.0.lock().drivers; - // 如果存在同类型的驱动,返回错误 - if drivers.contains_key(&id_table) { - return Err(DeviceError::DriverExists); - } else { - drivers.insert(id_table.clone(), driver.clone()); - return Ok(()); - } - } - - /// @brief: 卸载platform类型驱动 - /// @parameter driver: platform类型驱动,该驱动需挂载在plaform总线之上 - /// @return: None - #[allow(dead_code)] - #[inline] - fn unregister_platform_driver( - &mut self, - driver: Arc, - ) -> Result<(), DeviceError> { - let id_table = driver.id_table(); - self.0.lock().drivers.remove(&id_table); - return Ok(()); - } - - /// @brief: 注册platform类型设备 - /// @parameter driver: platform类型设备,该驱动需要实现PlatformDevice trait - /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型 - #[allow(dead_code)] - fn register_platform_device( - &mut self, - device: Arc, - ) -> Result<(), DeviceError> { - let id_table = device.id_table(); - - let devices = &mut self.0.lock().devices; - if devices.contains_key(&id_table) { - return Err(DeviceError::DeviceExists); - } else { - devices.insert(id_table.clone(), device.clone()); - return Ok(()); - } - } - - /// @brief: 卸载platform类型设备 - /// @parameter device: platform类型设备,该驱设备需挂载在plaform总线之上 - /// @return: None - #[inline] - #[allow(dead_code)] - fn unregister_platform_device(&mut self, device: Arc) { - let id_table = device.id_table(); - self.0.lock().devices.remove(&id_table); - } -} - -/// @brief: platform总线驱动 -#[derive(Debug)] -pub struct PlatformBusDriver { - drivers: BTreeMap>, // 总线上所有驱动 - devices: BTreeMap>, // 总线上所有设备 - sys_info: Option>, -} - -impl PlatformBusDriver { - /// @brief: 创建一个platform总线驱动,该驱动用于匹配plaform总线 - /// @parameter: None - /// @return: platfor总线驱动 - #[inline] - #[allow(dead_code)] - pub fn new() -> Self { - Self { - drivers: BTreeMap::new(), - devices: BTreeMap::new(), - sys_info: None, - } - } -} - -/// @brief: 为PlatformBusDriver实现Driver trait -impl Driver for LockedPlatformBusDriver { - #[inline] - fn as_any_ref(&self) -> &dyn core::any::Any { - self - } - - #[inline] - fn id_table(&self) -> IdTable { - return IdTable::new("PlatformBusDriver".to_string(), DeviceNumber::new(0)); - } - - #[inline] - #[allow(dead_code)] - fn sys_info(&self) -> Option> { - return self.0.lock().sys_info.clone(); - } - - #[inline] - #[allow(dead_code)] - fn set_sys_info(&self, sys_info: Option>) { - self.0.lock().sys_info = sys_info; - } - - fn probe(&self, _data: &DevicePrivateData) -> Result<(), DriverError> { - todo!() - } - - fn load( - &self, - _data: DevicePrivateData, - _resource: Option, - ) -> Result, DriverError> { - todo!() - } -} - -/// @brief: 为PlatformBusDriver实现BusDriver trait -impl BusDriver for LockedPlatformBusDriver { - fn is_empty(&self) -> bool { - if self.0.lock().devices.is_empty() && self.0.lock().drivers.is_empty() { - return true; - } else { - return false; - } - } -} - -impl KObject for LockedPlatformBusDriver {} - -#[derive(Debug)] -pub struct LockedPlatform(SpinLock); - -impl LockedPlatform { - /// @brief: 创建一个加锁的platform总线实例 - /// @parameter: None - /// @return: platform总线实例 - pub fn new(data: DevicePrivateData) -> LockedPlatform { - LockedPlatform(SpinLock::new(Platform::new(data))) - } - - /// @brief: 获取总线的匹配表 - /// @parameter: None - /// @return: platform总线匹配表 - #[inline] - #[allow(dead_code)] - fn compatible_table(&self) -> CompatibleTable { - CompatibleTable::new(vec!["platform"]) - } - - /// @brief: 判断总线是否初始化 - /// @parameter: None - /// @return: 已初始化,返回true,否则,返回false - #[inline] - #[allow(dead_code)] - fn is_initialized(&self) -> bool { - let state = self.0.lock().state; - match state { - BusState::Initialized => true, - _ => false, - } - } - - /// @brief: 设置总线状态 - /// @parameter set_state: 总线状态BusState - /// @return: None - #[inline] - fn set_state(&self, set_state: BusState) { - let state = &mut self.0.lock().state; - *state = set_state; - } - - /// @brief: 获取总线状态 - /// @parameter: None - /// @return: 总线状态 - #[inline] - #[allow(dead_code)] - fn get_state(&self) -> BusState { - let state = self.0.lock().state; - return state; - } - - // /// @brief: - // /// @parameter: None - // /// @return: 总线状态 - // #[inline] - // #[allow(dead_code)] - // fn set_driver(&self, driver: Option>) { - // self.0.lock().driver = driver; - // } -} - -/// @brief: platform总线 -#[derive(Debug, Clone)] -pub struct Platform { - _data: DevicePrivateData, - state: BusState, // 总线状态 - sys_info: Option>, // 总线sys information -} - -/// @brief: platform方法集 -impl Platform { - /// @brief: 创建一个platform总线实例 - /// @parameter: None - /// @return: platform总线实例 - pub fn new(_data: DevicePrivateData) -> Self { - Self { - _data, - state: BusState::NotInitialized, - sys_info: Option::None, - } - } -} - -/// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型 -impl Device for LockedPlatform { - #[inline] - #[allow(dead_code)] - fn dev_type(&self) -> DeviceType { - return DeviceType::Bus; - } - - #[inline] - #[allow(dead_code)] - fn id_table(&self) -> IdTable { - IdTable::new("platform".to_string(), DeviceNumber::new(0)) - } - - #[inline] - fn set_sys_info(&self, sys_info: Option>) { - self.0.lock().sys_info = sys_info; - } - - #[inline] - #[allow(dead_code)] - fn sys_info(&self) -> Option> { - return self.0.lock().sys_info.clone(); - } - - fn as_any_ref(&self) -> &dyn core::any::Any { - self - } -} - -/// @brief: 为Platform实现Bus trait,platform总线是一种总线设备 -impl Bus for LockedPlatform {} - -impl KObject for LockedPlatform {} - /// @brief: 初始化platform总线 /// @parameter: None /// @return: None +/// +/// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c?fi=platform_bus_init#1511 pub fn platform_bus_init() -> Result<(), SystemError> { - let platform_driver: Arc = Arc::new(LockedPlatformBusDriver::new()); - let platform_device: Arc = - Arc::new(LockedPlatform::new(DevicePrivateData::new( + let platform_device: Arc = PlatformBusDevice::new( + DevicePrivateData::new( IdTable::new("platform".to_string(), DeviceNumber::new(0)), None, CompatibleTable::new(vec!["platform"]), BusState::NotInitialized.into(), - ))); - bus_register(platform_device.clone()).map_err(|e| e.into())?; - platform_device.set_state(BusState::Initialized); - //platform_device.set_driver(Some(platform_driver.clone())); - bus_driver_register(platform_driver.clone()).map_err(|e| e.into())?; + ), + Some(Arc::downgrade(&(sys_devices_kset() as Arc))), + ); + unsafe { PLATFORM_BUS_DEVICE = Some(platform_device.clone()) }; + // 注册到/sys/devices下 + device_register(platform_device.clone())?; - return Ok(()); + let paltform_bus = PlatformBus::new(); + // 注册到/sys/bus下 + let r = bus_register(paltform_bus.clone() as Arc); + if r.is_err() { + device_unregister(platform_device.clone()); + unsafe { PLATFORM_BUS_DEVICE = None }; + return r; + } + unsafe { PLATFORM_BUS = Some(paltform_bus) }; + + return r; } diff --git a/kernel/src/driver/base/platform/platform_device.rs b/kernel/src/driver/base/platform/platform_device.rs index 4f21de89..78d02021 100644 --- a/kernel/src/driver/base/platform/platform_device.rs +++ b/kernel/src/driver/base/platform/platform_device.rs @@ -1,4 +1,26 @@ -use crate::driver::base::device::Device; +use alloc::{ + string::{String, ToString}, + sync::{Arc, Weak}, +}; + +use crate::{ + driver::{ + base::{ + device::{ + bus::{Bus, BusState}, + Device, DeviceNumber, DevicePrivateData, DeviceType, IdTable, + }, + kobject::{KObjType, KObject, KObjectState, LockedKObjectState}, + kset::KSet, + }, + Driver, + }, + filesystem::kernfs::KernFSInode, + libs::{ + rwlock::{RwLockReadGuard, RwLockWriteGuard}, + spinlock::SpinLock, + }, +}; use super::{super::device::DeviceState, CompatibleTable}; @@ -16,3 +38,196 @@ pub trait PlatformDevice: Device { /// @return: None fn set_state(&self, set_state: DeviceState); } + +#[derive(Debug)] +#[cast_to([sync] Device)] +pub struct PlatformBusDevice { + inner: SpinLock, + kobj_state: LockedKObjectState, +} + +impl PlatformBusDevice { + /// @brief: 创建一个加锁的platform总线实例 + /// @parameter: None + /// @return: platform总线实例 + pub fn new( + data: DevicePrivateData, + parent: Option>, + ) -> Arc { + return Arc::new(PlatformBusDevice { + inner: SpinLock::new(InnerPlatformBusDevice::new(data, parent)), + kobj_state: LockedKObjectState::new(KObjectState::empty()), + }); + } + + /// @brief: 获取总线的匹配表 + /// @parameter: None + /// @return: platform总线匹配表 + #[inline] + #[allow(dead_code)] + fn compatible_table(&self) -> CompatibleTable { + CompatibleTable::new(vec!["platform"]) + } + + /// @brief: 判断总线是否初始化 + /// @parameter: None + /// @return: 已初始化,返回true,否则,返回false + #[inline] + #[allow(dead_code)] + fn is_initialized(&self) -> bool { + let state = self.inner.lock().state; + match state { + BusState::Initialized => true, + _ => false, + } + } + + /// @brief: 设置总线状态 + /// @parameter set_state: 总线状态BusState + /// @return: None + #[inline] + #[allow(dead_code)] + fn set_state(&self, set_state: BusState) { + let state = &mut self.inner.lock().state; + *state = set_state; + } + + /// @brief: 获取总线状态 + /// @parameter: None + /// @return: 总线状态 + #[inline] + #[allow(dead_code)] + fn get_state(&self) -> BusState { + let state = self.inner.lock().state; + return state; + } + + // /// @brief: + // /// @parameter: None + // /// @return: 总线状态 + // #[inline] + // #[allow(dead_code)] + // fn set_driver(&self, driver: Option>) { + // self.0.lock().driver = driver; + // } +} + +/// @brief: platform总线 +#[allow(dead_code)] +#[derive(Debug, Clone)] +pub struct InnerPlatformBusDevice { + name: String, + data: DevicePrivateData, + state: BusState, // 总线状态 + parent: Option>, // 总线的父对象 + + kernfs_inode: Option>, + /// 当前设备挂载到的总线 + bus: Option>, + /// 当前设备已经匹配的驱动 + driver: Option>, +} + +/// @brief: platform方法集 +impl InnerPlatformBusDevice { + /// @brief: 创建一个platform总线实例 + /// @parameter: None + /// @return: platform总线实例 + pub fn new(data: DevicePrivateData, parent: Option>) -> Self { + Self { + data, + name: "platform".to_string(), + state: BusState::NotInitialized, + parent, + kernfs_inode: None, + bus: None, + driver: None, + } + } +} + +impl KObject for PlatformBusDevice { + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + fn parent(&self) -> Option> { + self.inner.lock().parent.clone() + } + + fn inode(&self) -> Option> { + self.inner.lock().kernfs_inode.clone() + } + + fn set_inode(&self, inode: Option>) { + self.inner.lock().kernfs_inode = inode; + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + None + } + + fn kset(&self) -> Option> { + None + } + + fn kobj_state(&self) -> RwLockReadGuard { + self.kobj_state.read() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + self.kobj_state.write() + } + + fn set_kobj_state(&self, state: KObjectState) { + *self.kobj_state.write() = state; + } + + fn name(&self) -> String { + self.inner.lock().name.clone() + } + + fn set_name(&self, name: String) { + self.inner.lock().name = name; + } + + fn set_kset(&self, _kset: Option>) { + todo!() + } + + fn set_parent(&self, parent: Option>) { + self.inner.lock().parent = parent; + } +} + +/// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型 +impl Device for PlatformBusDevice { + #[inline] + #[allow(dead_code)] + fn dev_type(&self) -> DeviceType { + return DeviceType::Bus; + } + + #[inline] + #[allow(dead_code)] + fn id_table(&self) -> IdTable { + IdTable::new("platform".to_string(), DeviceNumber::new(0)) + } + + fn bus(&self) -> Option> { + self.inner.lock().bus.clone() + } + + fn driver(&self) -> Option> { + self.inner.lock().driver.clone() + } + + #[inline] + fn is_dead(&self) -> bool { + false + } + + fn set_driver(&self, driver: Option>) { + self.inner.lock().driver = driver; + } +} diff --git a/kernel/src/driver/base/platform/subsys.rs b/kernel/src/driver/base/platform/subsys.rs new file mode 100644 index 00000000..085d9bd0 --- /dev/null +++ b/kernel/src/driver/base/platform/subsys.rs @@ -0,0 +1,65 @@ +use alloc::{ + string::{String, ToString}, + sync::{Arc, Weak}, +}; + +use crate::{ + driver::base::{device::bus::Bus, kobject::KObject, subsys::SubSysPrivate}, + filesystem::{ + sysfs::{Attribute, AttributeGroup}, + vfs::syscall::ModeType, + }, +}; + +#[derive(Debug)] +pub struct PlatformBus { + private: SubSysPrivate, +} + +impl PlatformBus { + pub fn new() -> Arc { + let w: Weak = Weak::new(); + let private = SubSysPrivate::new("platform".to_string(), w, &[]); + let bus = Arc::new(Self { private }); + bus.subsystem() + .set_bus(Arc::downgrade(&(bus.clone() as Arc))); + + return bus; + } +} + +impl Bus for PlatformBus { + fn name(&self) -> String { + return "platform".to_string(); + } + + fn dev_name(&self) -> String { + return self.name(); + } + + fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] { + return &[&PlatformDeviceAttrGroup]; + } + + fn subsystem(&self) -> &SubSysPrivate { + return &self.private; + } +} + +#[derive(Debug)] +pub struct PlatformDeviceAttrGroup; + +impl AttributeGroup for PlatformDeviceAttrGroup { + fn name(&self) -> Option<&str> { + None + } + + fn attrs(&self) -> &[&'static dyn Attribute] { + // todo: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c?r=&mo=38425&fi=1511#1311 + return &[]; + } + + fn is_visible(&self, _kobj: Arc, attr: &dyn Attribute) -> Option { + return Some(attr.mode()); + } +} diff --git a/kernel/src/driver/base/subsys.rs b/kernel/src/driver/base/subsys.rs new file mode 100644 index 00000000..21b99f2d --- /dev/null +++ b/kernel/src/driver/base/subsys.rs @@ -0,0 +1,150 @@ +use core::{ + fmt::Debug, + sync::atomic::{AtomicBool, Ordering}, +}; + +use alloc::{ + string::String, + sync::{Arc, Weak}, + vec::Vec, +}; + +use crate::{ + driver::Driver, + libs::{notifier::AtomicNotifierChain, rwlock::RwLock, spinlock::SpinLock}, + syscall::SystemError, +}; + +use super::{ + device::{ + bus::{Bus, BusNotifyEvent}, + Device, + }, + kset::KSet, +}; + +/// 一个用于存储bus/class的驱动核心部分的信息的结构体 +#[derive(Debug)] +pub struct SubSysPrivate { + /// 用于定义这个子系统的kset + subsys: Arc, + ksets: RwLock, + /// 指向拥有当前结构体的`dyn bus`对象的弱引用 + bus: SpinLock>, + drivers_autoprobe: AtomicBool, + /// 当前总线上的所有设备 + devices: RwLock>>, + /// 当前总线上的所有驱动 + drivers: RwLock>>, + interfaces: &'static [&'static dyn SubSysInterface], + bus_notifier: AtomicNotifierChain>, +} + +#[derive(Debug)] +struct SubSysKSets { + /// 子系统的`devices`目录 + devices_kset: Option>, + /// 子系统的`drivers`目录 + drivers_kset: Option>, +} + +impl SubSysKSets { + pub fn new() -> Self { + return Self { + devices_kset: None, + drivers_kset: None, + }; + } +} + +impl SubSysPrivate { + pub fn new( + name: String, + bus: Weak, + interfaces: &'static [&'static dyn SubSysInterface], + ) -> Self { + let subsys = KSet::new(name); + return Self { + subsys, + ksets: RwLock::new(SubSysKSets::new()), + drivers_autoprobe: AtomicBool::new(false), + bus: SpinLock::new(bus), + devices: RwLock::new(Vec::new()), + drivers: RwLock::new(Vec::new()), + interfaces, + bus_notifier: AtomicNotifierChain::new(), + }; + } + + pub fn subsys(&self) -> Arc { + return self.subsys.clone(); + } + + #[inline] + #[allow(dead_code)] + pub fn bus(&self) -> Weak { + return self.bus.lock().clone(); + } + + pub fn set_bus(&self, bus: Weak) { + *self.bus.lock() = bus; + } + + pub fn devices(&self) -> &RwLock>> { + return &self.devices; + } + + pub fn drivers(&self) -> &RwLock>> { + return &self.drivers; + } + + pub fn drivers_autoprobe(&self) -> bool { + return self.drivers_autoprobe.load(Ordering::SeqCst); + } + + pub fn set_drivers_autoprobe(&self, drivers_autoprobe: bool) { + self.drivers_autoprobe + .store(drivers_autoprobe, Ordering::SeqCst); + } + + #[allow(dead_code)] + #[inline] + pub fn devices_kset(&self) -> Option> { + return self.ksets.read().devices_kset.clone(); + } + + #[allow(dead_code)] + #[inline] + pub fn set_devices_kset(&self, devices_kset: Arc) { + self.ksets.write().devices_kset = Some(devices_kset); + } + + #[allow(dead_code)] + #[inline] + pub fn drivers_kset(&self) -> Option> { + return self.ksets.read().drivers_kset.clone(); + } + + pub fn set_drivers_kset(&self, drivers_kset: Arc) { + self.ksets.write().drivers_kset = Some(drivers_kset); + } + + pub fn bus_notifier(&self) -> &AtomicNotifierChain> { + return &self.bus_notifier; + } + + pub fn interfaces(&self) -> &'static [&'static dyn SubSysInterface] { + return self.interfaces; + } +} + +/// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/include/linux/device.h#63 +pub trait SubSysInterface: Debug + Send + Sync { + fn name(&self) -> &str; + fn bus(&self) -> Option>; + fn set_bus(&self, bus: Option>); + fn add_device(&self, _device: &Arc) -> Result<(), SystemError> { + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } + fn remove_device(&self, device: &Arc); +} diff --git a/kernel/src/driver/base/swnode.rs b/kernel/src/driver/base/swnode.rs new file mode 100644 index 00000000..f397e09c --- /dev/null +++ b/kernel/src/driver/base/swnode.rs @@ -0,0 +1,8 @@ +use alloc::sync::Arc; + +use super::device::Device; + +pub fn software_node_notify(_dev: &Arc) { + // todo: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/swnode.c?fi=software_node_notify#1120 + return; +} diff --git a/kernel/src/driver/disk/ahci/ahcidisk.rs b/kernel/src/driver/disk/ahci/ahcidisk.rs index f15e82bc..93ab9105 100644 --- a/kernel/src/driver/disk/ahci/ahcidisk.rs +++ b/kernel/src/driver/disk/ahci/ahcidisk.rs @@ -2,12 +2,18 @@ use super::{_port, hba::HbaCmdTable, virt_2_phys}; use crate::driver::base::block::block_device::{BlockDevice, BlockId}; use crate::driver::base::block::disk_info::Partition; use crate::driver::base::block::SeekFrom; -use crate::driver::base::device::{Device, DeviceType, KObject}; +use crate::driver::base::device::bus::Bus; +use crate::driver::base::device::{Device, DeviceType, IdTable}; +use crate::driver::base::kobject::{KObjType, KObject, KObjectState}; +use crate::driver::base::kset::KSet; use crate::driver::disk::ahci::HBA_PxIS_TFES; +use crate::driver::Driver; +use crate::filesystem::kernfs::KernFSInode; use crate::filesystem::mbr::MbrDiskPartionTable; use crate::include::bindings::bindings::verify_area; use crate::kdebug; +use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard}; use crate::libs::{spinlock::SpinLock, vec_cursor::VecCursor}; use crate::mm::phys_2_virt; use crate::syscall::SystemError; @@ -431,27 +437,83 @@ impl LockedAhciDisk { } } -impl KObject for LockedAhciDisk {} +impl KObject for LockedAhciDisk { + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + fn inode(&self) -> Option> { + todo!() + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + todo!() + } + + fn kset(&self) -> Option> { + todo!() + } + + fn parent(&self) -> Option> { + todo!() + } + + fn set_inode(&self, _inode: Option>) { + todo!() + } + + fn kobj_state(&self) -> RwLockReadGuard { + todo!() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + todo!() + } + + fn set_kobj_state(&self, _state: KObjectState) { + todo!() + } + + fn name(&self) -> alloc::string::String { + todo!() + } + + fn set_name(&self, _name: alloc::string::String) { + todo!() + } + + fn set_kset(&self, _kset: Option>) { + todo!() + } + + fn set_parent(&self, _parent: Option>) { + todo!() + } +} impl Device for LockedAhciDisk { fn dev_type(&self) -> DeviceType { return DeviceType::Block; } - fn as_any_ref(&self) -> &dyn core::any::Any { - return self; - } - - fn id_table(&self) -> crate::driver::base::device::IdTable { + fn id_table(&self) -> IdTable { todo!() } - fn set_sys_info(&self, _sys_info: Option>) { - todo!() + fn bus(&self) -> Option> { + todo!("LockedAhciDisk::bus()") } - fn sys_info(&self) -> Option> { - todo!() + fn driver(&self) -> Option> { + todo!("LockedAhciDisk::driver()") + } + + fn is_dead(&self) -> bool { + false + } + + fn set_driver(&self, _driver: Option>) { + todo!("LockedAhciDisk::set_driver()") } } diff --git a/kernel/src/driver/mod.rs b/kernel/src/driver/mod.rs index 688ea0d7..ba92592e 100644 --- a/kernel/src/driver/mod.rs +++ b/kernel/src/driver/mod.rs @@ -14,20 +14,16 @@ use core::fmt::Debug; use alloc::sync::Arc; -use crate::filesystem::vfs::IndexNode; - use self::base::{ device::{driver::DriverError, Device, DevicePrivateData, DeviceResource, IdTable}, + kobject::KObject, platform::CompatibleTable, }; -pub trait Driver: Sync + Send + Debug { - fn as_any_ref(&'static self) -> &'static dyn core::any::Any; - - //对于不需要匹配,在系统初始化的时候就生成的设备,例如 PlatformBus 就不需要匹配表 - +pub trait Driver: Sync + Send + Debug + KObject { /// @brief: 获取驱动匹配表 /// @parameter: None /// @return: 驱动匹配表 + /// 对于不需要匹配,在系统初始化的时候就生成的设备,例如 PlatformBus 就不需要匹配表 fn compatible_table(&self) -> CompatibleTable { //TODO 要完善每个 CompatibleTable ,将来要把这个默认实现删除 return CompatibleTable::new(vec!["unknown"]); @@ -56,15 +52,4 @@ pub trait Driver: Sync + Send + Debug { /// @parameter: None /// @return: 该驱动驱动唯一标识符 fn id_table(&self) -> IdTable; - - // 考虑到很多驱动并不需要存储在系统中,只需要当工具人就可以了,因此 SysINode 是可选的 - /// @brief: 设置驱动的sys information - /// @parameter id_table: 驱动标识符,用于唯一标识该驱动 - /// @return: 驱动实例 - fn set_sys_info(&self, sys_info: Option>); - - /// @brief: 获取驱动的sys information - /// @parameter id_table: 驱动标识符,用于唯一标识该驱动 - /// @return: 驱动实例 - fn sys_info(&self) -> Option>; } diff --git a/kernel/src/driver/net/virtio_net.rs b/kernel/src/driver/net/virtio_net.rs index 15461d36..118b49b6 100644 --- a/kernel/src/driver/net/virtio_net.rs +++ b/kernel/src/driver/net/virtio_net.rs @@ -10,7 +10,10 @@ use virtio_drivers::{device::net::VirtIONet, transport::Transport}; use crate::{ driver::{ - base::device::{driver::DriverError, Device, DevicePrivateData, DeviceResource, IdTable}, + base::{ + device::{driver::DriverError, Device, DevicePrivateData, DeviceResource, IdTable}, + kobject::KObject, + }, virtio::virtio_impl::HalImpl, Driver, }, @@ -231,20 +234,17 @@ pub fn virtio_net(transport: T) { let mac = smoltcp::wire::EthernetAddress::from_bytes(&driver_net.mac_address()); let driver: VirtioNICDriver = VirtioNICDriver::new(driver_net); let iface = VirtioInterface::new(driver); + let name = iface.name.clone(); // 将网卡的接口信息注册到全局的网卡接口信息表中 NET_DRIVERS.write().insert(iface.nic_id(), iface.clone()); kinfo!( "Virtio-net driver init successfully!\tNetDevID: [{}], MAC: [{}]", - iface.name(), + name, mac ); } -impl Driver for VirtioInterface { - fn as_any_ref(&'static self) -> &'static dyn core::any::Any { - self - } - +impl Driver for VirtioInterface { fn probe(&self, _data: &DevicePrivateData) -> Result<(), DriverError> { todo!() } @@ -260,17 +260,9 @@ impl Driver for VirtioInterface { fn id_table(&self) -> IdTable { todo!() } - - fn set_sys_info(&self, _sys_info: Option>) { - todo!() - } - - fn sys_info(&self) -> Option> { - todo!() - } } -impl NetDriver for VirtioInterface { +impl NetDriver for VirtioInterface { fn mac(&self) -> smoltcp::wire::EthernetAddress { let mac: [u8; 6] = self.driver.inner.lock().mac_address(); return smoltcp::wire::EthernetAddress::from_bytes(&mac); @@ -327,6 +319,64 @@ impl NetDriver for VirtioInterface { // } } +impl KObject for VirtioInterface { + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + fn set_inode(&self, _inode: Option>) { + todo!() + } + + fn inode(&self) -> Option> { + todo!() + } + + fn parent(&self) -> Option> { + todo!() + } + + fn set_parent(&self, _parent: Option>) { + todo!() + } + + fn kset(&self) -> Option> { + todo!() + } + + fn set_kset(&self, _kset: Option>) { + todo!() + } + + fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { + todo!() + } + + fn name(&self) -> String { + self.name.clone() + } + + fn set_name(&self, _name: String) { + todo!() + } + + fn kobj_state( + &self, + ) -> crate::libs::rwlock::RwLockReadGuard { + todo!() + } + + fn kobj_state_mut( + &self, + ) -> crate::libs::rwlock::RwLockWriteGuard { + todo!() + } + + fn set_kobj_state(&self, _state: crate::driver::base::kobject::KObjectState) { + todo!() + } +} + // 向编译器保证,VirtioNICDriver在线程之间是安全的. // 由于smoltcp只会在token内真正操作网卡设备,并且在VirtioNetToken的consume // 方法内,会对VirtioNet进行加【写锁】,因此,能够保证对设备操作的的互斥访问, diff --git a/kernel/src/driver/uart/uart_device.rs b/kernel/src/driver/uart/uart_device.rs index 953871b4..071567df 100644 --- a/kernel/src/driver/uart/uart_device.rs +++ b/kernel/src/driver/uart/uart_device.rs @@ -3,9 +3,11 @@ use crate::{ base::{ char::CharDevice, device::{ - driver::DriverError, Device, DeviceError, DeviceNumber, DevicePrivateData, - DeviceResource, DeviceState, DeviceType, IdTable, KObject, DEVICE_MANAGER, + bus::Bus, driver::DriverError, Device, DeviceError, DeviceNumber, + DevicePrivateData, DeviceResource, DeviceState, DeviceType, IdTable, }, + kobject::{KObjType, KObject, KObjectState}, + kset::KSet, platform::{ platform_device::PlatformDevice, platform_driver::PlatformDriver, CompatibleTable, }, @@ -14,7 +16,7 @@ use crate::{ }, filesystem::{ devfs::{devfs_register, DevFS, DeviceINode}, - sysfs::bus::{bus_device_register, bus_driver_register}, + kernfs::KernFSInode, vfs::{ syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus, @@ -22,7 +24,10 @@ use crate::{ }, include::bindings::bindings::{io_in8, io_out8}, kinfo, - libs::spinlock::SpinLock, + libs::{ + rwlock::{RwLockReadGuard, RwLockWriteGuard}, + spinlock::SpinLock, + }, syscall::SystemError, }; use alloc::{ @@ -120,8 +125,7 @@ struct UartRegister { #[derive(Debug)] pub struct Uart { private_data: DevicePrivateData, // 设备状态 - sys_info: Option>, - fs: Weak, // 文件系统 + fs: Weak, // 文件系统 port: UartPort, baud_rate: u32, metadata: Metadata, @@ -142,7 +146,6 @@ impl Default for Uart { CompatibleTable::new(vec!["uart"]), DeviceState::NotInitialized, ), - sys_info: None, fs: Weak::default(), port: UartPort::COM1, baud_rate: 115200, @@ -161,7 +164,59 @@ impl Default for LockedUart { } } -impl KObject for LockedUart {} +impl KObject for LockedUart { + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + fn inode(&self) -> Option> { + todo!() + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + todo!() + } + + fn kset(&self) -> Option> { + todo!() + } + + fn parent(&self) -> Option> { + todo!() + } + + fn set_inode(&self, _inode: Option>) { + todo!() + } + + fn kobj_state(&self) -> RwLockReadGuard { + todo!() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + todo!() + } + + fn set_kobj_state(&self, _state: KObjectState) { + todo!() + } + + fn name(&self) -> alloc::string::String { + todo!() + } + + fn set_name(&self, _name: alloc::string::String) { + todo!() + } + + fn set_kset(&self, _kset: Option>) { + todo!() + } + + fn set_parent(&self, _parent: Option>) { + todo!() + } +} impl PlatformDevice for LockedUart { fn is_initialized(&self) -> bool { @@ -189,20 +244,24 @@ impl Device for LockedUart { ); } - fn set_sys_info(&self, sys_info: Option>) { - self.0.lock().sys_info = sys_info; - } - - fn sys_info(&self) -> Option> { - self.0.lock().sys_info.clone() - } - fn dev_type(&self) -> DeviceType { DeviceType::Serial } - fn as_any_ref(&self) -> &dyn Any { - self + fn bus(&self) -> Option> { + todo!("LockedUart::bus()") + } + + fn driver(&self) -> Option> { + todo!("LockedUart::driver()") + } + + fn is_dead(&self) -> bool { + false + } + + fn set_driver(&self, _driver: Option>) { + todo!("LockedUart::set_driver()") } } @@ -533,25 +592,65 @@ impl Default for LockedUartDriver { } } -impl KObject for LockedUartDriver {} - -impl Driver for LockedUartDriver { - fn as_any_ref(&self) -> &dyn Any { +impl KObject for LockedUartDriver { + fn as_any_ref(&self) -> &dyn core::any::Any { self } + fn inode(&self) -> Option> { + todo!() + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + todo!() + } + + fn kset(&self) -> Option> { + todo!() + } + + fn parent(&self) -> Option> { + todo!() + } + + fn set_inode(&self, _inode: Option>) { + todo!() + } + + fn kobj_state(&self) -> RwLockReadGuard { + todo!() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + todo!() + } + + fn set_kobj_state(&self, _state: KObjectState) { + todo!() + } + + fn name(&self) -> alloc::string::String { + todo!() + } + + fn set_name(&self, _name: alloc::string::String) { + todo!() + } + + fn set_kset(&self, _kset: Option>) { + todo!() + } + + fn set_parent(&self, _parent: Option>) { + todo!() + } +} + +impl Driver for LockedUartDriver { fn id_table(&self) -> IdTable { return IdTable::new("uart_driver".to_string(), DeviceNumber::new(0)); } - fn set_sys_info(&self, sys_info: Option>) { - self.0.lock().sys_info = sys_info; - } - - fn sys_info(&self) -> Option> { - return self.0.lock().sys_info.clone(); - } - fn probe(&self, data: &DevicePrivateData) -> Result<(), DriverError> { let table = data.compatible_table(); if table.matches(&CompatibleTable::new(vec!["uart"])) { @@ -693,14 +792,14 @@ pub fn uart_init() -> Result<(), SystemError> { let dev = UART_DEV.0.lock(); LockedUart::uart_init(&dev.port, dev.baud_rate).map_err(|_| SystemError::ENODEV)?; drop(dev); - let device_inode = bus_device_register("platform:0", &UART_DEV.id_table().name()) - .expect("uart device register error"); - UART_DEV.set_sys_info(Some(device_inode)); - let driver_inode = bus_driver_register("platform:0", &UART_DRV.id_table().name()) - .expect("uart driver register error"); - UART_DRV.set_sys_info(Some(driver_inode)); + // let device_inode = bus_device_register("platform:0", &UART_DEV.id_table().name()) + // .expect("uart device register error"); + // UART_DEV.set_sys_info(Some(device_inode)); + // let driver_inode = bus_driver_register("platform:0", &UART_DRV.id_table().name()) + // .expect("uart driver register error"); + // UART_DRV.set_sys_info(Some(driver_inode)); UART_DEV.set_state(DeviceState::Initialized); devfs_register(&UART_DEV.id_table().name(), UART_DEV.clone())?; - DEVICE_MANAGER.add_device(UART_DEV.id_table().clone(), UART_DEV.clone()); + // DEVICE_MANAGER.add_device(UART_DEV.id_table().clone(), UART_DEV.clone()); return Ok(()); } diff --git a/kernel/src/driver/uart/uart_driver.rs b/kernel/src/driver/uart/uart_driver.rs index cd495e27..a1898fc5 100644 --- a/kernel/src/driver/uart/uart_driver.rs +++ b/kernel/src/driver/uart/uart_driver.rs @@ -1,7 +1,8 @@ use alloc::sync::Arc; use crate::driver::base::char::CharDevOps; -use crate::driver::base::device::{Device, DeviceResource, DEVICE_MANAGER}; +use crate::driver::base::device::{device_manager, Device, DeviceResource}; +use crate::driver::base::kobject::KObject; use crate::driver::base::platform::CompatibleTable; use crate::{ driver::{ @@ -32,7 +33,63 @@ impl Default for UartDriver { })) } } +impl KObject for UartDriver { + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + fn set_inode(&self, _inode: Option>) { + todo!() + } + + fn inode(&self) -> Option> { + todo!() + } + + fn parent(&self) -> Option> { + todo!() + } + + fn set_parent(&self, _parent: Option>) { + todo!() + } + + fn kset(&self) -> Option> { + todo!() + } + + fn set_kset(&self, _kset: Option>) { + todo!() + } + + fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> { + todo!() + } + + fn name(&self) -> alloc::string::String { + todo!() + } + + fn set_name(&self, _name: alloc::string::String) { + todo!() + } + + fn kobj_state( + &self, + ) -> crate::libs::rwlock::RwLockReadGuard { + todo!() + } + + fn kobj_state_mut( + &self, + ) -> crate::libs::rwlock::RwLockWriteGuard { + todo!() + } + + fn set_kobj_state(&self, _state: crate::driver::base::kobject::KObjectState) { + todo!() + } +} impl Driver for UartDriver { fn probe(&self, data: &DevicePrivateData) -> Result<(), DriverError> { let compatible_table = data.compatible_table(); @@ -48,34 +105,25 @@ impl Driver for UartDriver { data: DevicePrivateData, _resource: Option, ) -> Result, DriverError> { - if let Some(device) = DEVICE_MANAGER.get_device(data.id_table()) { + if let Some(device) = device_manager().find_device_by_idtable(data.id_table()) { return Ok(device.clone()); } let compatible_table = data.compatible_table(); if compatible_table.matches(&UART_COMPAT_TABLE) { let device = LockedUart::default(); let arc_device = Arc::new(device); - DEVICE_MANAGER.add_device(data.id_table().clone(), arc_device.clone()); - CharDevOps::cdev_add(arc_device.clone(), data.id_table().clone(), 1); + device_manager() + .add_device(arc_device.clone()) + .map_err(|_| DriverError::RegisterError)?; + CharDevOps::cdev_add(arc_device.clone(), data.id_table().clone(), 1) + .map_err(|_| DriverError::RegisterError)?; } - return Err(DriverError::ProbeError); + return Err(DriverError::RegisterError); } fn id_table(&self) -> IdTable { let driver = self.0.lock(); return driver.id_table.clone(); } - - fn as_any_ref(&'static self) -> &'static dyn core::any::Any { - return self; - } - - fn set_sys_info(&self, _sys_info: Option>) { - todo!() - } - - fn sys_info(&self) -> Option> { - todo!() - } } diff --git a/kernel/src/filesystem/kernfs/callback.rs b/kernel/src/filesystem/kernfs/callback.rs index 492ae314..03b8c4c7 100644 --- a/kernel/src/filesystem/kernfs/callback.rs +++ b/kernel/src/filesystem/kernfs/callback.rs @@ -64,6 +64,22 @@ impl<'a> KernCallbackData<'a> { pub fn private_data_mut(&mut self) -> &mut Option { return &mut self.private_data; } + + pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result { + let private_data = self.private_data(); + if let Some(private_data) = private_data { + return private_data.callback_read(buf, offset); + } + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } + + pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result { + let private_data = self.private_data(); + if let Some(private_data) = private_data { + return private_data.callback_write(buf, offset); + } + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } } #[allow(dead_code)] @@ -71,3 +87,23 @@ impl<'a> KernCallbackData<'a> { pub enum KernInodePrivateData { SysFS(SysFSKernPrivateData), } + +impl KernInodePrivateData { + #[inline(always)] + pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result { + match self { + KernInodePrivateData::SysFS(private_data) => { + return private_data.callback_read(buf, offset); + } + } + } + + #[inline(always)] + pub fn callback_write(&self, buf: &[u8], offset: usize) -> Result { + match self { + KernInodePrivateData::SysFS(private_data) => { + return private_data.callback_write(buf, offset); + } + } + } +} diff --git a/kernel/src/filesystem/kernfs/mod.rs b/kernel/src/filesystem/kernfs/mod.rs index 344c48ca..b582a946 100644 --- a/kernel/src/filesystem/kernfs/mod.rs +++ b/kernel/src/filesystem/kernfs/mod.rs @@ -8,7 +8,11 @@ use alloc::{ use hashbrown::HashMap; use crate::{ - libs::{rwlock::RwLock, spinlock::SpinLock}, + libs::{ + casting::DowncastArc, + rwlock::RwLock, + spinlock::{SpinLock, SpinLockGuard}, + }, syscall::SystemError, time::TimeSpec, }; @@ -83,6 +87,7 @@ impl KernFS { raw_dev: 0, }; let root_inode = Arc::new(KernFSInode { + name: String::from(""), inner: SpinLock::new(InnerKernFSInode { parent: Weak::new(), metadata, @@ -114,6 +119,8 @@ pub struct KernFSInode { children: SpinLock>>, /// Inode类型 inode_type: KernInodeType, + /// Inode名称 + name: String, } #[derive(Debug)] @@ -199,13 +206,29 @@ impl IndexNode for KernFSInode { if unlikely(self.inode_type != KernInodeType::Dir) { return Err(SystemError::ENOTDIR); } - let x: Arc = self - .children - .lock() - .get(name) - .cloned() - .ok_or(SystemError::ENOENT)?; - return Ok(x); + match name { + "" | "." => { + return Ok(self.self_ref.upgrade().ok_or(SystemError::ENOENT)?); + } + + ".." => { + return Ok(self + .inner + .lock() + .parent + .upgrade() + .ok_or(SystemError::ENOENT)?); + } + name => { + // 在子目录项中查找 + return Ok(self + .children + .lock() + .get(name) + .ok_or(SystemError::ENOENT)? + .clone()); + } + } } fn get_entry_name(&self, ino: InodeId) -> Result { @@ -248,11 +271,21 @@ impl IndexNode for KernFSInode { } fn list(&self) -> Result, SystemError> { - let mut list = Vec::new(); - for (name, _) in self.children.lock().iter() { - list.push(name.clone()); + let info = self.metadata()?; + if info.file_type != FileType::Dir { + return Err(SystemError::ENOTDIR); } - return Ok(list); + + let mut keys: Vec = Vec::new(); + keys.push(String::from(".")); + keys.push(String::from("..")); + self.children + .lock() + .keys() + .into_iter() + .for_each(|x| keys.push(x.clone())); + + return Ok(keys); } fn poll(&self) -> Result { @@ -272,6 +305,7 @@ impl IndexNode for KernFSInode { } if self.callback.is_none() { + kwarn!("kernfs: callback is none"); return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); } @@ -376,8 +410,14 @@ impl KernFSInode { private_data: Option, callback: Option<&'static dyn KernFSCallback>, ) -> Result, SystemError> { + let size = if file_type == KernInodeType::File { + 4096 + } else { + 0 + }; + let metadata = Metadata { - size: 0, + size, mode, uid: 0, gid: 0, @@ -394,9 +434,10 @@ impl KernFSInode { }; let new_inode: Arc = Self::new( - self.self_ref.upgrade().unwrap(), + Some(self.self_ref.upgrade().unwrap()), + name.clone(), metadata, - KernInodeType::Dir, + file_type, private_data, callback, ); @@ -434,16 +475,21 @@ impl KernFSInode { } } - pub(self) fn new( - parent: Arc, - metadata: Metadata, + pub fn new( + parent: Option>, + name: String, + mut metadata: Metadata, inode_type: KernInodeType, private_data: Option, callback: Option<&'static dyn KernFSCallback>, ) -> Arc { + metadata.file_type = inode_type.into(); + let parent: Weak = parent.map(|x| Arc::downgrade(&x)).unwrap_or_default(); + let inode = Arc::new(KernFSInode { + name, inner: SpinLock::new(InnerKernFSInode { - parent: Arc::downgrade(&parent), + parent: parent.clone(), metadata, }), self_ref: Weak::new(), @@ -460,18 +506,50 @@ impl KernFSInode { (*ptr).self_ref = Arc::downgrade(&inode); } } - *inode.fs.write() = Arc::downgrade( - parent + if parent.strong_count() > 0 { + let kernfs = parent + .upgrade() + .unwrap() .fs() - .as_any_ref() - .downcast_ref() - .expect("KernFSInode::new: parent is not a KernFS instance"), - ); + .downcast_arc::() + .expect("KernFSInode::new: parent is not a KernFS instance"); + *inode.fs.write() = Arc::downgrade(&kernfs); + } return inode; } + + pub fn name(&self) -> &str { + return &self.name; + } + + pub fn parent(&self) -> Option> { + return self.inner.lock().parent.upgrade(); + } + + pub fn private_data_mut(&self) -> SpinLockGuard> { + return self.private_data.lock(); + } + + /// remove a kernfs_node recursively + pub fn remove_recursive(&self) { + let mut children = self.children.lock().drain().collect::>(); + while let Some((_, child)) = children.pop() { + children.append(&mut child.children.lock().drain().collect::>()); + } + } + + /// 删除当前的inode(包括其自身、子目录和子文件) + #[allow(dead_code)] + pub fn remove_inode_include_self(&self) { + let parent = self.parent(); + if let Some(parent) = parent { + parent.children.lock().remove(self.name()); + } + self.remove_recursive(); + } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub(self) enum KernInodeType { +pub enum KernInodeType { Dir, File, } diff --git a/kernel/src/filesystem/sysfs/bus.rs b/kernel/src/filesystem/sysfs/bus.rs deleted file mode 100644 index acd797f0..00000000 --- a/kernel/src/filesystem/sysfs/bus.rs +++ /dev/null @@ -1,89 +0,0 @@ -use super::{LockedSysFSInode, SYS_BUS_INODE}; -use crate::{filesystem::vfs::IndexNode, kdebug, syscall::SystemError}; -use alloc::sync::Arc; - -/// @brief: 注册bus,在sys/bus下生成文件夹 -/// @parameter bus_name: 总线文件夹名 -/// @return: 操作成功,返回inode,操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn sys_bus_register(bus_name: &str) -> Result, SystemError> { - let binding: Arc = SYS_BUS_INODE(); - kdebug!("Before bus_register: ls /sys/bus/: {:?}", binding.list()); - binding - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .add_dir(bus_name) -} - -/// @brief: 注销bus,在sys/bus删除文件夹 -/// @parameter bus_name: 总线文件夹名 -/// @return: 操作成功,返回(),操作失败,返回错误码 -#[allow(dead_code)] -pub fn sys_bus_unregister(bus_name: &str) -> Result<(), SystemError> { - let binding: Arc = SYS_BUS_INODE(); - binding - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .remove(bus_name) -} - -/// @brief: 在相应总线文件夹下生成devices和drivers文件夹 -/// @parameter inode: 总线文件夹inode -/// @return: 操作成功,返回devices inode和drivers inode,操作失败,返回错误码 -pub fn sys_bus_init( - inode: &Arc, -) -> Result<(Arc, Arc), SystemError> { - match inode.as_any_ref().downcast_ref::() { - Some(lock_bus) => match lock_bus.add_dir("devices") { - Ok(devices) => match lock_bus.add_dir("drivers") { - Ok(drivers) => Ok((devices, drivers)), - Err(err) => Err(err), - }, - Err(err) => Err(err), - }, - None => Err(SystemError::E2BIG), - } -} - -/// @brief: 在相应总线的device下生成设备文件夹 -/// @parameter bus_name: 总线名 -/// name: 设备名 -/// @return: 操作成功,返回device inode,操作失败,返回错误码 -pub fn bus_driver_register(bus_name: &str, name: &str) -> Result, SystemError> { - match SYS_BUS_INODE().find(bus_name) { - Ok(platform) => match platform.find("drivers") { - Ok(device) => device - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .add_dir(name), - Err(_) => return Err(SystemError::EXDEV), - }, - Err(_) => return Err(SystemError::EXDEV), - } -} - -/// @brief: 在相应总线的driver下生成驱动文件夹 -/// @parameter bus_name: 总线名 -/// name: 驱动名 -/// @return: 操作成功,返回drivers inode,操作失败,返回错误码 -pub fn bus_device_register(bus_name: &str, name: &str) -> Result, SystemError> { - match SYS_BUS_INODE().find(bus_name) { - Ok(platform) => match platform.find("devices") { - Ok(device) => device - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .add_dir(name), - Err(_) => return Err(SystemError::EXDEV), - }, - Err(_) => return Err(SystemError::EXDEV), - } -} diff --git a/kernel/src/filesystem/sysfs/class.rs b/kernel/src/filesystem/sysfs/class.rs deleted file mode 100644 index d924fd4d..00000000 --- a/kernel/src/filesystem/sysfs/class.rs +++ /dev/null @@ -1,69 +0,0 @@ -use super::{LockedSysFSInode, SYS_CLASS_INODE}; -use crate::{filesystem::vfs::IndexNode, syscall::SystemError}; -use alloc::sync::Arc; - -/// @brief: 注册class,在sys/class下生成文件夹 -/// @parameter class_name: 类文件夹名 -/// @return: 操作成功,返回inode,操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn sys_class_register(class_name: &str) -> Result, SystemError> { - let binding: Arc = SYS_CLASS_INODE(); - binding - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .add_dir(class_name) -} - -/// @brief: 注销class,在sys/class删除文件夹 -/// @parameter class_name: 总线文件夹名 -/// @return: 操作成功,返回(),操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn sys_class_unregister(class_name: &str) -> Result<(), SystemError> { - let binding: Arc = SYS_CLASS_INODE(); - binding - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .remove(class_name) -} - -/// @brief: 注册device,在对应类下操作设备文件夹 -/// @parameter class: 类文件夹inode -/// @parameter device_name: 设备文件夹名 -/// @return: 操作成功,返回inode,操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn class_device_register( - class: Arc, - device_name: &str, -) -> Result, SystemError> { - class - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .add_dir(device_name) -} - -/// @brief: 操作device,在对应类下删除设备文件夹 -/// @parameter class: 类文件夹inode -/// @parameter device_name: 设备文件夹名 -/// @return: 操作成功,返回(),操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn class_device_unregister( - class: Arc, - device_name: &str, -) -> Result<(), SystemError> { - class - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .remove(device_name) -} diff --git a/kernel/src/filesystem/sysfs/devices.rs b/kernel/src/filesystem/sysfs/devices.rs deleted file mode 100644 index 6ab987c4..00000000 --- a/kernel/src/filesystem/sysfs/devices.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::{LockedSysFSInode, SYS_DEVICES_INODE}; -use crate::{filesystem::vfs::IndexNode, syscall::SystemError}; -use alloc::sync::Arc; - -/// @brief: 注册device,在sys/devices下生成文件夹 -/// @parameter device_name: 类文件夹名 -/// @return: 操作成功,返回inode,操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn sys_device_register(device_name: &str) -> Result, SystemError> { - let binding: Arc = SYS_DEVICES_INODE(); - binding - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .add_dir(device_name) -} - -/// @brief: 操作bus,在sys/devices删除文件夹 -/// @parameter device_name: 总线文件夹名 -/// @return: 操作成功,返回(),操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn sys_device_unregister(device_name: &str) -> Result<(), SystemError> { - let binding: Arc = SYS_DEVICES_INODE(); - binding - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .remove(device_name) -} diff --git a/kernel/src/filesystem/sysfs/dir.rs b/kernel/src/filesystem/sysfs/dir.rs index 3a03f468..debb4c67 100644 --- a/kernel/src/filesystem/sysfs/dir.rs +++ b/kernel/src/filesystem/sysfs/dir.rs @@ -1,32 +1,127 @@ #![allow(dead_code)] -use alloc::sync::Arc; +use alloc::{ + string::{String, ToString}, + sync::{Arc, Weak}, + vec::Vec, +}; -use crate::driver::base::device::KObject; +use crate::{ + driver::base::kobject::KObject, + filesystem::{ + kernfs::{callback::KernInodePrivateData, KernFSInode}, + vfs::syscall::ModeType, + }, + syscall::SystemError, +}; -use super::AttributeGroup; +use super::{SysFS, SysFSKernPrivateData}; #[derive(Debug)] pub struct SysKernDirPriv { - kobj: Arc, - attribute_group: Option<&'static dyn AttributeGroup>, + /// 该目录对应的kobject + /// use weak reference to avoid cyclic reference + kobj: Weak, + // attribute_group: Option<&'static dyn AttributeGroup>, } impl SysKernDirPriv { - pub fn new( - kobj: Arc, - attribute_group: Option<&'static dyn AttributeGroup>, - ) -> Self { + pub fn new(kobj: Arc) -> Self { + // let attribute_group = kobj.kobj_type().map(|kobj_type| kobj_type.attribute_groups()).flatten(); Self { - kobj, - attribute_group, + kobj: Arc::downgrade(&kobj), + // attribute_group, } } - pub fn kobj(&self) -> Arc { - self.kobj.clone() + pub fn kobj(&self) -> Option> { + self.kobj.upgrade() } - pub fn attribute_group(&self) -> Option<&'static dyn AttributeGroup> { - self.attribute_group + // pub fn attribute_group(&self) -> Option<&'static dyn AttributeGroup> { + // self.attribute_group + // } +} + +impl SysFS { + /// 在sysfs中创建一个目录 + /// + /// 如果kobj的parent为None,则会在根目录下创建一个目录。 + /// + /// ## 参数 + /// + /// - `kobj`: 要创建的目录对应的kobject + /// + /// ## 返回 + /// + /// 返回创建的目录对应的inode + pub fn create_dir(&self, kobj: Arc) -> Result, SystemError> { + // 如果kobj的parent为None,则会在/sys目录下创建一个目录。 + let parent = kobj + .parent() + .map(|p| p.upgrade().unwrap().inode()) + .unwrap_or_else(|| Some(self.root_inode.clone())) + .ok_or(SystemError::ENOENT)?; + + let sysfs_dir_priv = SysFSKernPrivateData::Dir(SysKernDirPriv::new(kobj.clone())); + // 在kernfs里面创建一个目录 + let dir: Arc = parent.add_dir( + kobj.name(), + ModeType::from_bits_truncate(0o755), + Some(KernInodePrivateData::SysFS(sysfs_dir_priv)), + None, + )?; + + kobj.set_inode(Some(dir.clone())); + + return Ok(dir); + } + + /// 获取指定的kernfs inode在sysfs中的路径(不包含`/sys`) + /// + /// ## 参数 + /// + /// - `parent`: inode的父目录 + /// - `name`: inode的名称 + /// + /// ## 返回 + /// + /// 返回inode在sysfs中的路径 + pub(super) fn kernfs_path(&self, parent: &Arc) -> String { + let mut p = parent.clone(); + let mut parts = Vec::new(); + let sys_root_inode = self.root_inode(); + let mut not_reach_sys_root = false; + while !Arc::ptr_eq(&p, sys_root_inode) { + parts.push(p.name().to_string()); + if let Some(parent) = p.parent() { + p = parent; + } else { + not_reach_sys_root = true; + break; + } + } + + let mut path = String::new(); + if not_reach_sys_root { + path.push_str("(null)"); + }; + + for part in parts.iter().rev() { + path.push('/'); + path.push_str(part); + } + + return path; + } + + /// 从sysfs中删除一个kobject对应的目录(包括目录自身以及目录下的所有文件、文件夹) + pub fn remove_dir(&self, kobj: &Arc) { + let kobj_inode = kobj.inode(); + kobj.set_inode(None); + + if let Some(inode) = kobj_inode { + let parent = inode.parent().unwrap(); + parent.remove_recursive() + } } } diff --git a/kernel/src/filesystem/sysfs/file.rs b/kernel/src/filesystem/sysfs/file.rs index af8c003a..66833cb1 100644 --- a/kernel/src/filesystem/sysfs/file.rs +++ b/kernel/src/filesystem/sysfs/file.rs @@ -1,21 +1,298 @@ -#![allow(dead_code)] -use super::Attribute; +use core::{intrinsics::unlikely, ops::BitAnd}; + +use alloc::{ + string::ToString, + sync::{Arc, Weak}, +}; + +use crate::{ + driver::base::kobject::KObject, + filesystem::{ + kernfs::{ + callback::{KernCallbackData, KernFSCallback, KernInodePrivateData}, + KernFSInode, + }, + sysfs::{SysFSOps, SysFSOpsSupport}, + vfs::{syscall::ModeType, PollStatus}, + }, + kwarn, + syscall::SystemError, +}; + +use super::{Attribute, SysFS, SysFSKernPrivateData}; #[derive(Debug)] pub struct SysKernFilePriv { attribute: Option<&'static dyn Attribute>, + /// 当前文件对应的kobject + kobj: Weak, // todo: 增加bin attribute,它和attribute二选一,只能有一个为Some } impl SysKernFilePriv { - pub fn new(attribute: Option<&'static dyn Attribute>) -> Self { + pub fn new(kobj: &Arc, attribute: Option<&'static dyn Attribute>) -> Self { if attribute.is_none() { panic!("attribute can't be None"); } - return Self { attribute }; + let kobj = Arc::downgrade(kobj); + return Self { kobj, attribute }; } + #[allow(dead_code)] + #[inline] pub fn attribute(&self) -> Option<&'static dyn Attribute> { self.attribute } + + pub fn callback_read(&self, buf: &mut [u8]) -> Result { + let attribute = self.attribute.ok_or(SystemError::EINVAL)?; + // 当前文件所指向的kobject已经被释放 + let kobj = self.kobj.upgrade().expect("kobj is None"); + return attribute.show(kobj, buf); + } + + pub fn callback_write(&self, buf: &[u8]) -> Result { + let attribute = self.attribute.ok_or(SystemError::EINVAL)?; + // 当前文件所指向的kobject已经被释放 + let kobj = self.kobj.upgrade().expect("kobj is None"); + return attribute.store(kobj, buf); + } +} + +impl SysFS { + /// 为指定的kobject创建一个属性文件 + /// + /// ## 参数 + /// + /// - `kobj` 要创建属性文件的kobject + /// - `attr` 属性 + pub fn create_file( + &self, + kobj: &Arc, + attr: &'static dyn Attribute, + ) -> Result<(), SystemError> { + let inode = kobj.inode().ok_or(SystemError::EINVAL)?; + return self.add_file_with_mode(&inode, attr, attr.mode()); + } + + // https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/file.c?fi=sysfs_add_file_mode_ns#271 + pub(super) fn add_file_with_mode( + &self, + parent: &Arc, + attr: &'static dyn Attribute, + mode: ModeType, + ) -> Result<(), SystemError> { + let x = parent.private_data_mut(); + let kobj: Arc; + if let Some(KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir(dt))) = x.as_ref() { + kobj = dt.kobj().unwrap(); + } else { + drop(x); + let path = self.kernfs_path(parent); + panic!("parent '{path}' is not a dir"); + } + drop(x); + + let sysfs_ops: &dyn SysFSOps = kobj.kobj_type().unwrap().sysfs_ops().ok_or_else(|| { + kwarn!("missing sysfs attribute operations for kobject: {kobj:?}"); + SystemError::EINVAL + })?; + + // assume that all sysfs ops are preallocated. + + let sys_support = sysfs_ops.support(attr); + + let kern_callback: &'static dyn KernFSCallback; + if sys_support.contains(SysFSOpsSupport::SHOW) + && sys_support.contains(SysFSOpsSupport::STORE) + { + kern_callback = &PreallocKFOpsRW; + } else if sys_support.contains(SysFSOpsSupport::SHOW) { + kern_callback = &PreallocKFOpsReadOnly; + } else if sys_support.contains(SysFSOpsSupport::STORE) { + kern_callback = &PreallocKFOpsWriteOnly; + } else { + kern_callback = &PreallocKFOpsEmpty; + } + + let sys_priv = SysFSKernPrivateData::File(SysKernFilePriv::new(&kobj, Some(attr))); + let r = parent.add_file( + attr.name().to_string(), + mode.bitand(ModeType::from_bits_truncate(0o777)), + Some(KernInodePrivateData::SysFS(sys_priv)), + Some(kern_callback), + ); + + if let Err(e) = r { + if e == SystemError::EEXIST { + self.warn_duplicate(parent, attr.name()); + } + + return Err(e); + } + return Ok(()); + } + + /// 在sysfs中删除某个kobject的属性文件 + /// + /// 如果属性文件不存在,则发出一个警告 + /// + /// ## 参数 + /// + /// - `kobj` 要删除属性文件的kobject + /// - `attr` 属性 + pub fn remove_file(&self, kobj: &Arc, attr: &'static dyn Attribute) { + let parent = kobj.inode(); + + if let Some(parent) = parent { + let r = parent.remove(attr.name()); + if unlikely(r.is_err()) { + kwarn!( + "failed to remove file '{}' from '{}'", + attr.name(), + kobj.name() + ); + } + } + } +} + +#[derive(Debug)] +struct PreallocKFOpsRW; + +impl KernFSCallback for PreallocKFOpsRW { + fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { + return Ok(()); + } + + fn read( + &self, + data: KernCallbackData, + buf: &mut [u8], + offset: usize, + ) -> Result { + return data.callback_read(buf, offset); + } + + fn write( + &self, + data: KernCallbackData, + buf: &[u8], + offset: usize, + ) -> Result { + return data.callback_write(buf, offset); + } + + #[inline] + fn poll(&self, _data: KernCallbackData) -> Result { + return Ok(PollStatus::READ | PollStatus::WRITE); + } +} + +#[derive(Debug)] +struct PreallocKFOpsReadOnly; + +impl KernFSCallback for PreallocKFOpsReadOnly { + fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { + return Ok(()); + } + + fn read( + &self, + data: KernCallbackData, + buf: &mut [u8], + offset: usize, + ) -> Result { + return data.callback_read(buf, offset); + } + + fn write( + &self, + _data: KernCallbackData, + _buf: &[u8], + _offset: usize, + ) -> Result { + return Err(SystemError::EPERM); + } + + #[inline] + fn poll(&self, _data: KernCallbackData) -> Result { + return Ok(PollStatus::READ); + } +} + +#[derive(Debug)] +struct PreallocKFOpsWriteOnly; + +impl KernFSCallback for PreallocKFOpsWriteOnly { + fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { + return Ok(()); + } + + fn read( + &self, + _data: KernCallbackData, + _buf: &mut [u8], + _offset: usize, + ) -> Result { + return Err(SystemError::EPERM); + } + + fn write( + &self, + data: KernCallbackData, + buf: &[u8], + offset: usize, + ) -> Result { + return data.callback_write(buf, offset); + } + + #[inline] + fn poll(&self, _data: KernCallbackData) -> Result { + return Ok(PollStatus::WRITE); + } +} + +#[derive(Debug)] +struct PreallocKFOpsEmpty; + +impl KernFSCallback for PreallocKFOpsEmpty { + fn open(&self, _data: KernCallbackData) -> Result<(), SystemError> { + return Ok(()); + } + + fn read( + &self, + _data: KernCallbackData, + _buf: &mut [u8], + _offset: usize, + ) -> Result { + return Err(SystemError::EPERM); + } + + fn write( + &self, + _data: KernCallbackData, + _buf: &[u8], + _offset: usize, + ) -> Result { + return Err(SystemError::EPERM); + } + + #[inline] + fn poll(&self, _data: KernCallbackData) -> Result { + return Ok(PollStatus::empty()); + } +} + +pub fn sysfs_emit_str(buf: &mut [u8], s: &str) -> Result { + let len; + if buf.len() > s.len() { + len = s.len(); + } else { + len = buf.len() - 1; + } + buf[..len].copy_from_slice(&s.as_bytes()[..len]); + buf[len] = b'\0'; + return Ok(len); } diff --git a/kernel/src/filesystem/sysfs/fs.rs b/kernel/src/filesystem/sysfs/fs.rs deleted file mode 100644 index 3d555859..00000000 --- a/kernel/src/filesystem/sysfs/fs.rs +++ /dev/null @@ -1,33 +0,0 @@ -use super::{LockedSysFSInode, SYS_FS_INODE}; -use crate::{filesystem::vfs::IndexNode, syscall::SystemError}; -use alloc::sync::Arc; - -/// @brief: 注册fs,在sys/fs下是生成文件夹 -/// @parameter fs_name: 类文件夹名 -/// @return: 操作成功,返回inode,操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn fs_register(fs_name: &str) -> Result, SystemError> { - let binding: Arc = SYS_FS_INODE(); - binding - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .add_dir(fs_name) -} - -/// @brief: 注销fs,在sys/fs删除文件夹 -/// @parameter fs_name: 总线文件夹名 -/// @return: 操作成功,返回(),操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn fs_unregister(fs_name: &str) -> Result<(), SystemError> { - let binding: Arc = SYS_FS_INODE(); - binding - .as_any_ref() - .downcast_ref::() - .ok_or(SystemError::E2BIG) - .unwrap() - .remove(fs_name) -} diff --git a/kernel/src/filesystem/sysfs/group.rs b/kernel/src/filesystem/sysfs/group.rs new file mode 100644 index 00000000..54bc89c8 --- /dev/null +++ b/kernel/src/filesystem/sysfs/group.rs @@ -0,0 +1,200 @@ +use core::intrinsics::unlikely; + +use alloc::{string::ToString, sync::Arc}; + +use crate::{ + driver::base::kobject::KObject, + filesystem::{ + kernfs::{callback::KernInodePrivateData, KernFSInode}, + sysfs::{dir::SysKernDirPriv, sysfs_instance, SysFSKernPrivateData}, + vfs::{syscall::ModeType, IndexNode}, + }, + kwarn, + libs::casting::DowncastArc, + syscall::SystemError, +}; + +use super::{AttributeGroup, SysFS}; + +impl SysFS { + /// 在sysfs中,为指定的kobject的属性组创建文件夹 + pub fn create_groups( + &self, + kobj: &Arc, + groups: &[&'static dyn AttributeGroup], + ) -> Result<(), SystemError> { + return self.do_create_groups(kobj, groups, false); + } + + fn do_create_groups( + &self, + kobj: &Arc, + groups: &[&'static dyn AttributeGroup], + update: bool, + ) -> Result<(), SystemError> { + for i in 0..groups.len() { + let group = groups[i]; + if let Err(e) = self.do_create_group(kobj, group, update) { + for j in (0..=i).rev() { + self.remove_group(kobj, groups[j]).ok(); + } + return Err(e); + } + } + return Ok(()); + } + + fn do_create_group( + &self, + kobj: &Arc, + group: &'static dyn AttributeGroup, + update: bool, + ) -> Result<(), SystemError> { + // kobj的inode必须存在 + let kobj_inode = kobj.inode().ok_or(SystemError::EINVAL)?; + + if group.attrs().is_empty() { + return Err(SystemError::EINVAL); + } + + let parent_inode: Arc; + if group.name().is_some() { + if update { + // 如果是更新,那么group的name必须存在 + parent_inode = kobj_inode + .find(group.name().unwrap()) + .map_err(|_| SystemError::EINVAL)? + .downcast_arc() + .unwrap(); + } else { + let private_data = KernInodePrivateData::SysFS(SysFSKernPrivateData::Dir( + SysKernDirPriv::new(kobj.clone()), + )); + parent_inode = kobj_inode + .add_dir( + group.name().unwrap().to_string(), + ModeType::S_IRWXU | ModeType::S_IRUGO | ModeType::S_IXUGO, + Some(private_data), + None, + ) + .map_err(|e| { + if e == SystemError::EEXIST { + self.warn_duplicate(&kobj_inode, group.name().unwrap()); + } + e + })?; + } + } else { + parent_inode = kobj_inode.clone(); + } + + if let Err(e) = self.group_create_files(parent_inode.clone(), kobj, group, update) { + if group.name().is_some() { + parent_inode.remove_recursive(); + } + return Err(e); + } + + return Ok(()); + } + + /// 从一个kobject中移除一个group + /// + /// This function removes a group of attributes from a kobject. The attributes + /// previously have to have been created for this group, otherwise it will fail. + /// + /// ## 参数 + /// + /// - `kobj` - 要移除group的kobject + /// - `group` - 要移除的group + /// + /// + pub fn remove_group( + &self, + kobj: &Arc, + group: &'static dyn AttributeGroup, + ) -> Result<(), SystemError> { + let inode = kobj.inode().unwrap(); + let parent_inode: Arc; + if let Some(name) = group.name() { + parent_inode = inode + .find(name) + .map_err(|e| { + kwarn!("sysfs group '{name}' not found for kobject {kobj:?}"); + e + })? + .downcast_arc() + .unwrap(); + } else { + parent_inode = inode; + } + + self.group_remove_files(&parent_inode, group); + + if group.name().is_some() { + parent_inode.remove_recursive(); + } + + return Ok(()); + } + + /// 创建属性组的文件 + /// + /// ## 参数 + /// + /// - `parent` - 属性组的父文件夹 + /// - `kobj` - 属性组所属的kobject + /// - `group` - 属性组 + /// - `update` - 当前是否正在更新属性 + /// + /// https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/group.c#34 + fn group_create_files( + &self, + parent: Arc, + kobj: &Arc, + group: &'static dyn AttributeGroup, + update: bool, + ) -> Result<(), SystemError> { + let mut e = Ok(()); + for attr in group.attrs() { + let mut mode = attr.mode(); + + // 由于我们在更新的时候,可能会更改visibility和permissions,所以需要先删除再创建 + if update { + parent.remove(attr.name()).ok(); + } + if let Some(mt) = group.is_visible(kobj.clone(), *attr) { + mode = mt; + // 当前属性不可见,跳过 + if mode.is_empty() { + continue; + } + } + + if unlikely((mode.bits() & (!0o644)) != 0) { + kwarn!( + "Attribute '{name}' has invalid mode 0{mode:o}", + name = attr.name(), + mode = mode + ); + } + + mode = ModeType::from_bits_truncate(mode.bits() & 0o644); + e = sysfs_instance().add_file_with_mode(&parent, *attr, mode); + if e.is_err() { + break; + } + } + + if let Err(e) = e { + self.group_remove_files(&parent, group); + return Err(e); + } + + return Ok(()); + } + + fn group_remove_files(&self, _parent: &Arc, _group: &'static dyn AttributeGroup) { + todo!("group_remove_files") + } +} diff --git a/kernel/src/filesystem/sysfs/mod.rs b/kernel/src/filesystem/sysfs/mod.rs index 9d55276e..5c9e2ec5 100644 --- a/kernel/src/filesystem/sysfs/mod.rs +++ b/kernel/src/filesystem/sysfs/mod.rs @@ -2,479 +2,31 @@ use core::fmt::Debug; use self::{dir::SysKernDirPriv, file::SysKernFilePriv}; -use super::vfs::{ - core::generate_inode_id, file::FileMode, syscall::ModeType, FileSystem, FileType, FsInfo, - IndexNode, Metadata, PollStatus, +use super::{ + kernfs::{KernFS, KernFSInode}, + vfs::{syscall::ModeType, FileSystem}, }; use crate::{ - driver::base::{device::KObject, platform::platform_bus_init}, - filesystem::{sysfs::bus::sys_bus_init, vfs::ROOT_INODE}, - kdebug, kinfo, - libs::{ - once::Once, - spinlock::{SpinLock, SpinLockGuard}, - }, + driver::base::kobject::KObject, + filesystem::vfs::ROOT_INODE, + kinfo, kwarn, + libs::{casting::DowncastArc, once::Once}, syscall::SystemError, - time::TimeSpec, -}; -use alloc::{ - collections::BTreeMap, - string::{String, ToString}, - sync::{Arc, Weak}, - vec::Vec, }; +use alloc::sync::Arc; -pub mod bus; -pub mod class; -pub mod devices; -mod dir; -mod file; -pub mod fs; +pub mod dir; +pub mod file; +pub mod group; +pub mod symlink; -const SYSFS_MAX_NAMELEN: usize = 64; +/// 全局的sysfs实例 +pub(self) static mut SYSFS_INSTANCE: Option = None; -static mut __SYS_DEVICES_INODE: Option> = None; -static mut __SYS_BUS_INODE: Option> = None; -static mut __SYS_CLASS_INODE: Option> = None; -static mut __SYS_FS_INODE: Option> = None; - -/// @brief 获取全局的sys/devices节点 #[inline(always)] -#[allow(non_snake_case)] -pub fn SYS_DEVICES_INODE() -> Arc { +pub fn sysfs_instance() -> &'static SysFS { unsafe { - return __SYS_DEVICES_INODE.as_ref().unwrap().clone(); - } -} - -/// @brief 获取全局的sys/bus节点 -#[inline(always)] -#[allow(non_snake_case)] -pub fn SYS_BUS_INODE() -> Arc { - unsafe { - return __SYS_BUS_INODE.as_ref().unwrap().clone(); - } -} - -/// @brief 获取全局的sys/class节点 -#[inline(always)] -#[allow(non_snake_case)] -pub fn SYS_CLASS_INODE() -> Arc { - unsafe { - return __SYS_CLASS_INODE.as_ref().unwrap().clone(); - } -} - -/// @brief 获取全局的sys/fs节点 -#[inline(always)] -#[allow(non_snake_case)] -pub fn SYS_FS_INODE() -> Arc { - unsafe { - return __SYS_FS_INODE.as_ref().unwrap().clone(); - } -} - -/// @brief dev文件系统 -#[derive(Debug)] -pub struct SysFS { - // 文件系统根节点 - root_inode: Arc, -} - -impl FileSystem for SysFS { - fn as_any_ref(&self) -> &dyn core::any::Any { - self - } - - fn root_inode(&self) -> Arc { - return self.root_inode.clone(); - } - - fn info(&self) -> super::vfs::FsInfo { - return FsInfo { - blk_dev_id: 0, - max_name_len: SYSFS_MAX_NAMELEN, - }; - } -} - -impl SysFS { - pub fn new() -> Arc { - // 初始化root inode - let root: Arc = Arc::new(LockedSysFSInode(SpinLock::new( - // /sys 的权限设置为 读+执行,root 可以读写 - // root 的 parent 是空指针 - SysFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0), - ))); - - let sysfs: Arc = Arc::new(SysFS { root_inode: root }); - - // 对root inode加锁,并继续完成初始化工作 - let mut root_guard: SpinLockGuard = sysfs.root_inode.0.lock(); - root_guard.parent = Arc::downgrade(&sysfs.root_inode); - root_guard.self_ref = Arc::downgrade(&sysfs.root_inode); - root_guard.fs = Arc::downgrade(&sysfs); - // 释放锁 - drop(root_guard); - - // 创建文件夹 - let root: &Arc = &sysfs.root_inode; - match root.add_dir("devices") { - Ok(devices) => unsafe { - __SYS_DEVICES_INODE = Some(devices); - }, - Err(_) => panic!("SysFS: Failed to create /sys/devices"), - } - - match root.add_dir("bus") { - Ok(bus) => unsafe { - __SYS_BUS_INODE = Some(bus); - }, - Err(_) => panic!("SysFS: Failed to create /sys/bus"), - } - - match root.add_dir("class") { - Ok(class) => unsafe { - __SYS_CLASS_INODE = Some(class); - }, - Err(_) => panic!("SysFS: Failed to create /sys/class"), - } - - match root.add_dir("fs") { - Ok(fs) => unsafe { - __SYS_FS_INODE = Some(fs); - }, - Err(_) => panic!("SysFS: Failed to create /sys/fs"), - } - - return sysfs; - } -} - -/// @brief sys文件i节点(锁) -#[derive(Debug)] -pub struct LockedSysFSInode(SpinLock); - -impl IndexNode for LockedSysFSInode { - fn as_any_ref(&self) -> &dyn core::any::Any { - self - } - - fn resize(&self, _len: usize) -> Result<(), SystemError> { - return Ok(()); - } - - fn truncate(&self, _len: usize) -> Result<(), SystemError> { - return Ok(()); - } - - fn open( - &self, - _data: &mut super::vfs::FilePrivateData, - _mode: &FileMode, - ) -> Result<(), SystemError> { - return Ok(()); - } - - fn close(&self, _data: &mut super::vfs::FilePrivateData) -> Result<(), SystemError> { - return Ok(()); - } - - fn read_at( - &self, - _offset: usize, - _len: usize, - _buf: &mut [u8], - _data: &mut super::vfs::FilePrivateData, - ) -> Result { - return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); - } - - fn write_at( - &self, - _offset: usize, - _len: usize, - _buf: &[u8], - _data: &mut super::vfs::FilePrivateData, - ) -> Result { - return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); - } - - fn poll(&self) -> Result { - // 加锁 - let inode: SpinLockGuard = self.0.lock(); - - // 检查当前inode是否为一个文件夹,如果是的话,就返回错误 - if inode.metadata.file_type == FileType::Dir { - return Err(SystemError::EISDIR); - } - - return Ok(PollStatus::READ | PollStatus::WRITE); - } - - fn metadata(&self) -> Result { - return Ok(self.0.lock().metadata.clone()); - } - - fn fs(&self) -> Arc { - return self.0.lock().fs.upgrade().unwrap(); - } - - fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result { - let inode: SpinLockGuard = self.0.lock(); - if inode.metadata.file_type != FileType::Dir { - return Err(SystemError::ENOTDIR); - } - - match ino.into() { - 0 => { - return Ok(String::from(".")); - } - 1 => { - return Ok(String::from("..")); - } - ino => { - // 暴力遍历所有的children,判断inode id是否相同 - // TODO: 优化这里,这个地方性能很差! - let mut key: Vec = inode - .children - .keys() - .filter(|k| { - inode - .children - .get(*k) - .unwrap() - .metadata() - .unwrap() - .inode_id - .into() - == ino - }) - .cloned() - .collect(); - - match key.len() { - 0=>{return Err(SystemError::ENOENT);} - 1=>{return Ok(key.remove(0));} - _ => panic!("Sysfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino) - } - } - } - } - - fn find(&self, name: &str) -> Result, SystemError> { - let inode = self.0.lock(); - - if inode.metadata.file_type != FileType::Dir { - return Err(SystemError::ENOTDIR); - } - - match name { - "" | "." => { - return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?); - } - ".." => { - return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?); - } - name => { - // 在子目录项中查找 - // match inode.children.get(name) { - // Some(_) => {} - // None => kdebug!("Sysfs find {} error", name), - // } - return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone()); - } - } - } - - fn ioctl(&self, _cmd: u32, _data: usize) -> Result { - Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) - } - - fn list(&self) -> Result, SystemError> { - let info = self.metadata()?; - if info.file_type != FileType::Dir { - return Err(SystemError::ENOTDIR); - } - - let mut keys: Vec = Vec::new(); - keys.push(String::from(".")); - keys.push(String::from("..")); - keys.append(&mut self.0.lock().children.keys().cloned().collect()); - - return Ok(keys); - } -} - -impl LockedSysFSInode { - fn do_create_with_data( - &self, - mut guard: SpinLockGuard, - name: &str, - file_type: FileType, - mode: ModeType, - data: usize, - ) -> Result, SystemError> { - if guard.metadata.file_type != FileType::Dir { - return Err(SystemError::ENOTDIR); - } - - // 如果有重名的,则返回 - if guard.children.contains_key(name) { - return Err(SystemError::EEXIST); - } - - // 创建inode - let result: Arc = Arc::new(LockedSysFSInode(SpinLock::new(SysFSInode { - parent: guard.self_ref.clone(), - self_ref: Weak::default(), - children: BTreeMap::new(), - metadata: Metadata { - dev_id: 0, - inode_id: generate_inode_id(), - size: 0, - blk_size: 0, - blocks: 0, - atime: TimeSpec::default(), - mtime: TimeSpec::default(), - ctime: TimeSpec::default(), - file_type, - mode, - nlinks: 1, - uid: 0, - gid: 0, - raw_dev: data, - }, - fs: guard.fs.clone(), - }))); - - // 初始化inode的自引用的weak指针 - result.0.lock().self_ref = Arc::downgrade(&result); - - // 将子inode插入父inode的B树中 - guard.children.insert(String::from(name), result.clone()); - return Ok(result); - } - - /// @brief 在当前目录下,创建一个目录 - /// @param name: 目录名 - /// @return 成功返回目录inode, 失败返回Err(错误码) - #[inline] - #[allow(dead_code)] - pub fn add_dir(&self, name: &str) -> Result, SystemError> { - let guard: SpinLockGuard = self.0.lock(); - - if guard.children.contains_key(name) { - return Err(SystemError::EEXIST); - } - - match self.do_create_with_data( - guard, - name, - FileType::Dir, - ModeType::from_bits_truncate(0o755), - 0, - ) { - Ok(inode) => return Ok(inode), - Err(err) => { - return Err(err); - } - }; - } - - /// @brief 在当前目录下,创建一个二进制文件 - /// @param name: 文件名 - /// @return 成功返回Ok(()), 失败返回Err(错误码) - #[inline] - #[allow(dead_code)] - pub fn add_file(&self, name: &str, file: Arc) -> Result<(), SystemError> { - let mut this = self.0.lock(); - - if this.children.contains_key(name) { - return Err(SystemError::EEXIST); - } - - this.children.insert(name.to_string(), file); - return Ok(()); - } - - /// @brief 为该inode创建硬链接 - /// @param None - /// @return 当前inode强引用 - #[inline] - #[allow(dead_code)] - pub fn link(&self) -> Arc { - return self - .0 - .lock() - .self_ref - .clone() - .upgrade() - .ok_or(SystemError::E2BIG) - .unwrap(); - } - - pub fn remove(&self, name: &str) -> Result<(), SystemError> { - let x = self - .0 - .lock() - .children - .remove(name) - .ok_or(SystemError::ENOENT)?; - - drop(x); - return Ok(()); - } -} - -/// @brief sys文件i节点(无锁) -#[derive(Debug)] -pub struct SysFSInode { - /// 指向父Inode的弱引用 - parent: Weak, - /// 指向自身的弱引用 - self_ref: Weak, - /// 子Inode的B树 - children: BTreeMap>, - /// 指向inode所在的文件系统对象的指针 - fs: Weak, - /// INode 元数据 - metadata: Metadata, -} - -impl SysFSInode { - pub fn new(file_type: FileType, mode: ModeType, data_: usize) -> Self { - return Self::new_with_parent(Weak::default(), file_type, mode, data_); - } - - pub fn new_with_parent( - parent: Weak, - file_type: FileType, - mode: ModeType, - data_: usize, - ) -> Self { - return SysFSInode { - parent: parent, - self_ref: Weak::default(), - children: BTreeMap::new(), - metadata: Metadata { - dev_id: 1, - inode_id: generate_inode_id(), - size: 0, - blk_size: 0, - blocks: 0, - atime: TimeSpec::default(), - mtime: TimeSpec::default(), - ctime: TimeSpec::default(), - file_type, - mode, - nlinks: 1, - uid: 0, - gid: 0, - raw_dev: data_, - }, - fs: Weak::default(), - }; + return &SYSFS_INSTANCE.as_ref().unwrap(); } } @@ -483,25 +35,21 @@ pub fn sysfs_init() -> Result<(), SystemError> { let mut result = None; INIT.call_once(|| { kinfo!("Initializing SysFS..."); + // 创建 sysfs 实例 - let sysfs: Arc = SysFS::new(); + // let sysfs: Arc = OldSysFS::new(); + let sysfs = SysFS::new(); + unsafe { SYSFS_INSTANCE = Some(sysfs) }; // sysfs 挂载 let _t = ROOT_INODE() .find("sys") .expect("Cannot find /sys") - .mount(sysfs) + .mount(sysfs_instance().fs().clone()) .expect("Failed to mount sysfs"); kinfo!("SysFS mounted."); - // 初始化platform总线 - platform_bus_init().expect("platform bus init failed"); - - sys_bus_init(&SYS_BUS_INODE()).unwrap_or_else(|err| { - panic!("sys_bus_init failed: {:?}", err); - }); - - kdebug!("sys_bus_init result: {:?}", SYS_BUS_INODE().list()); + // kdebug!("sys_bus_init result: {:?}", SYS_BUS_INODE().list()); result = Some(Ok(())); }); @@ -516,15 +64,131 @@ pub enum SysFSKernPrivateData { File(SysKernFilePriv), } +impl SysFSKernPrivateData { + #[inline(always)] + pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result { + match self { + SysFSKernPrivateData::File(file) => { + let len = file.callback_read(buf)?; + if offset > 0 { + if len <= offset { + return Ok(0); + } + let len = len - offset; + buf.copy_within(offset..offset + len, 0); + buf[len] = 0; + } + return Ok(len); + } + _ => { + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } + } + } + + #[inline(always)] + pub fn callback_write(&self, buf: &[u8], _offset: usize) -> Result { + match self { + SysFSKernPrivateData::File(file) => { + return file.callback_write(buf); + } + _ => { + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } + } + } +} + /// sysfs文件目录的属性组 pub trait AttributeGroup: Debug + Send + Sync { - fn name(&self) -> &str; + /// 属性组的名称 + /// + /// 如果属性组的名称为None,则所有的属性都会被添加到父目录下,而不是创建一个新的目录 + fn name(&self) -> Option<&str>; + /// 属性组的属性列表 fn attrs(&self) -> &[&'static dyn Attribute]; - fn is_visible(&self, kobj: Arc, attr: &dyn Attribute) -> bool; + + /// 属性在当前属性组内的权限(该方法可选) + /// + /// 如果返回None,则使用Attribute的mode()方法返回的权限 + /// + /// 如果返回Some,则使用返回的权限。 + /// 如果要标识属性不可见,则返回Some(ModeType::empty()) + fn is_visible(&self, kobj: Arc, attr: &dyn Attribute) -> Option; } /// sysfs文件的属性 pub trait Attribute: Debug + Send + Sync { fn name(&self) -> &str; fn mode(&self) -> ModeType; + + fn support(&self) -> SysFSOpsSupport; + + fn show(&self, _kobj: Arc, _buf: &mut [u8]) -> Result { + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } + + fn store(&self, _kobj: Arc, _buf: &[u8]) -> Result { + return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP); + } +} + +pub trait SysFSOps: Debug { + /// 获取当前文件的支持的操作 + fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport { + return attr.support(); + } + + fn show( + &self, + kobj: Arc, + attr: &dyn Attribute, + buf: &mut [u8], + ) -> Result; + + fn store( + &self, + kobj: Arc, + attr: &dyn Attribute, + buf: &[u8], + ) -> Result; +} + +bitflags! { + pub struct SysFSOpsSupport: u8{ + const SHOW = 1 << 0; + const STORE = 1 << 1; + } +} + +#[derive(Debug)] +pub struct SysFS { + root_inode: Arc, + kernfs: Arc, +} + +impl SysFS { + pub fn new() -> Self { + let kernfs: Arc = KernFS::new(); + + let root_inode: Arc = kernfs.root_inode().downcast_arc().unwrap(); + + let sysfs = SysFS { root_inode, kernfs }; + + return sysfs; + } + + pub fn root_inode(&self) -> &Arc { + return &self.root_inode; + } + + pub fn fs(&self) -> &Arc { + return &self.kernfs; + } + + /// 警告:重复的sysfs entry + pub(self) fn warn_duplicate(&self, parent: &Arc, name: &str) { + let path = self.kernfs_path(parent); + kwarn!("duplicate sysfs entry: {path}/{name}"); + } } diff --git a/kernel/src/filesystem/sysfs/symlink.rs b/kernel/src/filesystem/sysfs/symlink.rs new file mode 100644 index 00000000..3954db92 --- /dev/null +++ b/kernel/src/filesystem/sysfs/symlink.rs @@ -0,0 +1,38 @@ +use alloc::{string::String, sync::Arc}; + +use crate::{driver::base::kobject::KObject, syscall::SystemError}; + +use super::SysFS; + +impl SysFS { + /// 在sysfs中创建一个符号链接 + /// + /// ## 参数 + /// + /// - `kobj`: 要创建符号链接的kobject + /// - `target`: 符号链接的目标(在目标目录下创建) + /// - `name`: 符号链接的名称 + /// + /// 参考:https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/symlink.c#89 + pub fn create_link( + &self, + _kobj: &Arc, + _target: &Arc, + _name: String, + ) -> Result<(), SystemError> { + todo!("sysfs create link") + } + + /// 在sysfs中删除一个符号链接 + /// + /// ## 参数 + /// + /// - `kobj`: 要删除符号链接的kobject(符号链接所在目录) + /// - `name`: 符号链接的名称 + /// + /// + /// 参考:https://opengrok.ringotek.cn/xref/linux-6.1.9/fs/sysfs/symlink.c#143 + pub fn remove_link(&self, _kobj: &Arc, _name: String) -> Result<(), SystemError> { + todo!("sysfs remove link") + } +} diff --git a/kernel/src/filesystem/vfs/file.rs b/kernel/src/filesystem/vfs/file.rs index 7df623b4..c6495d61 100644 --- a/kernel/src/filesystem/vfs/file.rs +++ b/kernel/src/filesystem/vfs/file.rs @@ -280,7 +280,9 @@ impl File { let sub_inode: Arc = match inode.find(&name) { Ok(i) => i, Err(e) => { - kerror!("Readdir error: Failed to find sub inode, file={self:?}"); + kerror!( + "Readdir error: Failed to find sub inode:{name:?}, file={self:?}, error={e:?}" + ); return Err(e); } }; diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index 689cc387..a3638f42 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -559,6 +559,12 @@ pub trait FileSystem: Any + Sync + Send + Debug { fn as_any_ref(&self) -> &dyn Any; } +impl DowncastArc for dyn FileSystem { + fn as_any_arc(self: Arc) -> Arc { + self + } +} + #[derive(Debug)] pub struct FsInfo { /// 文件系统所在的块设备的id diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index 5dd46d93..55784bda 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -64,6 +64,19 @@ bitflags! { const S_IROTH = 0o0004; const S_IWOTH = 0o0002; const S_IXOTH = 0o0001; + + /// 0o777 + const S_IRWXUGO = Self::S_IRWXU.bits | Self::S_IRWXG.bits | Self::S_IRWXO.bits; + /// 0o7777 + const S_IALLUGO = Self::S_ISUID.bits | Self::S_ISGID.bits | Self::S_ISVTX.bits| Self::S_IRWXUGO.bits; + /// 0o444 + const S_IRUGO = Self::S_IRUSR.bits | Self::S_IRGRP.bits | Self::S_IROTH.bits; + /// 0o222 + const S_IWUGO = Self::S_IWUSR.bits | Self::S_IWGRP.bits | Self::S_IWOTH.bits; + /// 0o111 + const S_IXUGO = Self::S_IXUSR.bits | Self::S_IXGRP.bits | Self::S_IXOTH.bits; + + } } diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index cc16a358..a515d31f 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -4,6 +4,7 @@ #![feature(arbitrary_self_types)] #![feature(asm_const)] #![feature(const_mut_refs)] +#![feature(const_trait_impl)] #![feature(core_intrinsics)] #![feature(c_void_variant)] #![feature(drain_filter)] diff --git a/kernel/src/libs/notifier.rs b/kernel/src/libs/notifier.rs index 598d10f3..59ee1d66 100644 --- a/kernel/src/libs/notifier.rs +++ b/kernel/src/libs/notifier.rs @@ -1,4 +1,6 @@ #![allow(dead_code)] +use core::fmt::Debug; + use crate::{ kwarn, libs::{rwlock::RwLock, spinlock::SpinLock}, @@ -7,18 +9,19 @@ use crate::{ use alloc::{sync::Arc, vec::Vec}; /// @brief 通知链节点 -pub trait NotifierBlock { +pub trait NotifierBlock: Debug + Send + Sync { /// @brief 通知链中注册的回调函数类型 - fn notifier_call(&self, action: u64, data: Option<&T>) -> i32; + fn notifier_call(&self, action: V, data: Option<&T>) -> i32; /// @brief 通知链节点的优先级 fn priority(&self) -> i32; } /// @brief 通知链 // TODO: 考虑使用红黑树封装 -struct NotifierChain(Vec>>); +#[derive(Debug)] +struct NotifierChain(Vec>>); -impl NotifierChain { +impl NotifierChain { pub fn new() -> Self { Self(vec![]) } @@ -27,7 +30,7 @@ impl NotifierChain { /// @param unique_priority 检查通知链中优先级的唯一性 pub fn register( &mut self, - block: Arc>, + block: Arc>, unique_priority: bool, ) -> Result<(), SystemError> { let mut index: usize = 0; @@ -61,7 +64,7 @@ impl NotifierChain { } /// @brief 在通知链中取消注册节点 - pub fn unregister(&mut self, block: Arc>) -> Result<(), SystemError> { + pub fn unregister(&mut self, block: Arc>) -> Result<(), SystemError> { let remove = self .0 .drain_filter(|b| Arc::as_ptr(&block) == Arc::as_ptr(b)); @@ -71,13 +74,20 @@ impl NotifierChain { } } - /// @brief 通知链进行事件通知 - /// @param nr_to_call 回调函数次数 - /// @return (最后一次回调函数的返回值,回调次数) - // TODO: 增加 NOTIFIER_STOP_MASK 相关功能 + /// 通知链进行事件通知 + /// + /// ## 参数 + /// + /// - nr_to_call 最大调用回调函数的数量,如果为None,则不限制次数 + /// + /// ## 返回 + /// + /// (最后一次回调函数的返回值,回调次数) + /// + /// TODO: 增加 NOTIFIER_STOP_MASK 相关功能 pub fn call_chain( &self, - action: u64, + action: V, data: Option<&T>, nr_to_call: Option, ) -> (i32, usize) { @@ -96,34 +106,35 @@ impl NotifierChain { } /// @brief 原子的通知链,使用 SpinLock 进行同步 -pub struct AtomicNotifierChain(SpinLock>); +#[derive(Debug)] +pub struct AtomicNotifierChain(SpinLock>); -impl AtomicNotifierChain { +impl AtomicNotifierChain { pub fn new() -> Self { - Self(SpinLock::new(NotifierChain::::new())) + Self(SpinLock::new(NotifierChain::::new())) } - pub fn register(&mut self, block: Arc>) -> Result<(), SystemError> { + pub fn register(&mut self, block: Arc>) -> Result<(), SystemError> { let mut notifier_chain_guard = self.0.lock(); return notifier_chain_guard.register(block, false); } pub fn register_unique_prio( &mut self, - block: Arc>, + block: Arc>, ) -> Result<(), SystemError> { let mut notifier_chain_guard = self.0.lock(); return notifier_chain_guard.register(block, true); } - pub fn unregister(&mut self, block: Arc>) -> Result<(), SystemError> { + pub fn unregister(&mut self, block: Arc>) -> Result<(), SystemError> { let mut notifier_chain_guard = self.0.lock(); return notifier_chain_guard.unregister(block); } pub fn call_chain( &self, - action: u64, + action: V, data: Option<&T>, nr_to_call: Option, ) -> (i32, usize) { @@ -134,34 +145,35 @@ impl AtomicNotifierChain { /// @brief 可阻塞的通知链,使用 RwLock 进行同步 // TODO: 使用 semaphore 封装 -pub struct BlockingNotifierChain(RwLock>); +#[derive(Debug)] +pub struct BlockingNotifierChain(RwLock>); -impl BlockingNotifierChain { +impl BlockingNotifierChain { pub fn new() -> Self { - Self(RwLock::new(NotifierChain::::new())) + Self(RwLock::new(NotifierChain::::new())) } - pub fn register(&mut self, block: Arc>) -> Result<(), SystemError> { + pub fn register(&mut self, block: Arc>) -> Result<(), SystemError> { let mut notifier_chain_guard = self.0.write(); return notifier_chain_guard.register(block, false); } pub fn register_unique_prio( &mut self, - block: Arc>, + block: Arc>, ) -> Result<(), SystemError> { let mut notifier_chain_guard = self.0.write(); return notifier_chain_guard.register(block, true); } - pub fn unregister(&mut self, block: Arc>) -> Result<(), SystemError> { + pub fn unregister(&mut self, block: Arc>) -> Result<(), SystemError> { let mut notifier_chain_guard = self.0.write(); return notifier_chain_guard.unregister(block); } pub fn call_chain( &self, - action: u64, + action: V, data: Option<&T>, nr_to_call: Option, ) -> (i32, usize) { @@ -171,24 +183,24 @@ impl BlockingNotifierChain { } /// @brief 原始的通知链,由调用者自行考虑同步 -pub struct RawNotifierChain(NotifierChain); +pub struct RawNotifierChain(NotifierChain); -impl RawNotifierChain { +impl RawNotifierChain { pub fn new() -> Self { - Self(NotifierChain::::new()) + Self(NotifierChain::::new()) } - pub fn register(&mut self, block: Arc>) -> Result<(), SystemError> { + pub fn register(&mut self, block: Arc>) -> Result<(), SystemError> { return self.0.register(block, false); } - pub fn unregister(&mut self, block: Arc>) -> Result<(), SystemError> { + pub fn unregister(&mut self, block: Arc>) -> Result<(), SystemError> { return self.0.unregister(block); } pub fn call_chain( &self, - action: u64, + action: V, data: Option<&T>, nr_to_call: Option, ) -> (i32, usize) { diff --git a/kernel/src/main.c b/kernel/src/main.c index f556495a..cce8bca4 100644 --- a/kernel/src/main.c +++ b/kernel/src/main.c @@ -32,7 +32,7 @@ #include -extern int rs_device_init(); +extern int rs_driver_init(); extern int rs_tty_init(); extern void rs_softirq_init(); extern void rs_mm_init(); @@ -129,7 +129,8 @@ void system_initialize() rs_jiffies_init(); io_mfence(); vfs_init(); - rs_device_init(); + + rs_driver_init(); rs_tty_init(); rs_kthread_init(); diff --git a/user/apps/shell/cmd.c b/user/apps/shell/cmd.c index ebeadee7..74a6fd94 100644 --- a/user/apps/shell/cmd.c +++ b/user/apps/shell/cmd.c @@ -339,9 +339,11 @@ int shell_cmd_cat(int argc, char **argv) int l = read(fd, buf, 511); if (l < 0) { - printf("ERROR: Cannot read file: %s\n", file_path); + printf("ERROR: Cannot read file: %s, errno = %d\n", file_path, errno); return -1; } + if (l == 0) + break; buf[l] = '\0'; file_size -= l;