From e0de0fd6a52199753a3127cfbb5d12f0a1555aae Mon Sep 17 00:00:00 2001 From: TingHuang <92705854+TingSHub@users.noreply.github.com> Date: Sun, 23 Apr 2023 22:55:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B9=E6=8D=AEsysfs=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=A9=B1=E5=8A=A8=E6=A8=A1=E5=9E=8B=20&=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0sysfs=E5=AE=98=E6=96=B9=E6=96=87=E6=A1=A3=20(?= =?UTF-8?q?#254)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 根据sysfs完善设备驱动模型 * 添加sysfs官方文档 --- docs/kernel/filesystem/index.rst | 1 + docs/kernel/filesystem/sysfs.md | 109 +++++++++++++ kernel/src/driver/base/device/bus.rs | 107 ++++++++---- kernel/src/driver/base/device/driver.rs | 134 ++++++++++++++- kernel/src/driver/base/device/mod.rs | 150 ++++++++++++++++- kernel/src/driver/base/platform/mod.rs | 206 ++++++++++++++---------- kernel/src/filesystem/sysfs/bus.rs | 9 +- kernel/src/filesystem/sysfs/class.rs | 11 +- kernel/src/filesystem/sysfs/devices.rs | 4 +- kernel/src/filesystem/sysfs/mod.rs | 2 +- kernel/src/ipc/pipe.rs | 2 +- 11 files changed, 583 insertions(+), 152 deletions(-) create mode 100644 docs/kernel/filesystem/sysfs.md diff --git a/docs/kernel/filesystem/index.rst b/docs/kernel/filesystem/index.rst index 7233e385..1442e1e7 100644 --- a/docs/kernel/filesystem/index.rst +++ b/docs/kernel/filesystem/index.rst @@ -11,4 +11,5 @@ todo: 由于文件系统模块重构,文档暂时不可用,预计在2023年4 overview vfs/index + sysfs diff --git a/docs/kernel/filesystem/sysfs.md b/docs/kernel/filesystem/sysfs.md new file mode 100644 index 00000000..19a885c9 --- /dev/null +++ b/docs/kernel/filesystem/sysfs.md @@ -0,0 +1,109 @@ +# SysFS + +:::{note} +本文作者:黄厅 + +Email: +::: + +## 1. SysFS和设备驱动模型 + +### 1.1. 设备、驱动、总线等彼此之间关系错综复杂 + +  如果想让内核运行流畅,那就必须为每个模块编码实现这些功能。如此一来,内核将变得非常臃肿、冗余。而设备模型的理念即是将这些代码抽象成各模块共用的框架,这样不但代码简洁了,也可让设备驱动开发者摆脱这本让人头痛但又必不可少的一劫,将有限的精力放于设备差异性的实现。 + +  设备模型恰是提供了一个模板,一个被证明过的最优的思路和流程,这减少了开发者设计过程中不必要的错误,也给以后的维护扫除了障碍。 + +### 1.2. sysfs是一个基于内存的文件系统,它的作用是将内核信息以文件的方式提供给用户程序使用。 + +  sysfs可以看成与proc,devfs和devpty同类别的文件系统,该文件系统是虚拟的文件系统,可以更方便对系统设备进行管理。它可以产生一个包含所有系统硬件层次视图,与提供进程和状态信息的proc文件系统十分类似。sysfs把连接在系统上的设备和总线组织成为一个分级的文件,它们可以由用户空间存取,向用户空间导出内核的数据结构以及它们的属性。 + +## 2. DragosOS中的设备驱动模型 + +### 2.1 由设备和驱动构成基本元素 + +#### 2.1.1. 设备 + +```rust +/// @brief: 所有设备都应该实现该trait +pub trait Device: Any + Send + Sync + Debug {} +``` + +  DragonOS采用全局设备管理器管理系统中所有的设备。 + +```rust +/// @brief Device管理器 +#[derive(Debug, Clone)] +pub struct DeviceManager { + devices: BTreeMap>, // 所有设备 + sys_info: Option>, // sys information +} +``` + +#### 2.1.2. 驱动 + +```rust +/// @brief: 所有驱动驱动都应该实现该trait +pub trait Driver: Any + Send + Sync + Debug {} +``` + +  同样的,驱动也使用全局的驱动管理器来管理 + +```rust +/// @brief: 驱动管理器 +#[derive(Debug, Clone)] +pub struct DriverManager { + drivers: BTreeMap>, // 所有驱动 + sys_info: Option>, // sys information +} +``` + +### 2.2. 总线 + +  总线属于设备的一种类型,同样需要驱动来初始化,同时由于总线的特殊性,使用全局的总线管理器来进行管理。 + +```rust +/// @brief: 总线驱动trait,所有总线驱动都应实现该trait +pub trait BusDriver: Driver {} + +/// @brief: 总线设备trait,所有总线都应实现该trait +pub trait Bus: Device {} + +/// @brief: 总线管理结构体 +#[derive(Debug, Clone)] +pub struct BusManager { + buses: BTreeMap>, // 总线设备表 + bus_drvs: BTreeMap>, // 总线驱动表 + sys_info: Option>, // 总线inode +} +``` + +  可以看到,每个管理器中均存在sys_info,设备模型通过该成员与sysfs建立联系,sys_info指向sysfs中唯一的inode。对于device而言,对应sysfs下的devices文件夹,其他亦是如此。 + +## 3. 驱动开发如何进行 + +  以平台总线platform为例,platform总线是一种虚拟总线,可以对挂载在其上的设备和驱动进行匹配,并驱动设备。该总线是一类设备,同时也是一类总线,编程时需要创建该设备实例,并为设备实例实现Device trait和Bus trait,以表明该结构是一类总线设备。同时,应该实现总线上的匹配规则,不同的总线匹配规则不同,该总线采用匹配表方式进行匹配,设备和驱动都应该存在一份匹配表,表示驱动支持的设备以及设备支持的驱动。 + +```rust +pub struct CompatibleTable(BTreeSet<&'static str>); +``` + +  对于bus设备而言,需要调用bus_register,将bus注册进系统,并在sysfs中可视化。 + +```rust +/// @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.get_id_table(), bus.clone()); + match sys_bus_register(&bus.get_id_table().to_name()) { + Ok(inode) => { + let _ = sys_bus_init(&inode); + return device_register(bus); + } + Err(_) => Err(DeviceError::RegisterError), + } +} +``` + +  通过bus_register源码可知,该函数不仅在sysfs/bus下生成总线文件夹,同时内部调用device_register,该函数将总线加入设备管理器中,同时在sys/devices下生成设备文件夹。 diff --git a/kernel/src/driver/base/device/bus.rs b/kernel/src/driver/base/device/bus.rs index 911fd8ed..8074df1e 100644 --- a/kernel/src/driver/base/device/bus.rs +++ b/kernel/src/driver/base/device/bus.rs @@ -1,13 +1,26 @@ -use super::{driver::Driver, Device, DeviceError, DeviceState, IdTable}; +use super::{ + device_register, device_unregister, + driver::{driver_register, driver_unregister, Driver, DriverError}, + Device, DeviceError, DeviceState, IdTable, +}; use crate::{ - filesystem::sysfs::{self, SYS_BUS_INODE}, - kdebug, + filesystem::{ + sysfs::{ + bus::{sys_bus_init, sys_bus_register}, + SYS_BUS_INODE, + }, + vfs::IndexNode, + }, libs::spinlock::SpinLock, }; use alloc::{collections::BTreeMap, sync::Arc}; use core::fmt::Debug; use lazy_static::lazy_static; +lazy_static! { + pub static ref BUS_MANAGER: Arc = Arc::new(LockedBusManager::new()); +} + /// @brief: 总线状态 #[derive(Debug, Copy, Clone)] pub enum BusState { @@ -58,52 +71,31 @@ pub trait BusDriver: Driver { } /// @brief: 总线设备trait,所有总线都应实现该trait -pub trait Bus: Device { - /// @brief: 注册bus,在sysfs中生成相应文件夹 - /// @parameter name: 文件夹名 - /// @return: 注册成功,返回(),注册失败,返回错误码 - fn register_bus(&self, name: &str) -> Result<(), DeviceError> { - match self.register_device(name) { - Ok(_) => { - let bus = sysfs::bus::bus_register(name).unwrap(); - kdebug!( - "After register_bus: ls /sys/bus/: {:?}", - SYS_BUS_INODE().list() - ); - match sysfs::bus::bus_init(&bus) { - Ok(_) => { - kdebug!("After register_bus: ls /sys/bus/{}: {:?}", name, bus.list()); - return Ok(()); - } - Err(_) => Err(DeviceError::RegisterError), - } - } - Err(err) => Err(err), - } - } -} +pub trait Bus: Device {} /// @brief: 总线管理结构体 #[derive(Debug, Clone)] pub struct BusManager { buses: BTreeMap>, // 总线设备表 bus_drvs: BTreeMap>, // 总线驱动表 + sys_info: Option>, // 总线inode } -/// @brief: 总线管理结构体加锁 -pub struct BusManagerLock(SpinLock); +/// @brief: bus管理(锁) +pub struct LockedBusManager(SpinLock); /// @brief: 总线管理方法集 -impl BusManagerLock { +impl LockedBusManager { /// @brief: 创建总线管理实例 /// @parameter: None /// @return: 总线管理实例 #[inline] #[allow(dead_code)] pub fn new() -> Self { - BusManagerLock(SpinLock::new(BusManager { + LockedBusManager(SpinLock::new(BusManager { buses: BTreeMap::new(), bus_drvs: BTreeMap::new(), + sys_info: Some(SYS_BUS_INODE()), })) } @@ -124,7 +116,7 @@ impl BusManagerLock { /// @return: None #[inline] #[allow(dead_code)] - pub fn add_bus_driver(&self, id_table: IdTable, bus_drv: Arc) { + 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); } @@ -164,12 +156,57 @@ impl BusManagerLock { /// @return: 总线驱动实例 #[inline] #[allow(dead_code)] - pub fn get_bus_driver(&self, id_table: &IdTable) -> Option> { + 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(); + } } -lazy_static! { - pub static ref BUS_MANAGER: Arc = Arc::new(BusManagerLock::new()); +/// @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.get_id_table(), bus.clone()); + match sys_bus_register(&bus.get_id_table().to_name()) { + Ok(inode) => { + let _ = sys_bus_init(&inode); + return device_register(bus); + } + Err(_) => Err(DeviceError::RegisterError), + } +} + +/// @brief: 总线注销,将总线从全局总线管理器中删除,并在sys/bus和sys/devices下删除文件夹 +/// @parameter bus: Bus设备实体 +/// @return: 成功:() 失败:DeviceError +#[allow(dead_code)] +pub fn bus_unregister(bus: Arc) -> Result<(), DeviceError> { + BUS_MANAGER.add_bus(bus.get_id_table(), bus.clone()); + return device_unregister(bus); +} + +/// @brief: 总线驱动注册,将总线驱动加入全局总线管理器中 +/// @parameter bus: Bus设备驱动实体 +/// @return: 成功:() 失败:DeviceError +pub fn bus_driver_register(bus_driver: Arc) -> Result<(), DriverError> { + BUS_MANAGER.add_driver(bus_driver.get_id_table(), bus_driver.clone()); + return driver_register(bus_driver); +} + +/// @brief: 总线驱动注销,将总线从全局总线管理器中删除 +/// @parameter bus: Bus设备驱动实体 +/// @return: 成功:() 失败:DeviceError +#[allow(dead_code)] +pub fn bus_driver_unregister(bus_driver: Arc) -> Result<(), DriverError> { + BUS_MANAGER.add_driver(bus_driver.get_id_table(), bus_driver.clone()); + return driver_unregister(bus_driver); } diff --git a/kernel/src/driver/base/device/driver.rs b/kernel/src/driver/base/device/driver.rs index 2a319e19..d7a5ba39 100644 --- a/kernel/src/driver/base/device/driver.rs +++ b/kernel/src/driver/base/device/driver.rs @@ -1,17 +1,139 @@ use super::IdTable; +use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError}; +use alloc::{collections::BTreeMap, sync::Arc}; use core::{any::Any, 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)] pub enum DriverError { ProbeError, + RegisterError, } -/// @brief: 所有设备驱动都应该实现该trait -pub trait Driver: Any + Send + Sync + Debug { - /// @brief: 获取设备驱动标识符 - /// @parameter: None - /// @return: 该设备驱动唯一标识符 - fn get_id_table(&self) -> IdTable; +impl Into for DriverError { + fn into(self) -> SystemError { + match self { + DriverError::ProbeError => SystemError::EIO, + DriverError::RegisterError => SystemError::EIO, + } + } +} + +/// @brief: 所有驱动驱动都应该实现该trait +pub trait Driver: Any + Send + Sync + Debug { + /// @brief: 本函数用于实现动态转换 + /// @parameter: None + /// @return: 该驱动驱动唯一标识符 + fn as_any_ref(&'static self) -> &'static dyn core::any::Any; + + /// @brief: 获取驱动驱动标识符 + /// @parameter: None + /// @return: 该驱动驱动唯一标识符 + fn get_id_table(&self) -> IdTable; + + /// @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>; +} + +/// @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(); + } +} + +/// @brief: 驱动管理器 +#[derive(Debug, Clone)] +pub struct DriverManager { + drivers: BTreeMap>, // 所有驱动 + sys_info: Option>, // sys information +} + +impl DriverManager { + /// @brief: 创建一个新的设备管理器 + /// @parameter: None + /// @return: DeviceManager实体 + #[inline] + fn new() -> DriverManager { + DriverManager { + drivers: BTreeMap::new(), + sys_info: None, + } + } +} + +/// @brief: 驱动注册 +/// @parameter: name: 驱动名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +pub fn driver_register(driver: Arc) -> Result<(), DriverError> { + DRIVER_MANAGER.add_driver(driver.get_id_table(), driver); + return Ok(()); +} + +/// @brief: 驱动卸载 +/// @parameter: name: 驱动名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +#[allow(dead_code)] +pub fn driver_unregister(driver: Arc) -> Result<(), DriverError> { + DRIVER_MANAGER.add_driver(driver.get_id_table(), driver); + return Ok(()); } diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index a70ad764..aa4bf943 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/kernel/src/driver/base/device/mod.rs @@ -1,9 +1,25 @@ -use crate::filesystem::sysfs::devices::device_register; +use alloc::{collections::BTreeMap, string::String, sync::Arc}; + +use crate::{ + filesystem::{ + sysfs::{ + devices::{sys_device_register, sys_device_unregister}, + SYS_DEVICES_INODE, + }, + vfs::IndexNode, + }, + libs::spinlock::SpinLock, + syscall::SystemError, +}; use core::{any::Any, fmt::Debug}; pub mod bus; pub mod driver; +lazy_static! { + pub static ref DEVICE_MANAGER: Arc = Arc::new(LockedDeviceManager::new()); +} + /// @brief: 设备类型 #[allow(dead_code)] #[derive(Debug, Eq, PartialEq)] @@ -32,6 +48,13 @@ impl IdTable { pub fn new(name: &'static str, id: u32) -> IdTable { Self(name, id) } + + /// @brief: 将设备标识符转换成name + /// @parameter None + /// @return: 设备名 + pub fn to_name(&self) -> String { + return format!("{}:{}", self.0, self.1); + } } /// @brief: 设备当前状态 @@ -53,6 +76,19 @@ pub enum DeviceError { RegisterError, // 注册失败 } +impl Into for DeviceError { + fn into(self) -> SystemError { + match self { + DeviceError::DriverExists => SystemError::EEXIST, + DeviceError::DeviceExists => SystemError::EEXIST, + DeviceError::InitializeFailed => SystemError::EIO, + DeviceError::NoDeviceForDriver => SystemError::ENODEV, + DeviceError::NoDriverForDevice => SystemError::ENODEV, + DeviceError::RegisterError => SystemError::EIO, + } + } +} + /// @brief: 将u32类型转换为设备状态类型 impl From for DeviceState { fn from(state: u32) -> Self { @@ -87,13 +123,111 @@ pub trait Device: Any + Send + Sync + Debug { /// @return: 该设备唯一标识 fn get_id_table(&self) -> IdTable; - /// @brief: 设备注册 - /// @parameter: name: 设备名 - /// @return: 操作成功,返回(),操作失败,返回错误码 - fn register_device(&self, name: &str) -> Result<(), DeviceError> { - match device_register(name) { - Ok(_) => Ok(()), - Err(_) => Err(DeviceError::RegisterError), + /// @brief: 设置sysfs info + /// @parameter: None + /// @return: 该设备唯一标识 + fn set_sys_info(&self, sys_info: Option>); + + /// @brief: 获取设备的sys information + /// @parameter id_table: 设备标识符,用于唯一标识该设备 + /// @return: 设备实例 + fn sys_info(&self) -> Option>; +} + +/// @brief Device管理器(锁) +#[derive(Debug)] +pub struct LockedDeviceManager(SpinLock); + +impl LockedDeviceManager { + fn new() -> LockedDeviceManager { + LockedDeviceManager(SpinLock::new(DeviceManager::new())) + } + + /// @brief: 添加设备 + /// @parameter id_table: 总线标识符,用于唯一标识该总线 + /// @parameter dev: 设备实例 + /// @return: None + #[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); + } + + /// @brief: 卸载设备 + /// @parameter id_table: 总线标识符,用于唯一标识该设备 + /// @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); + } + + /// @brief: 获取设备 + /// @parameter id_table: 设备标识符,用于唯一标识该设备 + /// @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() + } + + /// @brief: 获取设备管理器的sys information + /// @parameter id_table: 设备标识符,用于唯一标识该设备 + /// @return: 设备实例 + #[inline] + #[allow(dead_code)] + fn sys_info(&self) -> Option> { + return self.0.lock().sys_info.clone(); + } +} + +/// @brief Device管理器 +#[derive(Debug, Clone)] +pub struct DeviceManager { + devices: BTreeMap>, // 所有设备 + sys_info: Option>, // sys information +} + +impl DeviceManager { + /// @brief: 创建一个新的设备管理器 + /// @parameter: None + /// @return: DeviceManager实体 + #[inline] + fn new() -> DeviceManager { + DeviceManager { + devices: BTreeMap::new(), + sys_info: Some(SYS_DEVICES_INODE()), } } } + +/// @brief: 设备注册 +/// @parameter: name: 设备名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +pub fn device_register(device: Arc) -> Result<(), DeviceError> { + DEVICE_MANAGER.add_device(device.get_id_table(), device.clone()); + match sys_device_register(&device.get_id_table().to_name()) { + Ok(sys_info) => { + device.set_sys_info(Some(sys_info)); + return Ok(()); + } + Err(_) => Err(DeviceError::RegisterError), + } +} + +/// @brief: 设备卸载 +/// @parameter: name: 设备名 +/// @return: 操作成功,返回(),操作失败,返回错误码 +pub fn device_unregister(device: Arc) -> Result<(), DeviceError> { + DEVICE_MANAGER.add_device(device.get_id_table(), device.clone()); + match sys_device_unregister(&device.get_id_table().to_name()) { + Ok(_) => { + device.set_sys_info(None); + return Ok(()); + } + Err(_) => Err(DeviceError::RegisterError), + } +} diff --git a/kernel/src/driver/base/platform/mod.rs b/kernel/src/driver/base/platform/mod.rs index 862c4848..76817906 100644 --- a/kernel/src/driver/base/platform/mod.rs +++ b/kernel/src/driver/base/platform/mod.rs @@ -1,16 +1,15 @@ use super::device::{ - bus::{Bus, BusDriver, BusState, BUS_MANAGER}, + bus::{bus_driver_register, bus_register, Bus, BusDriver, BusState}, driver::Driver, Device, DeviceError, DeviceState, DeviceType, IdTable, }; -use crate::libs::{mutex::Mutex, rwlock::RwLock}; +use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError}; use alloc::{ collections::{BTreeMap, BTreeSet}, sync::Arc, vec::Vec, }; use core::fmt::Debug; -use lazy_static::lazy_static; use platform_device::PlatformDevice; use platform_driver::PlatformDriver; @@ -48,24 +47,17 @@ impl CompatibleTable { } } -/// @brief: platform总线驱动 #[derive(Debug)] -pub struct PlatformBusDriver { - drivers: RwLock>>, // 总线上所有驱动 - devices: RwLock>>, // 总线上所有设备 -} +pub struct LockedPlatformBusDriver(SpinLock); -impl PlatformBusDriver { - /// @brief: 创建一个platform总线驱动,该驱动用于匹配plaform总线 +impl LockedPlatformBusDriver { + /// @brief: 创建一个platform总线加锁驱动,该驱动用于匹配plaform总线 /// @parameter: None /// @return: platfor总线驱动 #[inline] #[allow(dead_code)] - pub fn new() -> Self { - Self { - drivers: RwLock::new(BTreeMap::new()), - devices: RwLock::new(BTreeMap::new()), - } + pub fn new() -> LockedPlatformBusDriver { + LockedPlatformBusDriver(SpinLock::new(PlatformBusDriver::new())) } /// @brief: 获取该驱动的匹配表 @@ -83,7 +75,7 @@ impl PlatformBusDriver { #[inline] #[allow(dead_code)] fn get_device(&self, id_table: &IdTable) -> Option> { - let device_map = self.devices.read(); + let device_map = &self.0.lock().devices; return device_map.get(id_table).cloned(); } @@ -93,7 +85,7 @@ impl PlatformBusDriver { #[inline] #[allow(dead_code)] fn get_driver(&self, id_table: &IdTable) -> Option> { - let driver_map = self.drivers.read(); + let driver_map = &self.0.lock().drivers; return driver_map.get(id_table).cloned(); } @@ -101,13 +93,10 @@ impl PlatformBusDriver { /// @parameter driver: platform类型驱动,该驱动需要实现PlatformDriver trait /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型 #[allow(dead_code)] - fn register_platform_driver( - &mut self, - driver: Arc, - ) -> Result<(), DeviceError> { + fn register_platform_driver(&self, driver: Arc) -> Result<(), DeviceError> { let id_table = driver.get_id_table(); - let mut drivers = self.drivers.write(); + let drivers = &mut self.0.lock().drivers; // 如果存在同类型的驱动,返回错误 if drivers.contains_key(&id_table) { return Err(DeviceError::DriverExists); @@ -124,7 +113,7 @@ impl PlatformBusDriver { #[inline] fn unregister_platform_driver(&mut self, driver: Arc) { let id_table = driver.get_id_table(); - self.drivers.write().remove(&id_table); + self.0.lock().drivers.remove(&id_table); } /// @brief: 注册platform类型设备 @@ -137,7 +126,7 @@ impl PlatformBusDriver { ) -> Result<(), DeviceError> { let id_table = device.get_id_table(); - let mut devices = self.devices.write(); + let devices = &mut self.0.lock().devices; if devices.contains_key(&id_table) { return Err(DeviceError::DeviceExists); } else { @@ -153,7 +142,7 @@ impl PlatformBusDriver { #[allow(dead_code)] fn unregister_platform_device(&mut self, device: Arc) { let id_table = device.get_id_table(); - self.devices.write().remove(&id_table); + self.0.lock().devices.remove(&id_table); } /// @brief: 匹配platform类型驱动 @@ -162,7 +151,7 @@ impl PlatformBusDriver { #[allow(dead_code)] fn driver_match_device(&self, driver: Arc) -> Result { let mut num = 0; - let devices = self.devices.read(); + let devices = &self.0.lock().devices; for (_dev_id_table, device) in devices.iter() { if device @@ -194,8 +183,8 @@ impl PlatformBusDriver { /// @return: 如果匹配成功,返回Ok(()),否则,返回BusError类型 #[allow(dead_code)] fn device_match_driver(&self, device: Arc) -> Result<(), DeviceError> { - let drivers = self.drivers.read(); - for (_drv_id_table, driver) in &*drivers { + let drivers = &mut self.0.lock().drivers; + for (_drv_id_table, driver) in drivers.into_iter() { if driver .get_compatible_table() .matches(&device.get_compatible_table()) @@ -214,17 +203,58 @@ impl PlatformBusDriver { } } +/// @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 PlatformBusDriver { +impl Driver for LockedPlatformBusDriver { + #[inline] + fn as_any_ref(&self) -> &dyn core::any::Any { + self + } + + #[inline] fn get_id_table(&self) -> IdTable { IdTable::new("PlatformBusDriver", 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; + } } /// @brief: 为PlatformBusDriver实现BusDriver trait -impl BusDriver for PlatformBusDriver { +impl BusDriver for LockedPlatformBusDriver { fn is_empty(&self) -> bool { - if self.devices.read().is_empty() && self.drivers.read().is_empty() { + if self.0.lock().devices.is_empty() && self.0.lock().drivers.is_empty() { return true; } else { return false; @@ -232,23 +262,15 @@ impl BusDriver for PlatformBusDriver { } } -/// @brief: platform总线 -#[derive(Debug, Clone)] -pub struct Platform { - state: Arc>, // 总线状态 - driver: Option>, // 总线驱动 -} +#[derive(Debug)] +pub struct LockedPlatform(SpinLock); -/// @brief: platform方法集 -impl Platform { - /// @brief: 创建一个platform总线实例 +impl LockedPlatform { + /// @brief: 创建一个加锁的platform总线实例 /// @parameter: None /// @return: platform总线实例 - pub fn new() -> Self { - Self { - state: Arc::new(Mutex::new(BusState::NotInitialized)), - driver: Option::None, - } + pub fn new() -> LockedPlatform { + LockedPlatform(SpinLock::new(Platform::new())) } /// @brief: 获取总线的匹配表 @@ -266,8 +288,8 @@ impl Platform { #[inline] #[allow(dead_code)] fn is_initialized(&self) -> bool { - let state = self.state.lock(); - match *state { + let state = self.0.lock().state; + match state { BusState::Initialized => true, _ => false, } @@ -278,7 +300,7 @@ impl Platform { /// @return: None #[inline] fn set_state(&self, set_state: BusState) { - let mut state = self.state.lock(); + let state = &mut self.0.lock().state; *state = set_state; } @@ -288,8 +310,8 @@ impl Platform { #[inline] #[allow(dead_code)] fn get_state(&self) -> BusState { - let state = self.state.lock(); - return *state; + let state = self.0.lock().state; + return state; } /// @brief: @@ -297,66 +319,72 @@ impl Platform { /// @return: 总线状态 #[inline] #[allow(dead_code)] - fn set_driver(&mut self, driver: Option>) { - self.driver = driver; + fn set_driver(&self, driver: Option>) { + self.0.lock().driver = driver; + } +} + +/// @brief: platform总线 +#[derive(Debug, Clone)] +pub struct Platform { + state: BusState, // 总线状态 + driver: Option>, // 总线驱动 + sys_info: Option>, // 总线sys information +} + +/// @brief: platform方法集 +impl Platform { + /// @brief: 创建一个platform总线实例 + /// @parameter: None + /// @return: platform总线实例 + pub fn new() -> Self { + Self { + state: BusState::NotInitialized, + driver: Option::None, + sys_info: Option::None, + } } } /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型 -impl Device for Platform { - /// @brief: 获取platform设备类型 - /// @parameter: None - /// @return: Bus类型 +impl Device for LockedPlatform { #[inline] #[allow(dead_code)] fn get_type(&self) -> DeviceType { return DeviceType::Bus; } - /// @brief: 获取platform设备标识符 - /// @parameter: None - /// @return: platform总线设备标识符 #[inline] #[allow(dead_code)] fn get_id_table(&self) -> IdTable { IdTable::new("platform", 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(); + } } /// @brief: 为Platform实现Bus trait,platform总线是一种总线设备 -impl Bus for Platform {} - -lazy_static! { - pub static ref BUS_PLATFORM_DRIVER: Arc = Arc::new(PlatformBusDriver::new()); - pub static ref BUS_PLATFORM_DEVICE: Arc = Arc::new(Platform::new()); -} +impl Bus for LockedPlatform {} /// @brief: 初始化platform总线 /// @parameter: None /// @return: None -#[allow(dead_code)] -pub fn platform_bus_init() { - BUS_MANAGER.add_bus_driver( - BUS_PLATFORM_DRIVER.get_id_table(), - BUS_PLATFORM_DRIVER.clone(), - ); - BUS_MANAGER.add_bus( - BUS_PLATFORM_DEVICE.get_id_table(), - BUS_PLATFORM_DEVICE.clone(), - ); - BUS_PLATFORM_DEVICE.set_state(BusState::Initialized); - let _ = BUS_PLATFORM_DEVICE.register_bus("platform"); -} +pub fn platform_bus_init() -> Result<(), SystemError> { + let platform_driver: Arc = Arc::new(LockedPlatformBusDriver::new()); + let platform_device: Arc = Arc::new(LockedPlatform::new()); + 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())?; -#[no_mangle] -extern "C" fn c_platform_bus_init() { - BUS_MANAGER.add_bus_driver( - BUS_PLATFORM_DRIVER.get_id_table(), - BUS_PLATFORM_DRIVER.clone(), - ); - BUS_MANAGER.add_bus( - BUS_PLATFORM_DEVICE.get_id_table(), - BUS_PLATFORM_DEVICE.clone(), - ); - BUS_PLATFORM_DEVICE.set_state(BusState::Initialized); + return Ok(()); } diff --git a/kernel/src/filesystem/sysfs/bus.rs b/kernel/src/filesystem/sysfs/bus.rs index 39760cb4..0df220f1 100644 --- a/kernel/src/filesystem/sysfs/bus.rs +++ b/kernel/src/filesystem/sysfs/bus.rs @@ -7,7 +7,7 @@ use alloc::sync::Arc; /// @return: 操作成功,返回inode,操作失败,返回错误码 #[inline] #[allow(dead_code)] -pub fn bus_register(bus_name: &str) -> Result, SystemError> { +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 @@ -21,9 +21,8 @@ pub fn bus_register(bus_name: &str) -> Result, SystemError> { /// @brief: 注销bus,在sys/bus删除文件夹 /// @parameter bus_name: 总线文件夹名 /// @return: 操作成功,返回(),操作失败,返回错误码 -#[inline] #[allow(dead_code)] -pub fn bus_unregister(bus_name: &str) -> Result<(), SystemError> { +pub fn sys_bus_unregister(bus_name: &str) -> Result<(), SystemError> { let binding: Arc = SYS_BUS_INODE(); binding .as_any_ref() @@ -36,9 +35,7 @@ pub fn bus_unregister(bus_name: &str) -> Result<(), SystemError> { /// @brief: 在相应总线文件夹下生成devices和drivers文件夹 /// @parameter inode: 总线文件夹inode /// @return: 操作成功,返回devices inode和drivers inode,操作失败,返回错误码 -#[inline] -#[allow(dead_code)] -pub fn bus_init( +pub fn sys_bus_init( inode: &Arc, ) -> Result<(Arc, Arc), SystemError> { match inode.as_any_ref().downcast_ref::() { diff --git a/kernel/src/filesystem/sysfs/class.rs b/kernel/src/filesystem/sysfs/class.rs index 779fe596..d924fd4d 100644 --- a/kernel/src/filesystem/sysfs/class.rs +++ b/kernel/src/filesystem/sysfs/class.rs @@ -7,7 +7,7 @@ use alloc::sync::Arc; /// @return: 操作成功,返回inode,操作失败,返回错误码 #[inline] #[allow(dead_code)] -pub fn class_register(class_name: &str) -> Result, SystemError> { +pub fn sys_class_register(class_name: &str) -> Result, SystemError> { let binding: Arc = SYS_CLASS_INODE(); binding .as_any_ref() @@ -22,7 +22,7 @@ pub fn class_register(class_name: &str) -> Result, SystemErro /// @return: 操作成功,返回(),操作失败,返回错误码 #[inline] #[allow(dead_code)] -pub fn class_unregister(class_name: &str) -> Result<(), SystemError> { +pub fn sys_class_unregister(class_name: &str) -> Result<(), SystemError> { let binding: Arc = SYS_CLASS_INODE(); binding .as_any_ref() @@ -38,7 +38,7 @@ pub fn class_unregister(class_name: &str) -> Result<(), SystemError> { /// @return: 操作成功,返回inode,操作失败,返回错误码 #[inline] #[allow(dead_code)] -pub fn device_register( +pub fn class_device_register( class: Arc, device_name: &str, ) -> Result, SystemError> { @@ -56,7 +56,10 @@ pub fn device_register( /// @return: 操作成功,返回(),操作失败,返回错误码 #[inline] #[allow(dead_code)] -pub fn device_unregister(class: Arc, device_name: &str) -> Result<(), SystemError> { +pub fn class_device_unregister( + class: Arc, + device_name: &str, +) -> Result<(), SystemError> { class .as_any_ref() .downcast_ref::() diff --git a/kernel/src/filesystem/sysfs/devices.rs b/kernel/src/filesystem/sysfs/devices.rs index fd6ff5f3..6ab987c4 100644 --- a/kernel/src/filesystem/sysfs/devices.rs +++ b/kernel/src/filesystem/sysfs/devices.rs @@ -7,7 +7,7 @@ use alloc::sync::Arc; /// @return: 操作成功,返回inode,操作失败,返回错误码 #[inline] #[allow(dead_code)] -pub fn device_register(device_name: &str) -> Result, SystemError> { +pub fn sys_device_register(device_name: &str) -> Result, SystemError> { let binding: Arc = SYS_DEVICES_INODE(); binding .as_any_ref() @@ -22,7 +22,7 @@ pub fn device_register(device_name: &str) -> Result, SystemEr /// @return: 操作成功,返回(),操作失败,返回错误码 #[inline] #[allow(dead_code)] -pub fn device_unregister(device_name: &str) -> Result<(), SystemError> { +pub fn sys_device_unregister(device_name: &str) -> Result<(), SystemError> { let binding: Arc = SYS_DEVICES_INODE(); binding .as_any_ref() diff --git a/kernel/src/filesystem/sysfs/mod.rs b/kernel/src/filesystem/sysfs/mod.rs index 90d5d770..cee12fdc 100644 --- a/kernel/src/filesystem/sysfs/mod.rs +++ b/kernel/src/filesystem/sysfs/mod.rs @@ -137,7 +137,7 @@ impl SysFS { Err(_) => panic!("SysFS: Failed to create /sys/fs"), } // 初始化platform总线 - crate::driver::base::platform::platform_bus_init(); + crate::driver::base::platform::platform_bus_init().expect("platform bus init failed"); return sysfs; } } diff --git a/kernel/src/ipc/pipe.rs b/kernel/src/ipc/pipe.rs index b1e34331..863d6002 100644 --- a/kernel/src/ipc/pipe.rs +++ b/kernel/src/ipc/pipe.rs @@ -94,7 +94,7 @@ impl IndexNode for LockedPipeInode { let irq_guard = CurrentIrqArch::save_and_disable_irq(); inode.read_wait_queue.sleep_without_schedule(); drop(inode); - + drop(irq_guard); } sched();