完善设备驱动模型,基于kset、kobj来维护对象之间的关系 (#401)

* 使用kobj和kset管理/sys文件夹下的对象

* 修改notifier,把action从u64换为泛型。

* 完善设备驱动模型,基于kset、kobj来维护对象之间的关系
This commit is contained in:
LoGin 2023-10-11 00:53:15 +08:00 committed by GitHub
parent 6abb8bd7c0
commit 06d5e24726
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 3492 additions and 1530 deletions

View File

@ -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<dyn Device>) {
return;
}

View File

@ -15,6 +15,7 @@ use crate::{
};
mod c_adapter;
pub mod glue;
pub mod old;
extern crate acpi;

View File

@ -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<dyn BlockDevice>, id_table: IdTable) {
pub fn bdev_add(_bdev: Arc<dyn BlockDevice>, id_table: IdTable) -> Result<(), DeviceError> {
if Into::<usize>::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设备注销

View File

@ -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;
}

View File

@ -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<dyn CharDevice>, id_table: IdTable, range: usize) {
pub fn cdev_add(
cdev: Arc<dyn CharDevice>,
id_table: IdTable,
range: usize,
) -> Result<(), SystemError> {
if Into::<usize>::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);
}
}

View File

@ -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<Arc<KSet>> = None;
#[inline(always)]
#[allow(dead_code)]
pub fn sys_class_kset() -> Arc<KSet> {
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(());
}

View File

@ -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,
sysfs::{file::sysfs_emit_str, sysfs_instance, Attribute, AttributeGroup, SysFSOpsSupport},
vfs::syscall::ModeType,
},
vfs::IndexNode,
},
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<LockedBusManager> = Arc::new(LockedBusManager::new());
/// `/sys/bus`的kset
static mut BUS_KSET_INSTANCE: Option<Arc<KSet>> = None;
/// `/sys/devices/system`的kset
static mut DEVICES_SYSTEM_KSET_INSTANCE: Option<Arc<KSet>> = None;
static mut BUS_MANAGER_INSTANCE: Option<BusManager> = None;
#[inline(always)]
pub fn sys_bus_kset() -> Arc<KSet> {
unsafe { BUS_KSET_INSTANCE.clone().unwrap() }
}
#[inline(always)]
#[allow(dead_code)]
pub fn sys_devices_system_kset() -> Arc<KSet> {
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<BusState> 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<Arc<dyn Device>> {
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<T: Copy>(
&self,
matcher: &dyn DeviceMatcher<T>,
data: T,
) -> Option<Arc<dyn Device>> {
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<Arc<dyn Device>> {
return self.find_device(&DeviceMatchName, name);
}
}
/// @brief: 总线管理结构体
#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct BusManager {
buses: BTreeMap<IdTable, Arc<dyn Bus>>, // 总线设备表
bus_drvs: BTreeMap<IdTable, Arc<dyn BusDriver>>, // 总线驱动表
sys_info: Option<Arc<dyn IndexNode>>, // 总线inode
/// 存储总线bus的kset结构体与bus实例的映射(用于在sysfs callback的时候,根据kset找到bus实例)
kset_bus_map: RwLock<HashMap<Arc<KSet>, Arc<dyn Bus>>>,
}
/// @brief: bus管理(锁)
pub struct LockedBusManager(SpinLock<BusManager>);
/// @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<dyn Bus>) {
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<dyn Bus>) -> 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<dyn BusDriver>) {
let mut bus_manager = self.0.lock();
bus_manager.bus_drvs.insert(id_table, bus_drv);
pub fn unregister(&self, _bus: Arc<dyn Bus>) -> 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<dyn Bus>) -> Result<(), SystemError> {
self.create_file(bus, &BusAttrDriversProbe)?;
let r = self.create_file(bus, &BusAttrDriversAutoprobe);
if r.is_err() {
self.remove_file(bus, &BusAttrDriversProbe);
}
return r;
}
/// @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);
fn remove_probe_files(&self, bus: &Arc<dyn Bus>) {
self.remove_file(bus, &BusAttrDriversAutoprobe);
self.remove_file(bus, &BusAttrDriversProbe);
}
/// @brief: 获取总线设备
/// @parameter id_table: 总线标识符,用于唯一标识该总线
/// @return: 总线设备实例
#[inline]
#[allow(dead_code)]
pub fn get_bus(&self, id_table: &IdTable) -> Option<Arc<dyn Bus>> {
let bus_manager = self.0.lock();
bus_manager.buses.get(id_table).cloned()
fn create_file(
&self,
bus: &Arc<dyn Bus>,
attr: &'static dyn Attribute,
) -> Result<(), SystemError> {
let bus_kobj = bus.subsystem().subsys() as Arc<dyn KObject>;
return sysfs_instance().create_file(&bus_kobj, attr);
}
/// @brief: 获取总线驱动
/// @parameter id_table: 总线驱动标识符,用于唯一标识该总线驱动
/// @return: 总线驱动实例
#[inline]
#[allow(dead_code)]
pub fn get_driver(&self, id_table: &IdTable) -> Option<Arc<dyn BusDriver>> {
let bus_manager = self.0.lock();
return bus_manager.bus_drvs.get(id_table).cloned();
fn remove_file(&self, bus: &Arc<dyn Bus>, attr: &'static dyn Attribute) {
let bus_kobj = bus.subsystem().subsys() as Arc<dyn KObject>;
sysfs_instance().remove_file(&bus_kobj, attr);
}
/// @brief: 获取总线管理器的sys information
/// @parameter None
/// @return: sys inode
#[inline]
fn add_groups(
&self,
bus: &Arc<dyn Bus>,
groups: &[&'static dyn AttributeGroup],
) -> Result<(), SystemError> {
let bus_kobj = bus.subsystem().subsys() as Arc<dyn KObject>;
return sysfs_instance().create_groups(&bus_kobj, groups);
}
/// 根据bus的kset找到bus实例
fn get_bus_by_kset(&self, kset: &Arc<KSet>) -> Option<Arc<dyn Bus>> {
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<dyn Bus>) -> 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<dyn Device>) {
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)]
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
return self.0.lock().sys_info.clone();
pub fn find_device<T: Copy>(
&self,
bus: &Arc<dyn Bus>,
matcher: &dyn DeviceMatcher<T>,
data: T,
) -> Option<Arc<dyn Device>> {
return bus.find_device(matcher, data);
}
}
/// @brief: 总线注册将总线加入全局总线管理器中并根据id table在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<dyn Device>) -> 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<dyn Bus>) -> Result<(), SystemError> {
return bus_manager().register(bus);
}
/// @brief: 总线注销并在sys/bus和sys/devices下删除文件夹
/// @parameter bus: Bus设备实体
/// @return: 成功:() 失败:DeviceError
pub fn bus_register<T: Bus>(bus: Arc<T>) -> 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);
/// @return: 成功:() 失败:SystemError
#[allow(dead_code)]
pub fn bus_unregister(bus: Arc<dyn Bus>) -> Result<(), SystemError> {
return bus_manager().unregister(bus);
}
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);
}
Err(_) => Err(DeviceError::RegisterError),
// 初始化 /sys/devices/system
{
let devices_system_kset = KSet::new("system".to_string());
let parent = sys_devices_kset() as Arc<dyn KObject>;
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(());
}
/// 把一个设备添加到总线上
///
/// ## 描述
///
/// - 添加一个设备的与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<dyn Device>) -> 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<dyn Device>) {
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<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError> {
let kset: Arc<KSet> = 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);
}
}
/// @brief: 总线注销将总线从全局总线管理器中删除并在sys/bus和sys/devices下删除文件夹
/// @parameter bus: Bus设备实体
/// @return: 成功:() 失败:DeviceError
#[allow(dead_code)]
pub fn bus_unregister<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
BUS_MANAGER.remove_bus(&bus.id_table());
return device_unregister(bus);
#[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<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError> {
if buf.len() == 0 {
return Ok(0);
}
let kset: Arc<KSet> = 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<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let kset: Arc<KSet> = 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());
}
}
/// @brief: 总线驱动注册,将总线驱动加入全局总线管理器中
/// @parameter bus: Bus设备驱动实体
/// @return: 成功:() 失败:DeviceError
pub fn bus_driver_register(bus_driver: Arc<dyn BusDriver>) -> Result<(), DriverError> {
BUS_MANAGER.add_driver(bus_driver.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<dyn BusDriver>) -> Result<(), DriverError> {
BUS_MANAGER.remove_bus_driver(&bus_driver.id_table());
return driver_unregister(bus_driver);
#[derive(Debug, Clone, Copy)]
pub enum BusNotifyEvent {
/// 一个设备被添加到总线上
AddDevice,
/// 一个设备将要被移除
DelDevice,
/// 一个设备已经被移除
RemovedDevice,
/// 一个驱动将要被绑定
BindDriver,
/// 一个驱动已经被绑定
BoundDriver,
/// 一个驱动将要被解绑
UnbindDriver,
/// 一个驱动已经被解绑
UnboundDriver,
/// 驱动绑定失败
DriverNotBound,
}

View File

@ -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<dyn Device>) -> Result<bool, SystemError> {
return self.do_device_attach(dev, false);
}
pub fn device_initial_probe(&self, dev: &Arc<dyn Device>) -> Result<bool, SystemError> {
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<dyn Device>,
allow_async: bool,
) -> Result<bool, SystemError> {
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<dyn Driver>,
_data: &mut DeviceAttachData,
) -> Result<(), SystemError> {
todo!("do_device_attach_driver")
}
/// 检查设备是否绑定到驱动程序
///
/// ## 参数
///
/// - `dev`: 设备
///
/// ## 返回
///
/// 如果传递的设备已成功完成对驱动程序的探测则返回true否则返回false。
pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> 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<dyn Device>) -> 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<dyn Device>) {
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<dyn Device>,
/// 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<dyn Device>, 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;
}
}

