Skip to content

Commit

Permalink
feature: 完善设备驱动模型的class的抽象,并创建graphics class
Browse files Browse the repository at this point in the history
  • Loading branch information
fslongjin committed Dec 19, 2023
1 parent e543e45 commit 183ad7b
Show file tree
Hide file tree
Showing 13 changed files with 316 additions and 20 deletions.
7 changes: 3 additions & 4 deletions kernel/src/driver/acpi/bus.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use alloc::{
string::{String, ToString},
sync::{Arc, Weak},
sync::Arc,
};

use crate::{
Expand Down Expand Up @@ -53,12 +53,11 @@ pub(super) struct AcpiBus {

impl AcpiBus {
pub fn new() -> Arc<Self> {
let default_weak: Weak<Self> = Weak::new();
let bus = Arc::new(Self {
private: SubSysPrivate::new("acpi".to_string(), default_weak, &[]),
private: SubSysPrivate::new("acpi".to_string(), None, None, &[]),
});
bus.subsystem()
.set_bus(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>)));
.set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));
return bus;
}
}
Expand Down
166 changes: 164 additions & 2 deletions kernel/src/driver/base/class.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
use alloc::{string::ToString, sync::Arc};

use crate::syscall::SystemError;
use core::fmt::Debug;

use super::kset::KSet;
use crate::{
driver::video::fbdev::base::fbmem::fbmem_init,
filesystem::sysfs::{sysfs_instance, Attribute, AttributeGroup, SysFSOps},
syscall::SystemError,
};

use super::{
device::{sys_dev_char_kset, Device, DeviceMatchName, DeviceMatcher},
kobject::{KObjType, KObject},
kset::KSet,
subsys::SubSysPrivate,
};

/// `/sys/class`的kset
static mut CLASS_KSET_INSTANCE: Option<Arc<KSet>> = None;
Expand All @@ -22,5 +33,156 @@ pub(super) fn classes_init() -> Result<(), SystemError> {
unsafe {
CLASS_KSET_INSTANCE = Some(class_kset);
}

fbmem_init()?;
return Ok(());
}

/// 设备分类
///
/// 类是对设备的高级视图,它抽象了低级实现细节。
///
/// 比如,驱动程序可能看到一个SCSI硬盘或一个ATA硬盘,但在类的这个级别,它们都只是硬盘。
/// 类允许用户空间根据设备的功能而不是它们如何连接或工作来操作设备。
///
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/device/class.h#54
pub trait Class: Debug + Send + Sync {
/// 获取类的名称
fn name(&self) -> &'static str;

/// 属于该类的设备的基本属性。
fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
return &[];
}

/// 当前类的基本属性。
fn class_groups(&self) -> &'static [&'static dyn AttributeGroup] {
return &[];
}

/// 表示此类的kobject,并将它链接到层次结构中。
///
/// 当前class的所有设备,将会挂载到的`/sys/dev/`内的某个目录下。
fn dev_kobj(&self) -> Option<Arc<dyn KObject>>;

fn set_dev_kobj(&self, kobj: Arc<dyn KObject>);

/// subsystem应当拥有的数据
fn subsystem(&self) -> &SubSysPrivate;

/// Called to release this class
fn class_release(&self) {}
}

impl dyn Class {
/// 在class内,根据条件寻找一个特定的设备
///
/// ## 参数
///
/// - `matcher` - 匹配器
/// - `data` - 传给匹配器的数据
#[allow(dead_code)]
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();
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 设备名称
#[allow(dead_code)]
pub fn find_device_by_name(&self, name: &str) -> Option<Arc<dyn Device>> {
return self.find_device(&DeviceMatchName, name);
}
}

pub struct ClassManager;

impl ClassManager {
/// 注册一个设备类
///
/// 该方法会将设备类注册到`/sys/class`目录下,
/// 并创建它的默认属性组对应的文件。
///
/// ## 参数
///
/// - `class` - 设备类
pub fn class_register(class: &Arc<dyn Class>) -> Result<(), SystemError> {
let subsystem = class.subsystem();
let subsys = subsystem.subsys();
subsys.set_name(class.name().to_string());

if class.dev_kobj().is_none() {
class.set_dev_kobj(sys_dev_char_kset() as Arc<dyn KObject>);
}

subsys.set_kobj_type(Some(&ClassKObjbectType));
subsystem.set_class(Some(Arc::downgrade(class)));

subsys.register(Some(sys_class_kset()))?;

sysfs_instance().create_groups(&(subsys as Arc<dyn KObject>), class.class_groups())?;

return Ok(());
}

/// 注销一个设备类
#[allow(dead_code)]
pub fn class_unregister(class: &Arc<dyn Class>) {
let subsystem = class.subsystem();
let subsys = subsystem.subsys();
sysfs_instance().remove_groups(&(subsys.clone() as Arc<dyn KObject>), class.class_groups());
subsys.unregister();
}
}

#[derive(Debug)]
pub struct ClassKObjbectType;

impl KObjType for ClassKObjbectType {
fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
Some(&ClassSysFSOps)
}

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

#[derive(Debug)]
struct ClassSysFSOps;

