Skip to content

Commit

Permalink
feat: 支持 sysfs下 block, char, Net, rtc, tty 等类型设备的 uevent 文件读操作 (#973)
Browse files Browse the repository at this point in the history
* 新增CommonAttrGroup,基本支持sysfs下各种类型设备的uevent属性文件的读测试

* 修改net设备的uevent内容,使之与Linux语义一致

* 删除无用注释
  • Loading branch information
val213 authored Oct 14, 2024
1 parent 4e4ce68 commit 38d161c
Show file tree
Hide file tree
Showing 17 changed files with 126 additions and 58 deletions.
2 changes: 1 addition & 1 deletion kernel/src/arch/x86_64/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
show &= false;
}
}

show = false;
if show {
debug!("[SYS] [Pid: {:?}] [Call: {:?}]", pid, to_print);
}
Expand Down
7 changes: 3 additions & 4 deletions kernel/src/driver/base/block/block_device.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
/// 引入Module
use crate::driver::{
use crate::{driver::{
base::{
device::{
device_number::{DeviceNumber, Major},
Device, DeviceError, IdTable, BLOCKDEVS,
device_number::{DeviceNumber, Major}, Device, DeviceError, 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,
},
},
block::cache::{cached_block_device::BlockCache, BlockCacheError, BLOCK_SIZE},
};
}, filesystem::sysfs::AttributeGroup};

use alloc::{string::String, sync::Arc, vec::Vec};
use core::{any::Any, fmt::Display, ops::Deref};
Expand Down
20 changes: 20 additions & 0 deletions kernel/src/driver/base/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use super::{
},
kset::KSet,
swnode::software_node_notify,
uevent::UeventAttr,
};

pub mod bus;
Expand Down Expand Up @@ -1025,6 +1026,25 @@ impl Eq for DeviceId {}

impl IrqHandlerData for DeviceId {}

/// sysfs下设备的通用属性组
#[derive(Debug)]
pub struct CommonAttrGroup;
impl AttributeGroup for CommonAttrGroup {
fn name(&self) -> Option<&str> {
None
}
fn attrs(&self) -> &[&'static dyn Attribute] {
&[&UeventAttr]
}
fn is_visible(
&self,
_kobj: alloc::sync::Arc<dyn KObject>,
attr: &'static dyn Attribute,
) -> Option<crate::filesystem::vfs::syscall::ModeType> {
Some(attr.mode())
}
}