View File

@ -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<LockedDriverManager> = Arc::new(LockedDriverManager::new());
}
/// @brief: Driver error
#[allow(dead_code)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -32,93 +26,18 @@ impl Into<SystemError> for DriverError {
}
}
/// @brief: 驱动管理器(锁)
#[derive(Debug)]
pub struct LockedDriverManager(SpinLock<DriverManager>);
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<dyn Driver>) {
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<Arc<dyn Driver>> {
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<Arc<dyn IndexNode>> {
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<IdTable, Arc<dyn Driver>>, // 所有驱动
sys_info: Option<Arc<dyn IndexNode>>, // 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<dyn Device>) -> Result<(), SystemError> {
todo!("DriverManager::driver_sysfs_add()");
}
}
/// @brief: 驱动注册
/// @parameter: name: 驱动名
/// @return: 操作成功,返回(),操作失败,返回错误码
pub fn driver_register(driver: Arc<dyn Driver>) -> 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<dyn Driver>) -> Result<(), DriverError> {
DRIVER_MANAGER.remove_driver(&driver.id_table());
return Ok(());
}

View File

@ -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<dyn KObject>;
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<dyn KObject>;
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(());
}

View File

@ -1,32 +1,45 @@
use alloc::{
collections::BTreeMap,
string::{String, ToString},
sync::Arc,
};
use intertrait::cast::CastArc;
use crate::{
driver::base::map::{LockedDevsMap, LockedKObjMap},
driver::{
acpi::glue::acpi_device_notify,
base::map::{LockedDevsMap, LockedKObjMap},
Driver,
},
filesystem::{
sysfs::{
devices::{sys_device_register, sys_device_unregister},
SYS_DEVICES_INODE,
sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport},
vfs::syscall::ModeType,
},
vfs::IndexNode,
},
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<LockedDeviceManager> = Arc::new(LockedDeviceManager::new());
static mut DEVICE_MANAGER: Option<DeviceManager> = None;
#[inline(always)]
pub fn device_manager() -> &'static DeviceManager {
unsafe { DEVICE_MANAGER.as_ref().unwrap() }
}
lazy_static! {
// 全局字符设备号管理实例
pub static ref CHARDEVS: Arc<LockedDevsMap> = 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<Arc<KSet>> = None;
/// `/sys/dev` 的 kset 实例
static mut DEV_KSET_INSTANCE: Option<Arc<KSet>> = None;
/// `/sys/dev/block` 的 kset 实例
static mut DEV_BLOCK_KSET_INSTANCE: Option<Arc<KSet>> = None;
/// `/sys/dev/char` 的 kset 实例
static mut DEV_CHAR_KSET_INSTANCE: Option<Arc<KSet>> = None;
#[inline(always)]
pub(super) fn sys_devices_kset() -> Arc<KSet> {
unsafe { DEVICES_KSET_INSTANCE.as_ref().unwrap().clone() }
}
#[inline(always)]
pub(super) fn sys_dev_kset() -> Arc<KSet> {
unsafe { DEV_KSET_INSTANCE.as_ref().unwrap().clone() }
}
#[inline(always)]
#[allow(dead_code)]
pub(super) fn sys_dev_block_kset() -> Arc<KSet> {
unsafe { DEV_BLOCK_KSET_INSTANCE.as_ref().unwrap().clone() }
}
#[inline(always)]
pub(self) fn sys_dev_char_kset() -> Arc<KSet> {
unsafe { DEV_CHAR_KSET_INSTANCE.as_ref().unwrap().clone() }
}
/// 设备应该实现的操作
///
/// ## 注意
///
/// 由于设备驱动模型需要从Arc<dyn KObject>转换为Arc<dyn Device>
/// 因此所有的实现了Device trait的结构体都应该在结构体上方标注`#[[sync] Device]`
///
/// 否则在释放设备资源的时候会由于无法转换为Arc<dyn Device>而导致资源泄露并且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<Arc<dyn IndexNode>>);
/// 设备释放时的回调函数
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<Arc<dyn IndexNode>>;
/// 获取当前设备所属的总线
fn bus(&self) -> Option<Arc<dyn Bus>> {
return None;
}
/// 返回已经与当前设备匹配好的驱动程序
fn driver(&self) -> Option<Arc<dyn Driver>>;
fn set_driver(&self, driver: Option<Arc<dyn Driver>>);
/// 当前设备是否已经挂掉了
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<DeviceState> for u32 {
}
}
/// @brief Device管理器(锁)
#[derive(Debug)]
pub struct LockedDeviceManager(SpinLock<DeviceManager>);
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<dyn KObject>) {
let dev = kobj.cast::<dyn Device>().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<dyn KObject>,
attr: &dyn Attribute,
buf: &[u8],
) -> Result<usize, SystemError> {
return attr.store(kobj, buf);
}
fn show(
&self,
kobj: Arc<dyn KObject>,
attr: &dyn Attribute,
buf: &mut [u8],
) -> Result<usize, SystemError> {
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<dyn Device>) {
let mut device_manager = self.0.lock();
device_manager.devices.insert(id_table, dev);
pub fn add_device(&self, device: Arc<dyn Device>) -> Result<(), SystemError> {
// todo: 引入class后在这里处理与parent相关的逻辑
KObjectManager::add_kobj(device.clone() as Arc<dyn KObject>, 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<Arc<dyn Device>> {
let device_manager = self.0.lock();
device_manager.devices.get(id_table).cloned()
pub fn find_device_by_idtable(&self, _id_table: &IdTable) -> Option<Arc<dyn Device>> {
todo!("find_device_by_idtable")
}
/// @brief: 获取设备管理器的sys information
/// @parameter id_table: 设备标识符,用于唯一标识该设备
/// @return: 设备实例
#[inline]
fn device_platform_notify(&self, dev: &Arc<dyn Device>) {
acpi_device_notify(dev);
software_node_notify(dev);
}
fn add_class_symlinks(&self, _dev: &Arc<dyn Device>) -> Result<(), SystemError> {
// todo: 引入class后在这里处理与class相关的逻辑
// https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c#3224
return Ok(());
}
/// 在sysfs中为指定的设备创建属性文件
///
/// ## 参数
///
/// - `dev`: 设备
fn add_attrs(&self, dev: &Arc<dyn Device>) -> 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<dyn Device>,
attr_groups: &'static [&dyn AttributeGroup],
) -> Result<(), SystemError> {
let dev = dev.clone();
let binding = dev.arc_any();
let kobj: &Arc<dyn KObject> = binding.downcast_ref().unwrap();
return sysfs_instance().create_groups(kobj, attr_groups);
}
/// 为设备在sysfs中创建属性文件
///
/// ## 参数
///
/// - `dev`: 设备
/// - `attr`: 属性
pub fn create_file(
&self,
dev: &Arc<dyn Device>,
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<dyn KObject>;
return sysfs_instance().create_file(&kobj, attr);
}
/// 在/sys/dev下或者设备所属的class下为指定的设备创建链接
fn create_sys_dev_entry(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
let target_kobj = self.device_to_dev_kobj(dev);
let name = dev.id_table().name();
let current_kobj = dev.clone() as Arc<dyn KObject>;
return sysfs_instance().create_link(&current_kobj, &target_kobj, name);
}
/// Delete symlink for device in `/sys/dev` or `/sys/class/<class_name>`
#[allow(dead_code)]
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
return self.0.lock().sys_info.clone();
fn remove_sys_dev_entry(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
let kobj = self.device_to_dev_kobj(dev);
let name = dev.id_table().name();
return sysfs_instance().remove_link(&kobj, name);
}
}
/// @brief Device管理器
#[derive(Debug, Clone)]
pub struct DeviceManager {
devices: BTreeMap<IdTable, Arc<dyn Device>>, // 所有设备
sys_info: Option<Arc<dyn IndexNode>>, // sys information
}
impl DeviceManager {
/// @brief: 创建一个新的设备管理器
/// @parameter: None
/// @return: DeviceManager实体
#[inline]
fn new() -> DeviceManager {
DeviceManager {
devices: BTreeMap::new(),
sys_info: Some(SYS_DEVICES_INODE()),
/// 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<dyn Device>) -> Arc<dyn KObject> {
// 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<dyn Device>) {
todo!("device_links_force_bind")
}
}
/// @brief: 设备注册
/// @parameter: name: 设备名
/// @return: 操作成功,返回(),操作失败,返回错误码
pub fn device_register<T: Device>(device: Arc<T>) -> 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<T: Device>(device: Arc<T>) -> Result<(), SystemError> {
return device_manager().add_device(device);
}
/// @brief: 设备卸载
/// @parameter: name: 设备名
/// @return: 操作成功,返回(),操作失败,返回错误码
pub fn device_unregister<T: Device>(device: Arc<T>) -> 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(());
pub fn device_unregister<T: Device>(_device: Arc<T>) {
// 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;
}
Err(_) => Err(DeviceError::RegisterError),
fn name(&self) -> &str {
"dev"
}
fn show(&self, kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
let dev = kobj.cast::<dyn Device>().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<T>: Debug {
fn match_device(&self, device: &Arc<dyn Device>, data: T) -> bool;
}
/// 用于根据名称匹配设备的匹配器
#[derive(Debug)]
pub struct DeviceMatchName;
impl DeviceMatcher<&str> for DeviceMatchName {
#[inline]
fn match_device(&self, device: &Arc<dyn Device>, data: &str) -> bool {
return device.name() == data;
}
}

View File

@ -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<Arc<KSet>> = None;
#[inline(always)]
#[allow(dead_code)]
pub fn sys_firmware_kset() -> Arc<KSet> {
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(());
}

View File

@ -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<Arc<KSet>> = None;
#[inline(always)]
#[allow(dead_code)]
pub fn sys_hypervisor_kset() -> Arc<KSet> {
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(());
}

View File

@ -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(());
}

View File

@ -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<Arc<KernFSInode>>);
/// 获取当前kobject对应的sysfs inode(类型为KernFSInode)
fn inode(&self) -> Option<Arc<KernFSInode>>;
fn parent(&self) -> Option<Weak<dyn KObject>>;
/// 设置当前kobject的parent kobject不一定与kset相同
fn set_parent(&self, parent: Option<Weak<dyn KObject>>);
/// 当前kobject属于哪个kset
fn kset(&self) -> Option<Arc<KSet>>;
/// 设置当前kobject所属的kset
fn set_kset(&self, kset: Option<Arc<KSet>>);
fn kobj_type(&self) -> Option<&'static dyn KObjType>;
fn name(&self) -> String;
fn set_name(&self, name: String);
fn kobj_state(&self) -> RwLockReadGuard<KObjectState>;
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>;
fn set_kobj_state(&self, state: KObjectState);
}
impl dyn KObject {
/// 更新kobject的状态
pub fn update_kobj_state(&self, insert: Option<KObjectState>, remove: Option<KObjectState>) {
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<Self>) -> Arc<dyn Any> {
self
}
}
pub trait KObjType: Debug {
fn release(&self, _kobj: Arc<dyn KObject>) {}
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<KObjectState>);
impl LockedKObjectState {
pub const fn new(state: KObjectState) -> LockedKObjectState {
LockedKObjectState(RwLock::new(state))
}
}
impl Deref for LockedKObjectState {
type Target = RwLock<KObjectState>;
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<usize, SystemError>;
fn store(&self, kobj: &dyn KObject, buf: &[u8]) -> Result<usize, SystemError>;
}
#[derive(Debug)]
pub struct KObjectSysFSOps;
impl SysFSOps for KObjectSysFSOps {
fn support(&self, attr: &dyn Attribute) -> SysFSOpsSupport {
return attr.support();
}
fn show(
&self,
kobj: Arc<dyn KObject>,
attr: &dyn Attribute,
buf: &mut [u8],
) -> Result<usize, SystemError> {
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<dyn KObject>,
attr: &dyn Attribute,
buf: &[u8],
) -> Result<usize, SystemError> {
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<dyn KObject>,
join_kset: Option<Arc<KSet>>,
) -> 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<dyn KObject>))));
}
}
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<dyn KObject>) -> 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(());
}
}