impl SysFSOps for ClassSysFSOps {
fn show(
&self,
_kobj: Arc<dyn KObject>,
_attr: &dyn Attribute,
_buf: &mut [u8],
) -> Result<usize, SystemError> {
todo!()
}

fn store(
&self,
_kobj: Arc<dyn KObject>,
_attr: &dyn Attribute,
_buf: &[u8],
) -> Result<usize, SystemError> {
todo!()
}
}
5 changes: 2 additions & 3 deletions kernel/src/driver/base/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,11 @@ struct CpuSubSystem {

impl CpuSubSystem {
pub fn new() -> Arc<Self> {
let default_weak: Weak<Self> = Weak::new();
let bus = Arc::new(Self {
subsys_private: SubSysPrivate::new("cpu".to_string(), default_weak, &[]),
subsys_private: SubSysPrivate::new("cpu".to_string(), None, None, &[]),
});
bus.subsystem()
.set_bus(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>)));
.set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));
return bus;
}
}
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/driver/base/device/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ impl BusManager {
///
/// todo: 增加错误处理逻辑
pub fn register(&self, bus: Arc<dyn Bus>) -> Result<(), SystemError> {
bus.subsystem().set_bus(Arc::downgrade(&bus));
bus.subsystem().set_bus(Some(Arc::downgrade(&bus)));

let subsys_kset = bus.subsystem().subsys();
subsys_kset.set_name(bus.name());
Expand Down
7 changes: 6 additions & 1 deletion kernel/src/driver/base/device/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use alloc::{string::ToString, sync::Arc};
use crate::{
driver::base::{
device::{
sys_dev_kset, DeviceManager, DEVICES_KSET_INSTANCE, DEVICE_MANAGER, DEV_KSET_INSTANCE,
set_sys_dev_block_kset, set_sys_dev_char_kset, sys_dev_kset, DeviceManager,
DEVICES_KSET_INSTANCE, DEVICE_MANAGER, DEV_KSET_INSTANCE,
},
kobject::KObject,
kset::KSet,
Expand Down Expand Up @@ -47,6 +48,8 @@ pub fn devices_init() -> Result<(), SystemError> {
dev_block_kset
.register(Some(dev_kset))
.expect("register dev block kset failed");

unsafe { set_sys_dev_block_kset(dev_block_kset) };
}

// 创建 `/sys/dev/char` 目录
Expand All @@ -60,6 +63,8 @@ pub fn devices_init() -> Result<(), SystemError> {
dev_char_kset
.register(Some(dev_kset))
.expect("register dev char kset failed");

unsafe { set_sys_dev_char_kset(dev_char_kset) };
}

kinfo!("devices init success");
Expand Down
12 changes: 10 additions & 2 deletions kernel/src/driver/base/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,23 @@ pub(super) fn sys_dev_kset() -> Arc<KSet> {

#[inline(always)]
#[allow(dead_code)]
pub(super) fn sys_dev_block_kset() -> Arc<KSet> {
pub 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> {
pub fn sys_dev_char_kset() -> Arc<KSet> {
unsafe { DEV_CHAR_KSET_INSTANCE.as_ref().unwrap().clone() }
}

pub(self) unsafe fn set_sys_dev_block_kset(kset: Arc<KSet>) {
DEV_BLOCK_KSET_INSTANCE = Some(kset);
}

pub(self) unsafe fn set_sys_dev_char_kset(kset: Arc<KSet>) {
DEV_CHAR_KSET_INSTANCE = Some(kset);
}

/// 设备应该实现的操作
///
/// ## 注意
Expand Down
21 changes: 21 additions & 0 deletions kernel/src/driver/base/kobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ impl DowncastArc for dyn KObject {
}

pub trait KObjType: Debug + Send + Sync {
/// 当指定的kobject被释放时,设备驱动模型会调用此方法
fn release(&self, _kobj: Arc<dyn KObject>) {}
fn sysfs_ops(&self) -> Option<&dyn SysFSOps>;

Expand Down Expand Up @@ -225,6 +226,26 @@ impl KObjectManager {

return Ok(());
}

/// 从sysfs中移除kobject
pub fn remove_kobj(kobj: Arc<dyn KObject>) {
let ktype = kobj.kobj_type();
if let Some(ktype) = ktype {
if let Some(groups) = ktype.attribute_groups() {
sysfs_instance().remove_groups(&kobj, groups);
}
}

// todo: 发送uevent: KOBJ_REMOVE

sysfs_instance().remove_dir(&kobj);
kobj.update_kobj_state(None, Some(KObjectState::IN_SYSFS));
let kset = kobj.kset();
if let Some(kset) = kset {
kset.leave(&kobj);
}
kobj.set_parent(None);
}
}

/// 动态创建的kobject对象的ktype
Expand Down
11 changes: 11 additions & 0 deletions kernel/src/driver/base/kset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,22 @@ impl KSet {
return Ok(kset);
}

/// 注册一个kset
///
/// ## 参数
///
/// - join_kset: 如果不为None,那么这个kset会加入到join_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
}

/// 注销一个kset
#[allow(dead_code)]
pub fn unregister(&self) {
KObjectManager::remove_kobj(self.self_ref.upgrade().unwrap());
}

/// 把一个kobject加入到当前kset中。
///
/// 该函数不会修改kobj的parent,需要调用者自己视情况修改。
Expand Down
4 changes: 2 additions & 2 deletions kernel/src/driver/base/platform/subsys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ pub struct PlatformBus {
impl PlatformBus {
pub fn new() -> Arc<Self> {
let w: Weak<Self> = Weak::new();
let private = SubSysPrivate::new("platform".to_string(), w, &[]);
let private = SubSysPrivate::new("platform".to_string(), Some(w), None, &[]);
let bus = Arc::new(Self { private });
bus.subsystem()
.set_bus(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>)));
.set_bus(Some(Arc::downgrade(&(bus.clone() as Arc<dyn Bus>))));

return bus;
}
Expand Down
Loading

0 comments on commit 183ad7b

Please sign in to comment.