lazy_static! {
/// class_dir列表,通过parent kobject的name和class_dir的name来索引class_dir实例
static ref CLASS_DIR_KSET_INSTANCE: RwLock<BTreeMap<String, Arc<ClassDir>>> = RwLock::new(BTreeMap::new());
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/driver/base/kobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{

use system_error::SystemError;

use super::{kset::KSet, uevent::kobject_uevent};
use super::{device::CommonAttrGroup, kset::KSet, uevent::kobject_uevent};

pub trait KObject: Any + Send + Sync + Debug + CastFromSync {
fn as_any_ref(&self) -> &dyn core::any::Any;
Expand Down
8 changes: 6 additions & 2 deletions kernel/src/driver/base/platform/platform_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ use crate::{
bus::{Bus, BusState},
device_manager,
driver::Driver,
Device, DeviceCommonData, DevicePrivateData, DeviceType, IdTable,
CommonAttrGroup, Device, DeviceCommonData, DevicePrivateData, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
kset::KSet,
},
filesystem::kernfs::KernFSInode,
filesystem::{kernfs::KernFSInode, sysfs::AttributeGroup},
libs::{
rwlock::{RwLockReadGuard, RwLockWriteGuard},
spinlock::{SpinLock, SpinLockGuard},
Expand Down Expand Up @@ -329,4 +329,8 @@ impl Device for PlatformBusDevice {
fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) {
self.inner().device_common.parent = dev_parent;
}

fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
Some(&[&CommonAttrGroup])
}
}
72 changes: 44 additions & 28 deletions kernel/src/driver/base/uevent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use alloc::string::{String, ToString};
use alloc::sync::Arc;
use alloc::vec::Vec;
use intertrait::cast::CastArc;
use log::warn;
use system_error::SystemError;

use super::block::block_device::{BlockDevice, BlockDeviceOps};
Expand Down Expand Up @@ -128,46 +129,60 @@ impl Attribute for UeventAttr {

/// 用户空间读取 uevent 文件,返回 uevent 信息
fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
let device: Arc<dyn KObject> = _kobj
.parent()
.and_then(|x| x.upgrade())
.ok_or(SystemError::ENODEV)?;
let device = kobj2device(device).ok_or(SystemError::EINVAL)?;
let device = _kobj.cast::<dyn Device>().map_err(|e: Arc<dyn KObject>| {
warn!("device:{:?} is not a device!", e);
SystemError::EINVAL
})?;
log::info!("show uevent");
let device_type = device.dev_type();
let mut uevent_content = String::new();
log::info!("device_type: {:?}", device_type);
match device_type {
DeviceType::Block => {
let block_device = device
.cast::<dyn BlockDevice>()
.ok()
.ok_or(SystemError::EINVAL)?;
let major = block_device.id_table().device_number().major().data();
let minor = block_device.id_table().device_number().minor();
let device_name = block_device.id_table().name();
let major = device.id_table().device_number().major().data();
let minor = device.id_table().device_number().minor();
let device_name = device.id_table().name();
writeln!(&mut uevent_content, "MAJOR={:?}", major).unwrap();
writeln!(&mut uevent_content, "MINOR={:?}", minor).unwrap();
writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
writeln!(&mut uevent_content, "DEVTYPE=disk").unwrap();
}
DeviceType::Char => {
let char_device = device
.cast::<dyn CharDevice>()
.ok()
.ok_or(SystemError::EINVAL)?;
let major = char_device.id_table().device_number().major().data();
let minor = char_device.id_table().device_number().minor();
let device_name = char_device.id_table().name();
let major = device.id_table().device_number().major().data();
let minor = device.id_table().device_number().minor();
let device_name = device.id_table().name();
writeln!(&mut uevent_content, "MAJOR={}", major).unwrap();
writeln!(&mut uevent_content, "MINOR={}", minor).unwrap();
writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
writeln!(&mut uevent_content, "DEVTYPE=char").unwrap();
}
DeviceType::Net => {
let net_device = device.cast::<dyn Iface>().ok().ok_or(SystemError::EINVAL)?;
// let ifindex = net_device.ifindex().expect("Find ifindex error.\n");
let device_name = net_device.iface_name();
let net_device = device.clone().cast::<dyn Iface>().map_err(|e: Arc<dyn Device>| {
warn!("device:{:?} is not a net device!", e);
SystemError::EINVAL
})?;
let iface_id = net_device.nic_id();
let device_name = device.name();
writeln!(&mut uevent_content, "INTERFACE={}", device_name).unwrap();
// writeln!(&mut uevent_content, "IFINDEX={}", ifindex).unwrap();
writeln!(&mut uevent_content, "IFINDEX={}", iface_id).unwrap();
}
DeviceType::Bus => {
// 处理总线设备类型
let device_name = device.name();
writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
writeln!(&mut uevent_content, "DEVTYPE=bus").unwrap();
}
DeviceType::Rtc => {
// 处理RTC设备类型
let device_name = device.name();
writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
writeln!(&mut uevent_content, "DEVTYPE=rtc").unwrap();
}
DeviceType::Pci => {
// 处理PCI设备类型
let device_name = device.name();
writeln!(&mut uevent_content, "DEVNAME={}", device_name).unwrap();
writeln!(&mut uevent_content, "DEVTYPE=pci").unwrap();
}
_ => {
// 处理其他设备类型
Expand All @@ -180,17 +195,15 @@ impl Attribute for UeventAttr {
}
/// 捕获来自用户空间对 uevent 文件的写操作,触发uevent事件
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
log::info!("store uevent");
return kobject_synth_uevent(_buf, _kobj);
}
}

/// 将 kobject 转换为 device
fn kobj2device(kobj: Arc<dyn KObject>) -> Option<Arc<dyn Device>> {
kobj.cast::<dyn Device>().ok()
}

/// 将设备的基本信息写入 uevent 文件
fn sysfs_emit_str(buf: &mut [u8], content: &str) -> Result<usize, SystemError> {
log::info!("sysfs_emit_str");
let bytes = content.as_bytes();
if buf.len() < bytes.len() {
return Err(SystemError::ENOMEM);
Expand All @@ -211,7 +224,10 @@ fn kobject_synth_uevent(buf: &[u8], kobj: Arc<dyn KObject>) -> Result<usize, Sys
};

if let Err(e) = result {
let device = kobj2device(kobj).ok_or(SystemError::EINVAL)?;
let device = kobj.cast::<dyn Device>().map_err(|e: Arc<dyn KObject>| {
warn!("device:{:?} is not a device!", e);
SystemError::EINVAL
})?;
let devname = device.name();
log::error!("synth uevent: {}: {:?}", devname, e);
return Err(SystemError::EINVAL);
Expand Down
12 changes: 8 additions & 4 deletions kernel/src/driver/block/virtio_blk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{
device::{
bus::Bus,
driver::{Driver, DriverCommonData},
Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
CommonAttrGroup, Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
kset::KSet,
Expand All @@ -38,7 +38,7 @@ use crate::{
},
},
exception::{irqdesc::IrqReturn, IrqNumber},
filesystem::{kernfs::KernFSInode, mbr::MbrDiskPartionTable},
filesystem::{kernfs::KernFSInode, mbr::MbrDiskPartionTable, sysfs::AttributeGroup},
init::initcall::INITCALL_POSTCORE,
libs::{
rwlock::{RwLockReadGuard, RwLockWriteGuard},
Expand Down Expand Up @@ -342,7 +342,7 @@ impl VirtIODevice for VirtIOBlkDevice {

impl Device for VirtIOBlkDevice {
fn dev_type(&self) -> DeviceType {
DeviceType::Net
DeviceType::Block
}

fn id_table(&self) -> IdTable {
Expand Down Expand Up @@ -407,6 +407,10 @@ impl Device for VirtIOBlkDevice {
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
self.inner().device_common.parent = parent;
}

fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
Some(&[&CommonAttrGroup])
}
}

impl KObject for VirtIOBlkDevice {
Expand Down Expand Up @@ -472,7 +476,7 @@ fn virtio_blk_driver_init() -> Result<(), SystemError> {
let driver = VirtIOBlkDriver::new();
virtio_driver_manager()
.register(driver.clone() as Arc<dyn VirtIODriver>)
.expect("Add virtio net driver failed");
.expect("Add virtio block driver failed");
unsafe {
VIRTIO_BLK_DRIVER = Some(driver);
}
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/driver/net/class.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
driver::base::{
class::{class_manager, Class},
device::sys_dev_char_kset,
device::{sys_dev_char_kset, CommonAttrGroup},
kobject::KObject,
subsys::SubSysPrivate,
},
Expand Down Expand Up @@ -78,6 +78,6 @@ impl Class for NetClass {
}

fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
return &[&NetAttrGroup];
return &[&NetAttrGroup, &CommonAttrGroup];
}
}
8 changes: 6 additions & 2 deletions kernel/src/driver/net/virtio_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
device::{
bus::Bus,
driver::{Driver, DriverCommonData},
Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
CommonAttrGroup, Device, DeviceCommonData, DeviceId, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
kset::KSet,
Expand All @@ -41,7 +41,7 @@ use crate::{
},
},
exception::{irqdesc::IrqReturn, IrqNumber},
filesystem::kernfs::KernFSInode,
filesystem::{kernfs::KernFSInode, sysfs::AttributeGroup},
init::initcall::INITCALL_POSTCORE,
libs::{
rwlock::{RwLockReadGuard, RwLockWriteGuard},
Expand Down Expand Up @@ -249,6 +249,10 @@ impl Device for VirtIONetDevice {
fn set_dev_parent(&self, parent: Option<Weak<dyn Device>>) {
self.inner().device_common.parent = parent;
}

fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
Some(&[&CommonAttrGroup])
}
}

impl VirtIODevice for VirtIONetDevice {
Expand Down
7 changes: 5 additions & 2 deletions kernel/src/driver/pci/raw_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use alloc::{
use crate::{
driver::base::{
class::Class,
device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable},
device::{
bus::Bus, driver::Driver, CommonAttrGroup, Device, DeviceCommonData, DeviceType,
IdTable,
},
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
kset::KSet,
},
Expand Down Expand Up @@ -84,7 +87,7 @@ impl PciDevice for PciGeneralDevice {

impl Device for PciGeneralDevice {
fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
Some(&[&BasicPciReadOnlyAttrs])
Some(&[&BasicPciReadOnlyAttrs, &CommonAttrGroup])
}

fn bus(&self) -> Option<Weak<dyn Bus>> {
Expand Down
7 changes: 5 additions & 2 deletions kernel/src/driver/pci/test/pt_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ use crate::{
driver::{
base::{
class::Class,
device::{bus::Bus, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable},
device::{
bus::Bus, driver::Driver, CommonAttrGroup, Device, DeviceCommonData, DeviceType,
IdTable,
},
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
kset::KSet,
},
Expand Down Expand Up @@ -74,7 +77,7 @@ impl PciDevice for TestDevice {

impl Device for TestDevice {
fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
Some(&[&HelloAttr])
Some(&[&HelloAttr, &CommonAttrGroup])
}

fn bus(&self) -> Option<Weak<dyn Bus>> {
Expand Down
6 changes: 5 additions & 1 deletion kernel/src/driver/rtc/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ use unified_init::macros::unified_init;
use crate::{
driver::base::{
class::{class_manager, Class},
device::{device_manager, sys_dev_char_kset},
device::{device_manager, sys_dev_char_kset, CommonAttrGroup},
kobject::KObject,
subsys::SubSysPrivate,
},
filesystem::sysfs::AttributeGroup,
init::initcall::INITCALL_SUBSYS,
time::{timekeeping::do_settimeofday64, PosixTimeSpec},
};
Expand Down Expand Up @@ -78,6 +79,9 @@ impl Class for RtcClass {
fn subsystem(&self) -> &SubSysPrivate {
return &self.subsystem;
}
fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
return &[&CommonAttrGroup];
}
}

/// 注册rtc通用设备
Expand Down
5 changes: 3 additions & 2 deletions kernel/src/driver/rtc/sysfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use crate::{
driver::base::{
class::Class,
device::{
bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable,
bus::Bus, device_manager, driver::Driver, CommonAttrGroup, Device, DeviceCommonData,
DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
kset::KSet,
Expand Down Expand Up @@ -172,7 +173,7 @@ impl Device for RtcGeneralDevice {
true
}
fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
Some(&[&RtcAttrGroup])
Some(&[&RtcAttrGroup, &CommonAttrGroup])
}

fn dev_parent(&self) -> Option<Weak<dyn Device>> {
Expand Down
Loading

0 comments on commit 38d161c

Please sign in to comment.