View File

@ -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<Vec<Weak<dyn KObject>>>,
/// 节点的一些信息
inner: RwLock<InnerKSet>,
/// kobject的状态
kobj_state: LockedKObjectState,
/// 与父节点有关的一些信息
parent_data: RwLock<KSetParentData>,
self_ref: Weak<KSet>,
}
impl Hash for KSet {
fn hash<H: ~const core::hash::Hasher>(&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<Self> {
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<Arc<dyn KObject>>,
join_kset: Option<Arc<KSet>>,
) -> Result<Arc<Self>, 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<Arc<KSet>>) -> 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<dyn KObject>) {
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<dyn KObject>) {
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<dyn KObject> {
return self.self_ref.upgrade().unwrap();
}
}
impl KObject for KSet {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn inode(&self) -> Option<Arc<KernFSInode>> {
self.inner.read().kern_inode.clone()
}
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
self.inner.write().kern_inode = inode;
}
fn parent(&self) -> Option<Weak<dyn KObject>> {
self.parent_data.read().parent.clone()
}
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
self.parent_data.write().parent = parent;
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
self.kobj_state.read()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
self.kobj_state.write()
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
Some(&KSetKObjType)
}
fn kset(&self) -> Option<Arc<KSet>> {
self.parent_data.read().kset.clone()
}
fn set_kset(&self, kset: Option<Arc<KSet>>) {
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<Weak<dyn KObject>>,
kset: Option<Arc<KSet>>,
}
impl KSetParentData {
fn new(parent: Option<Weak<dyn KObject>>, kset: Option<Arc<KSet>>) -> Self {
Self { parent, kset }
}
}
#[derive(Debug)]
struct InnerKSet {
kern_inode: Option<Arc<KernFSInode>>,
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
}
}

View File

@ -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};

View File

@ -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;

View File

@ -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<Arc<PlatformBusDevice>> = None;
static mut PLATFORM_BUS: Option<Arc<PlatformBus>> = None;
#[allow(dead_code)]
#[inline(always)]
pub fn platform_bus_device() -> Arc<PlatformBusDevice> {
unsafe { PLATFORM_BUS_DEVICE.clone().unwrap() }
}
#[allow(dead_code)]
#[inline(always)]
pub fn platform_bus() -> Arc<PlatformBus> {
unsafe { PLATFORM_BUS.clone().unwrap() }
}
/// @brief: platform总线匹配表
/// 总线上的设备和驱动都存在一份匹配表
@ -55,317 +65,34 @@ impl CompatibleTable {
}
}
#[derive(Debug)]
pub struct LockedPlatformBusDriver(SpinLock<PlatformBusDriver>);
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<Arc<dyn PlatformDevice>> {
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<Arc<dyn PlatformDriver>> {
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<dyn PlatformDriver>) -> 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<dyn PlatformDriver>,
) -> 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<dyn PlatformDevice>,
) -> 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<dyn PlatformDevice>) {
let id_table = device.id_table();
self.0.lock().devices.remove(&id_table);
}
}
/// @brief: platform总线驱动
#[derive(Debug)]
pub struct PlatformBusDriver {
drivers: BTreeMap<IdTable, Arc<dyn PlatformDriver>>, // 总线上所有驱动
devices: BTreeMap<IdTable, Arc<dyn PlatformDevice>>, // 总线上所有设备
sys_info: Option<Arc<dyn IndexNode>>,
}
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<Arc<dyn IndexNode>> {
return self.0.lock().sys_info.clone();
}
#[inline]
#[allow(dead_code)]
fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
self.0.lock().sys_info = sys_info;
}
fn probe(&self, _data: &DevicePrivateData) -> Result<(), DriverError> {
todo!()
}
fn load(
&self,
_data: DevicePrivateData,
_resource: Option<DeviceResource>,
) -> Result<Arc<dyn Device>, 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<Platform>);
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<Arc<LockedPlatformBusDriver>>) {
// self.0.lock().driver = driver;
// }
}
/// @brief: platform总线
#[derive(Debug, Clone)]
pub struct Platform {
_data: DevicePrivateData,
state: BusState, // 总线状态
sys_info: Option<Arc<dyn IndexNode>>, // 总线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 traitplatform总线也是一种设备属于总线设备类型
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<Arc<dyn IndexNode>>) {
self.0.lock().sys_info = sys_info;
}
#[inline]
#[allow(dead_code)]
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
return self.0.lock().sys_info.clone();
}
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
}
/// @brief: 为Platform实现Bus traitplatform总线是一种总线设备
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<LockedPlatformBusDriver> = Arc::new(LockedPlatformBusDriver::new());
let platform_device: Arc<LockedPlatform> =
Arc::new(LockedPlatform::new(DevicePrivateData::new(
let platform_device: Arc<PlatformBusDevice> = 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<dyn KObject>))),
);
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<dyn Bus>);
if r.is_err() {
device_unregister(platform_device.clone());
unsafe { PLATFORM_BUS_DEVICE = None };
return r;
}
unsafe { PLATFORM_BUS = Some(paltform_bus) };
return r;
}

View File

@ -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<InnerPlatformBusDevice>,
kobj_state: LockedKObjectState,
}
impl PlatformBusDevice {
/// @brief: 创建一个加锁的platform总线实例
/// @parameter: None
/// @return: platform总线实例
pub fn new(
data: DevicePrivateData,
parent: Option<Weak<dyn KObject>>,
) -> Arc<PlatformBusDevice> {
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<Arc<LockedPlatformBusDriver>>) {
// self.0.lock().driver = driver;
// }
}
/// @brief: platform总线
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct InnerPlatformBusDevice {
name: String,
data: DevicePrivateData,
state: BusState, // 总线状态
parent: Option<Weak<dyn KObject>>, // 总线的父对象
kernfs_inode: Option<Arc<KernFSInode>>,
/// 当前设备挂载到的总线
bus: Option<Arc<dyn Bus>>,
/// 当前设备已经匹配的驱动
driver: Option<Arc<dyn Driver>>,
}
/// @brief: platform方法集
impl InnerPlatformBusDevice {
/// @brief: 创建一个platform总线实例
/// @parameter: None
/// @return: platform总线实例
pub fn new(data: DevicePrivateData, parent: Option<Weak<dyn KObject>>) -> 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<Weak<dyn KObject>> {
self.inner.lock().parent.clone()
}
fn inode(&self) -> Option<Arc<KernFSInode>> {
self.inner.lock().kernfs_inode.clone()
}
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
self.inner.lock().kernfs_inode = inode;
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
None
}
fn kset(&self) -> Option<Arc<KSet>> {
None
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
self.kobj_state.read()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
self.kobj_state.write()
}
fn set_kobj_state(&self, state: KObjectState) {
*self.kobj_state.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<Arc<KSet>>) {
todo!()
}
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
self.inner.lock().parent = parent;
}
}
/// @brief: 为Platform实现Device traitplatform总线也是一种设备属于总线设备类型
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<Arc<dyn Bus>> {
self.inner.lock().bus.clone()
}
fn driver(&self) -> Option<Arc<dyn Driver>> {
self.inner.lock().driver.clone()
}
#[inline]
fn is_dead(&self) -> bool {
false
}
fn set_driver(&self, driver: Option<Arc<dyn Driver>>) {
self.inner.lock().driver = driver;
}
}

View File

@ -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<Self> {
let w: Weak<Self> = 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<dyn Bus>)));
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<dyn KObject>, attr: &dyn Attribute) -> Option<ModeType> {
return Some(attr.mode());
}
}

View File

@ -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<KSet>,
ksets: RwLock<SubSysKSets>,
/// 指向拥有当前结构体的`dyn bus`对象的弱引用
bus: SpinLock<Weak<dyn Bus>>,
drivers_autoprobe: AtomicBool,
/// 当前总线上的所有设备
devices: RwLock<Vec<Weak<dyn Device>>>,
/// 当前总线上的所有驱动
drivers: RwLock<Vec<Weak<dyn Driver>>>,
interfaces: &'static [&'static dyn SubSysInterface],
bus_notifier: AtomicNotifierChain<BusNotifyEvent, Arc<dyn Device>>,
}
#[derive(Debug)]
struct SubSysKSets {
/// 子系统的`devices`目录
devices_kset: Option<Arc<KSet>>,
/// 子系统的`drivers`目录
drivers_kset: Option<Arc<KSet>>,
}
impl SubSysKSets {
pub fn new() -> Self {
return Self {
devices_kset: None,
drivers_kset: None,
};
}
}
impl SubSysPrivate {
pub fn new(
name: String,
bus: Weak<dyn Bus>,
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<KSet> {
return self.subsys.clone();
}
#[inline]
#[allow(dead_code)]
pub fn bus(&self) -> Weak<dyn Bus> {
return self.bus.lock().clone();
}
pub fn set_bus(&self, bus: Weak<dyn Bus>) {
*self.bus.lock() = bus;
}
pub fn devices(&self) -> &RwLock<Vec<Weak<dyn Device>>> {
return &self.devices;
}
pub fn drivers(&self) -> &RwLock<Vec<Weak<dyn Driver>>> {
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<Arc<KSet>> {
return self.ksets.read().devices_kset.clone();
}
#[allow(dead_code)]
#[inline]
pub fn set_devices_kset(&self, devices_kset: Arc<KSet>) {
self.ksets.write().devices_kset = Some(devices_kset);
}
#[allow(dead_code)]
#[inline]
pub fn drivers_kset(&self) -> Option<Arc<KSet>> {
return self.ksets.read().drivers_kset.clone();
}
pub fn set_drivers_kset(&self, drivers_kset: Arc<KSet>) {
self.ksets.write().drivers_kset = Some(drivers_kset);
}
pub fn bus_notifier(&self) -> &AtomicNotifierChain<BusNotifyEvent, Arc<dyn Device>> {
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<Weak<dyn Bus>>;
fn set_bus(&self, bus: Option<Weak<dyn Bus>>);
fn add_device(&self, _device: &Arc<dyn Device>) -> Result<(), SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn remove_device(&self, device: &Arc<dyn Device>);
}

View File

@ -0,0 +1,8 @@
use alloc::sync::Arc;
use super::device::Device;
pub fn software_node_notify(_dev: &Arc<dyn Device>) {
// todo: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/swnode.c?fi=software_node_notify#1120
return;
}

View File

@ -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<Arc<KernFSInode>> {
todo!()
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
todo!()
}
fn kset(&self) -> Option<Arc<KSet>> {
todo!()
}
fn parent(&self) -> Option<Weak<dyn KObject>> {
todo!()
}
fn set_inode(&self, _inode: Option<Arc<KernFSInode>>) {
todo!()
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
todo!()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
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<Arc<KSet>>) {
todo!()
}
fn set_parent(&self, _parent: Option<Weak<dyn KObject>>) {
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<Arc<dyn crate::filesystem::vfs::IndexNode>>) {
todo!()
fn bus(&self) -> Option<Arc<dyn Bus>> {
todo!("LockedAhciDisk::bus()")
}
fn sys_info(&self) -> Option<Arc<dyn crate::filesystem::vfs::IndexNode>> {
todo!()
fn driver(&self) -> Option<Arc<dyn Driver>> {
todo!("LockedAhciDisk::driver()")
}
fn is_dead(&self) -> bool {
false
}
fn set_driver(&self, _driver: Option<Arc<dyn Driver>>) {
todo!("LockedAhciDisk::set_driver()")
}
}

View File

@ -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<Arc<dyn IndexNode>>);
/// @brief: 获取驱动的sys information
/// @parameter id_table: 驱动标识符,用于唯一标识该驱动
/// @return: 驱动实例
fn sys_info(&self) -> Option<Arc<dyn IndexNode>>;
}

View File

@ -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<T: Transport + 'static>(transport: T) {
let mac = smoltcp::wire::EthernetAddress::from_bytes(&driver_net.mac_address());
let driver: VirtioNICDriver<T> = 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<T: Transport> Driver for VirtioInterface<T> {
fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
self
}
impl<T: Transport + 'static> Driver for VirtioInterface<T> {
fn probe(&self, _data: &DevicePrivateData) -> Result<(), DriverError> {
todo!()
}
@ -260,17 +260,9 @@ impl<T: Transport> Driver for VirtioInterface<T> {
fn id_table(&self) -> IdTable {
todo!()
}
fn set_sys_info(&self, _sys_info: Option<Arc<dyn crate::filesystem::vfs::IndexNode>>) {
todo!()
}
fn sys_info(&self) -> Option<Arc<dyn crate::filesystem::vfs::IndexNode>> {
todo!()
}
}
impl<T: Transport> NetDriver for VirtioInterface<T> {
impl<T: Transport + 'static> NetDriver for VirtioInterface<T> {
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<T: Transport> NetDriver for VirtioInterface<T> {
// }
}
impl<T: Transport + 'static> KObject for VirtioInterface<T> {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
todo!()
}
fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
todo!()
}
fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
todo!()
}
fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
todo!()
}
fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
todo!()
}
fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
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<crate::driver::base::kobject::KObjectState> {
todo!()
}
fn kobj_state_mut(
&self,
) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
todo!()
}
fn set_kobj_state(&self, _state: crate::driver::base::kobject::KObjectState) {
todo!()
}
}
// 向编译器保证VirtioNICDriver在线程之间是安全的.
// 由于smoltcp只会在token内真正操作网卡设备并且在VirtioNetToken的consume
// 方法内会对VirtioNet进行加【写锁】因此能够保证对设备操作的的互斥访问

View File

@ -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,7 +125,6 @@ struct UartRegister {
#[derive(Debug)]
pub struct Uart {
private_data: DevicePrivateData, // 设备状态
sys_info: Option<Arc<dyn IndexNode>>,
fs: Weak<DevFS>, // 文件系统
port: UartPort,
baud_rate: u32,
@ -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<Arc<KernFSInode>> {
todo!()
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
todo!()
}
fn kset(&self) -> Option<Arc<KSet>> {
todo!()
}
fn parent(&self) -> Option<Weak<dyn KObject>> {
todo!()
}
fn set_inode(&self, _inode: Option<Arc<KernFSInode>>) {
todo!()
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
todo!()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
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<Arc<KSet>>) {
todo!()
}
fn set_parent(&self, _parent: Option<Weak<dyn KObject>>) {
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<Arc<dyn IndexNode>>) {
self.0.lock().sys_info = sys_info;
}
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
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<Arc<dyn Bus>> {
todo!("LockedUart::bus()")
}
fn driver(&self) -> Option<Arc<dyn Driver>> {
todo!("LockedUart::driver()")
}
fn is_dead(&self) -> bool {
false
}
fn set_driver(&self, _driver: Option<Arc<dyn Driver>>) {
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<Arc<KernFSInode>> {
todo!()
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
todo!()
}
fn kset(&self) -> Option<Arc<KSet>> {
todo!()
}
fn parent(&self) -> Option<Weak<dyn KObject>> {
todo!()
}
fn set_inode(&self, _inode: Option<Arc<KernFSInode>>) {
todo!()
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
todo!()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
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<Arc<KSet>>) {
todo!()
}
fn set_parent(&self, _parent: Option<Weak<dyn KObject>>) {
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<Arc<dyn IndexNode>>) {
self.0.lock().sys_info = sys_info;
}
fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
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(());
}

View File

@ -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<Arc<crate::filesystem::kernfs::KernFSInode>>) {
todo!()
}
fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
todo!()
}
fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
todo!()
}
fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
todo!()
}
fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
todo!()
}
fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
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<crate::driver::base::kobject::KObjectState> {
todo!()
}
fn kobj_state_mut(
&self,
) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
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<DeviceResource>,
) -> Result<Arc<dyn Device>, 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<Arc<dyn crate::filesystem::vfs::IndexNode>>) {
todo!()
}
fn sys_info(&self) -> Option<Arc<dyn crate::filesystem::vfs::IndexNode>> {
todo!()
}
}

View File

@ -64,6 +64,22 @@ impl<'a> KernCallbackData<'a> {
pub fn private_data_mut(&mut self) -> &mut Option<KernInodePrivateData> {
return &mut self.private_data;
}
pub fn callback_read(&self, buf: &mut [u8], offset: usize) -> Result<usize, SystemError> {
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<usize, SystemError> {
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<usize, SystemError> {
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<usize, SystemError> {
match self {
KernInodePrivateData::SysFS(private_data) => {
return private_data.callback_write(buf, offset);
}
}
}
}

View File

@ -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<HashMap<String, Arc<KernFSInode>>>,
/// 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<KernFSInode> = self
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)
.cloned()
.ok_or(SystemError::ENOENT)?;
return Ok(x);
.ok_or(SystemError::ENOENT)?
.clone());
}
}
}
fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
@ -248,11 +271,21 @@ impl IndexNode for KernFSInode {
}
fn list(&self) -> Result<Vec<String>, 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<String> = 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<PollStatus, SystemError> {
@ -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<KernInodePrivateData>,
callback: Option<&'static dyn KernFSCallback>,
) -> Result<Arc<KernFSInode>, 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<KernFSInode> = 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<KernFSInode>,
metadata: Metadata,
pub fn new(
parent: Option<Arc<KernFSInode>>,
name: String,
mut metadata: Metadata,
inode_type: KernInodeType,
private_data: Option<KernInodePrivateData>,
callback: Option<&'static dyn KernFSCallback>,
) -> Arc<KernFSInode> {
metadata.file_type = inode_type.into();
let parent: Weak<KernFSInode> = 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::<KernFS>()
.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<Arc<KernFSInode>> {
return self.inner.lock().parent.upgrade();
}
pub fn private_data_mut(&self) -> SpinLockGuard<Option<KernInodePrivateData>> {
return self.private_data.lock();
}
/// remove a kernfs_node recursively
pub fn remove_recursive(&self) {
let mut children = self.children.lock().drain().collect::<Vec<_>>();
while let Some((_, child)) = children.pop() {
children.append(&mut child.children.lock().drain().collect::<Vec<_>>());
}
}
/// 删除当前的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,
}

View File

@ -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<Arc<dyn IndexNode>, SystemError> {
let binding: Arc<dyn IndexNode> = SYS_BUS_INODE();
kdebug!("Before bus_register: ls /sys/bus/: {:?}", binding.list());
binding
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.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<dyn IndexNode> = SYS_BUS_INODE();
binding
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.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<dyn IndexNode>,
) -> Result<(Arc<dyn IndexNode>, Arc<dyn IndexNode>), SystemError> {
match inode.as_any_ref().downcast_ref::<LockedSysFSInode>() {
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<Arc<dyn IndexNode>, SystemError> {
match SYS_BUS_INODE().find(bus_name) {
Ok(platform) => match platform.find("drivers") {
Ok(device) => device
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.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<Arc<dyn IndexNode>, SystemError> {
match SYS_BUS_INODE().find(bus_name) {
Ok(platform) => match platform.find("devices") {
Ok(device) => device
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.ok_or(SystemError::E2BIG)
.unwrap()
.add_dir(name),
Err(_) => return Err(SystemError::EXDEV),
},
Err(_) => return Err(SystemError::EXDEV),
}
}

View File

@ -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<Arc<dyn IndexNode>, SystemError> {
let binding: Arc<dyn IndexNode> = SYS_CLASS_INODE();
binding
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.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<dyn IndexNode> = SYS_CLASS_INODE();
binding
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.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<dyn IndexNode>,
device_name: &str,
) -> Result<Arc<dyn IndexNode>, SystemError> {
class
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.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<dyn IndexNode>,
device_name: &str,
) -> Result<(), SystemError> {
class
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.ok_or(SystemError::E2BIG)
.unwrap()
.remove(device_name)
}

View File

@ -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<Arc<dyn IndexNode>, SystemError> {
let binding: Arc<dyn IndexNode> = SYS_DEVICES_INODE();
binding
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.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<dyn IndexNode> = SYS_DEVICES_INODE();
binding
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.ok_or(SystemError::E2BIG)
.unwrap()
.remove(device_name)
}

View File

@ -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<dyn KObject>,
attribute_group: Option<&'static dyn AttributeGroup>,
/// 该目录对应的kobject
/// use weak reference to avoid cyclic reference
kobj: Weak<dyn KObject>,
// attribute_group: Option<&'static dyn AttributeGroup>,
}
impl SysKernDirPriv {
pub fn new(
kobj: Arc<dyn KObject>,
attribute_group: Option<&'static dyn AttributeGroup>,
) -> Self {
pub fn new(kobj: Arc<dyn KObject>) -> 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<dyn KObject> {
self.kobj.clone()
pub fn kobj(&self) -> Option<Arc<dyn KObject>> {
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<dyn KObject>) -> Result<Arc<KernFSInode>, 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<KernFSInode> = 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<KernFSInode>) -> 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<dyn KObject>) {
let kobj_inode = kobj.inode();
kobj.set_inode(None);
if let Some(inode) = kobj_inode {
let parent = inode.parent().unwrap();
parent.remove_recursive()
}
}
}

View File

@ -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<dyn KObject>,
// todo: 增加bin attribute,它和attribute二选一只能有一个为Some
}
impl SysKernFilePriv {
pub fn new(attribute: Option<&'static dyn Attribute>) -> Self {
pub fn new(kobj: &Arc<dyn KObject>, 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<usize, SystemError> {
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<usize, SystemError> {
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<dyn KObject>,
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<KernFSInode>,
attr: &'static dyn Attribute,
mode: ModeType,
) -> Result<(), SystemError> {
let x = parent.private_data_mut();
let kobj: Arc<dyn KObject>;
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<dyn KObject>, 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<usize, SystemError> {
return data.callback_read(buf, offset);
}
fn write(
&self,
data: KernCallbackData,
buf: &[u8],
offset: usize,
) -> Result<usize, SystemError> {
return data.callback_write(buf, offset);
}
#[inline]
fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
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<usize, SystemError> {
return data.callback_read(buf, offset);
}
fn write(
&self,
_data: KernCallbackData,
_buf: &[u8],
_offset: usize,
) -> Result<usize, SystemError> {
return Err(SystemError::EPERM);
}
#[inline]
fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
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<usize, SystemError> {
return Err(SystemError::EPERM);
}
fn write(
&self,
data: KernCallbackData,
buf: &[u8],
offset: usize,
) -> Result<usize, SystemError> {
return data.callback_write(buf, offset);
}
#[inline]
fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
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<usize, SystemError> {
return Err(SystemError::EPERM);
}
fn write(
&self,
_data: KernCallbackData,
_buf: &[u8],
_offset: usize,
) -> Result<usize, SystemError> {
return Err(SystemError::EPERM);
}
#[inline]
fn poll(&self, _data: KernCallbackData) -> Result<PollStatus, SystemError> {
return Ok(PollStatus::empty());
}
}
pub fn sysfs_emit_str(buf: &mut [u8], s: &str) -> Result<usize, SystemError> {
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);
}

View File

@ -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<Arc<dyn IndexNode>, SystemError> {
let binding: Arc<dyn IndexNode> = SYS_FS_INODE();
binding
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.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<dyn IndexNode> = SYS_FS_INODE();
binding
.as_any_ref()
.downcast_ref::<LockedSysFSInode>()
.ok_or(SystemError::E2BIG)
.unwrap()
.remove(fs_name)
}

View File

@ -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<dyn KObject>,
groups: &[&'static dyn AttributeGroup],
) -> Result<(), SystemError> {
return self.do_create_groups(kobj, groups, false);
}
fn do_create_groups(
&self,
kobj: &Arc<dyn KObject>,
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<dyn KObject>,
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<KernFSInode>;
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<dyn KObject>,
group: &'static dyn AttributeGroup,
) -> Result<(), SystemError> {
let inode = kobj.inode().unwrap();
let parent_inode: Arc<KernFSInode>;
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<KernFSInode>,
kobj: &Arc<dyn KObject>,
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<KernFSInode>, _group: &'static dyn AttributeGroup) {
todo!("group_remove_files")
}
}

View File

@ -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<SysFS> = None;
static mut __SYS_DEVICES_INODE: Option<Arc<dyn IndexNode>> = None;
static mut __SYS_BUS_INODE: Option<Arc<dyn IndexNode>> = None;
static mut __SYS_CLASS_INODE: Option<Arc<dyn IndexNode>> = None;
static mut __SYS_FS_INODE: Option<Arc<dyn IndexNode>> = None;
/// @brief 获取全局的sys/devices节点
#[inline(always)]
#[allow(non_snake_case)]
pub fn SYS_DEVICES_INODE() -> Arc<dyn IndexNode> {
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<dyn IndexNode> {
unsafe {
return __SYS_BUS_INODE.as_ref().unwrap().clone();
}
}
/// @brief 获取全局的sys/class节点
#[inline(always)]
#[allow(non_snake_case)]
pub fn SYS_CLASS_INODE() -> Arc<dyn IndexNode> {
unsafe {
return __SYS_CLASS_INODE.as_ref().unwrap().clone();
}
}
/// @brief 获取全局的sys/fs节点
#[inline(always)]
#[allow(non_snake_case)]
pub fn SYS_FS_INODE() -> Arc<dyn IndexNode> {
unsafe {
return __SYS_FS_INODE.as_ref().unwrap().clone();
}
}
/// @brief dev文件系统
#[derive(Debug)]
pub struct SysFS {
// 文件系统根节点
root_inode: Arc<LockedSysFSInode>,
}
impl FileSystem for SysFS {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> {
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<Self> {
// 初始化root inode
let root: Arc<LockedSysFSInode> = Arc::new(LockedSysFSInode(SpinLock::new(
// /sys 的权限设置为 读+执行root 可以读写
// root 的 parent 是空指针
SysFSInode::new(FileType::Dir, ModeType::from_bits_truncate(0o755), 0),
)));
let sysfs: Arc<SysFS> = Arc::new(SysFS { root_inode: root });
// 对root inode加锁并继续完成初始化工作
let mut root_guard: SpinLockGuard<SysFSInode> = 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<LockedSysFSInode> = &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<SysFSInode>);
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<usize, SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn write_at(
&self,
_offset: usize,
_len: usize,
_buf: &[u8],
_data: &mut super::vfs::FilePrivateData,
) -> Result<usize, SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn poll(&self) -> Result<super::vfs::PollStatus, SystemError> {
// 加锁
let inode: SpinLockGuard<SysFSInode> = 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<Metadata, SystemError> {
return Ok(self.0.lock().metadata.clone());
}
fn fs(&self) -> Arc<dyn FileSystem> {
return self.0.lock().fs.upgrade().unwrap();
}
fn get_entry_name(&self, ino: super::vfs::InodeId) -> Result<String, SystemError> {
let inode: SpinLockGuard<SysFSInode> = 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<String> = 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<Arc<dyn IndexNode>, 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<usize, SystemError> {
Err(SystemError::EOPNOTSUPP_OR_ENOTSUP)
}
fn list(&self) -> Result<Vec<String>, SystemError> {
let info = self.metadata()?;
if info.file_type != FileType::Dir {
return Err(SystemError::ENOTDIR);
}
let mut keys: Vec<String> = 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<SysFSInode>,
name: &str,
file_type: FileType,
mode: ModeType,
data: usize,
) -> Result<Arc<dyn IndexNode>, 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<LockedSysFSInode> = 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<Arc<dyn IndexNode>, SystemError> {
let guard: SpinLockGuard<SysFSInode> = 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<dyn IndexNode>) -> 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<dyn IndexNode> {
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<LockedSysFSInode>,
/// 指向自身的弱引用
self_ref: Weak<LockedSysFSInode>,
/// 子Inode的B树
children: BTreeMap<String, Arc<dyn IndexNode>>,
/// 指向inode所在的文件系统对象的指针
fs: Weak<SysFS>,
/// 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<LockedSysFSInode>,
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> = SysFS::new();
// let sysfs: Arc<OldSysFS> = 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<usize, SystemError> {
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<usize, SystemError> {
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<dyn KObject>, attr: &dyn Attribute) -> bool;
/// 属性在当前属性组内的权限(该方法可选)
///
/// 如果返回None则使用Attribute的mode()方法返回的权限
///
/// 如果返回Some则使用返回的权限。
/// 如果要标识属性不可见则返回Some(ModeType::empty())
fn is_visible(&self, kobj: Arc<dyn KObject>, attr: &dyn Attribute) -> Option<ModeType>;
}
/// sysfs文件的属性
pub trait Attribute: Debug + Send + Sync {
fn name(&self) -> &str;
fn mode(&self) -> ModeType;
fn support(&self) -> SysFSOpsSupport;
fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
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<dyn KObject>,
attr: &dyn Attribute,
buf: &mut [u8],
) -> Result<usize, SystemError>;
fn store(
&self,
kobj: Arc<dyn KObject>,
attr: &dyn Attribute,
buf: &[u8],
) -> Result<usize, SystemError>;
}
bitflags! {
pub struct SysFSOpsSupport: u8{
const SHOW = 1 << 0;
const STORE = 1 << 1;
}
}
#[derive(Debug)]
pub struct SysFS {
root_inode: Arc<KernFSInode>,
kernfs: Arc<KernFS>,
}
impl SysFS {
pub fn new() -> Self {
let kernfs: Arc<KernFS> = KernFS::new();
let root_inode: Arc<KernFSInode> = kernfs.root_inode().downcast_arc().unwrap();
let sysfs = SysFS { root_inode, kernfs };
return sysfs;
}
pub fn root_inode(&self) -> &Arc<KernFSInode> {
return &self.root_inode;
}
pub fn fs(&self) -> &Arc<KernFS> {
return &self.kernfs;
}
/// 警告重复的sysfs entry
pub(self) fn warn_duplicate(&self, parent: &Arc<KernFSInode>, name: &str) {
let path = self.kernfs_path(parent);
kwarn!("duplicate sysfs entry: {path}/{name}");
}
}

View File

@ -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<dyn KObject>,
_target: &Arc<dyn KObject>,
_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<dyn KObject>, _name: String) -> Result<(), SystemError> {
todo!("sysfs remove link")
}
}

View File

@ -280,7 +280,9 @@ impl File {
let sub_inode: Arc<dyn IndexNode> = 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);
}
};

View File

@ -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<Self>) -> Arc<dyn Any> {
self
}
}
#[derive(Debug)]
pub struct FsInfo {
/// 文件系统所在的块设备的id

View File

@ -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;
}
}

View File

@ -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)]

View File

@ -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<T> {
pub trait NotifierBlock<V: Clone + Copy, T>: 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<T>(Vec<Arc<dyn NotifierBlock<T>>>);
#[derive(Debug)]
struct NotifierChain<V: Clone + Copy, T>(Vec<Arc<dyn NotifierBlock<V, T>>>);
impl<T> NotifierChain<T> {
impl<V: Clone + Copy, T> NotifierChain<V, T> {
pub fn new() -> Self {
Self(vec![])
}
@ -27,7 +30,7 @@ impl<T> NotifierChain<T> {
/// @param unique_priority 检查通知链中优先级的唯一性
pub fn register(
&mut self,
block: Arc<dyn NotifierBlock<T>>,
block: Arc<dyn NotifierBlock<V, T>>,
unique_priority: bool,
) -> Result<(), SystemError> {
let mut index: usize = 0;
@ -61,7 +64,7 @@ impl<T> NotifierChain<T> {
}
/// @brief 在通知链中取消注册节点
pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
let remove = self
.0
.drain_filter(|b| Arc::as_ptr(&block) == Arc::as_ptr(b));
@ -71,13 +74,20 @@ impl<T> NotifierChain<T> {
}
}
/// @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<usize>,
) -> (i32, usize) {
@ -96,34 +106,35 @@ impl<T> NotifierChain<T> {
}
/// @brief 原子的通知链,使用 SpinLock 进行同步
pub struct AtomicNotifierChain<T>(SpinLock<NotifierChain<T>>);
#[derive(Debug)]
pub struct AtomicNotifierChain<V: Clone + Copy, T>(SpinLock<NotifierChain<V, T>>);
impl<T> AtomicNotifierChain<T> {
impl<V: Clone + Copy, T> AtomicNotifierChain<V, T> {
pub fn new() -> Self {
Self(SpinLock::new(NotifierChain::<T>::new()))
Self(SpinLock::new(NotifierChain::<V, T>::new()))
}
pub fn register(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> 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<dyn NotifierBlock<T>>,
block: Arc<dyn NotifierBlock<V, T>>,
) -> Result<(), SystemError> {
let mut notifier_chain_guard = self.0.lock();
return notifier_chain_guard.register(block, true);
}
pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> 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<usize>,
) -> (i32, usize) {
@ -134,34 +145,35 @@ impl<T> AtomicNotifierChain<T> {
/// @brief 可阻塞的通知链,使用 RwLock 进行同步
// TODO: 使用 semaphore 封装
pub struct BlockingNotifierChain<T>(RwLock<NotifierChain<T>>);
#[derive(Debug)]
pub struct BlockingNotifierChain<V: Clone + Copy, T>(RwLock<NotifierChain<V, T>>);
impl<T> BlockingNotifierChain<T> {
impl<V: Clone + Copy, T> BlockingNotifierChain<V, T> {
pub fn new() -> Self {
Self(RwLock::new(NotifierChain::<T>::new()))
Self(RwLock::new(NotifierChain::<V, T>::new()))
}
pub fn register(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> 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<dyn NotifierBlock<T>>,
block: Arc<dyn NotifierBlock<V, T>>,
) -> Result<(), SystemError> {
let mut notifier_chain_guard = self.0.write();
return notifier_chain_guard.register(block, true);
}
pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> 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<usize>,
) -> (i32, usize) {
@ -171,24 +183,24 @@ impl<T> BlockingNotifierChain<T> {
}
/// @brief 原始的通知链,由调用者自行考虑同步
pub struct RawNotifierChain<T>(NotifierChain<T>);
pub struct RawNotifierChain<V: Clone + Copy, T>(NotifierChain<V, T>);
impl<T> RawNotifierChain<T> {
impl<V: Clone + Copy, T> RawNotifierChain<V, T> {
pub fn new() -> Self {
Self(NotifierChain::<T>::new())
Self(NotifierChain::<V, T>::new())
}
pub fn register(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
pub fn register(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
return self.0.register(block, false);
}
pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<T>>) -> Result<(), SystemError> {
pub fn unregister(&mut self, block: Arc<dyn NotifierBlock<V, T>>) -> Result<(), SystemError> {
return self.0.unregister(block);
}
pub fn call_chain(
&self,
action: u64,
action: V,
data: Option<&T>,
nr_to_call: Option<usize>,
) -> (i32, usize) {

View File

@ -32,7 +32,7 @@
#include <driver/interrupt/apic/apic_timer.h>
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();

View File

@ -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;