完善设备驱动模型&调试串口驱动 (#379)

* 完成了基本架构重构,正在进行兼容

* 重构了所有 Device Driver ,还没有接上具体设备

* 基本把 Uart 接上了,还没有测试

* 初步完成系统设备初始化

* 初步重构 BlockDevice ,使其兼容新的 Device 结构

* 修改文件系统内的部分函数调用以满足重构后的接口

* 测试完 Uart 设备的功能

* 移除了自动添加的文件

* 修复了 warning 和部分格式

* 解决warning,并且修正sysfs初始化的位置

* Patch fix

* 删除了 sysinfo 的默认实现

* 删除了字符设备读写的 offset 参数

* 修复了 warning 和一些小逻辑错误

---------

Co-authored-by: longjin <longjin@RinGoTek.cn>
This commit is contained in:
Chiichen
2023-09-13 18:01:52 +08:00
committed by GitHub
parent 9029414af2
commit b087521e07
45 changed files with 1930 additions and 981 deletions

View File

@ -5,7 +5,7 @@ use hashbrown::HashSet;
use x86::time::rdtsc;
use x86_64::registers::model_specific::EferFlags;
use crate::driver::uart::uart::c_uart_send_str;
use crate::driver::uart::uart_device::c_uart_send_str;
use crate::include::bindings::bindings::{
multiboot2_get_memory, multiboot2_iter, multiboot_mmap_entry_t,
};

View File

@ -1,7 +1,7 @@
/// 引入Module
use crate::syscall::SystemError;
use crate::{driver::base::device::Device, syscall::SystemError};
use alloc::{sync::Arc, vec::Vec};
use core::{any::Any, fmt::Debug};
use core::any::Any;
use super::disk_info::Partition;
@ -17,172 +17,10 @@ use super::disk_info::Partition;
pub type BlockId = usize;
/// 定义常量
const BLK_SIZE_LOG2_LIMIT: u8 = 12; // 设定块设备的块大小不能超过 1 << 12.
pub const BLK_SIZE_LOG2_LIMIT: u8 = 12; // 设定块设备的块大小不能超过 1 << 12.
/// 在DragonOS中我们认为磁盘的每个LBA大小均为512字节。注意文件系统的1个扇区可能事实上是多个LBA
pub const LBA_SIZE: usize = 512;
/// @brief 设备应该实现的操作
/// @usage Device::read_at()
pub trait Device: Any + Send + Sync + Debug {
/// Notice buffer对应设备按字节划分使用u8类型
/// Notice offset应该从0开始计数
/// @brief: 从设备的第offset个字节开始读取len个byte存放到buf中
/// @parameter offset: 起始字节偏移量
/// @parameter len: 读取字节的数量
/// @parameter buf: 目标数组
/// @return: 如果操作成功,返回操作的长度(单位是字节);否则返回错误码;如果操作异常,但是并没有检查出什么错误,将返回已操作的长度
fn read_at(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result<usize, SystemError>;
/// @brief: 从设备的第offset个字节开始把buf数组的len个byte写入到设备中
/// @parameter offset: 起始字节偏移量
/// @parameter len: 读取字节的数量
/// @parameter buf: 目标数组
/// @return: 如果操作成功,返回操作的长度(单位是字节);否则返回错误码;如果操作异常,但是并没有检查出什么错误,将返回已操作的长度
fn write_at(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError>;
/// @brief: 同步信息把所有的dirty数据写回设备 - 待实现
fn sync(&self) -> Result<(), SystemError>;
// TODO: 待实现 open, close
}
/// @brief 块设备应该实现的操作
pub trait BlockDevice: Any + Send + Sync + Debug {
/// @brief: 在块设备中从第lba_id_start个块开始读取count个块数据存放到buf中
///
/// @parameter lba_id_start: 起始块
/// @parameter count: 读取块的数量
/// @parameter buf: 目标数组
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
/// 否则返回Err(错误码),其中错误码为负数;
/// 如果操作异常但是并没有检查出什么错误将返回Err(已操作的长度)
fn read_at(
&self,
lba_id_start: BlockId,
count: usize,
buf: &mut [u8],
) -> Result<usize, SystemError>;
/// @brief: 在块设备中从第lba_id_start个块开始把buf中的count个块数据存放到设备中
/// @parameter lba_id_start: 起始块
/// @parameter count: 写入块的数量
/// @parameter buf: 目标数组
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
/// 否则返回Err(错误码),其中错误码为负数;
/// 如果操作异常但是并没有检查出什么错误将返回Err(已操作的长度)
fn write_at(
&self,
lba_id_start: BlockId,
count: usize,
buf: &[u8],
) -> Result<usize, SystemError>;
/// @brief: 同步磁盘信息把所有的dirty数据写回硬盘 - 待实现
fn sync(&self) -> Result<(), SystemError>;
/// @brief: 每个块设备都必须固定自己块大小而且该块大小必须是2的幂次
/// @return: 返回一个固定量,硬编码(编程的时候固定的常量).
fn blk_size_log2(&self) -> u8;
// TODO: 待实现 open, close
/// @brief 本函数用于实现动态转换。
/// 具体的文件系统在实现本函数时最简单的方式就是直接返回self
fn as_any_ref(&self) -> &dyn Any;
/// @brief 本函数用于将BlockDevice转换为Device。
/// 由于实现了BlockDevice的结构体本身也实现了Device Trait, 因此转换是可能的。
/// 思路在BlockDevice的结构体中新增一个self_ref变量返回self_ref.upgrade()即可。
fn device(&self) -> Arc<dyn Device>;
/// @brief 返回块设备的块大小(单位:字节)
fn block_size(&self) -> usize;
/// @brief 返回当前磁盘上的所有分区的Arc指针数组
fn partitions(&self) -> Vec<Arc<Partition>>;
}
/// 对于所有<块设备>自动实现 Device Trait 的 read_at 和 write_at 函数
impl<T: BlockDevice> Device for T {
// 读取设备操作,读取设备内部 [offset, offset + buf.len) 区间内的字符,存放到 buf 中
fn read_at(&self, offset: usize, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
if len > buf.len() {
return Err(SystemError::E2BIG);
}
let iter = BlockIter::new_multiblock(offset, offset + len, self.blk_size_log2());
let multi = iter.multiblock;
// 枚举每一个range
for range in iter {
let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
let buf_end = range.origin_end() - offset;
let buf_slice = &mut buf[buf_begin..buf_end];
let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
let full = multi && range.is_multi() || !multi && range.is_full();
if full {
// 调用 BlockDevice::read_at() 直接把引用传进去不是把整个数组move进去
BlockDevice::read_at(self, range.lba_start, count, buf_slice)?;
} else {
// 判断块的长度不能超过最大值
if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {
return Err(SystemError::E2BIG);
}
let mut temp = Vec::new();
temp.resize(1usize << self.blk_size_log2(), 0);
BlockDevice::read_at(self, range.lba_start, 1, &mut temp[..])?;
// 把数据从临时buffer复制到目标buffer
buf_slice.copy_from_slice(&temp[range.begin..range.end]);
}
}
return Ok(len);
}
/// 写入设备操作,把 buf 的数据写入到设备内部 [offset, offset + len) 区间内
fn write_at(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
// assert!(len <= buf.len());
if len > buf.len() {
return Err(SystemError::E2BIG);
}
let iter = BlockIter::new_multiblock(offset, offset + len, self.blk_size_log2());
let multi = iter.multiblock;
for range in iter {
let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
let buf_end = range.origin_end() - offset;
let buf_slice = &buf[buf_begin..buf_end];
let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
let full = multi && range.is_multi() || !multi && range.is_full();
if full {
BlockDevice::write_at(self, range.lba_start, count, buf_slice)?;
} else {
if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {
return Err(SystemError::E2BIG);
}
let mut temp = Vec::new();
temp.resize(1usize << self.blk_size_log2(), 0);
// 由于块设备每次读写都是整块的,在不完整写入之前,必须把不完整的地方补全
BlockDevice::read_at(self, range.lba_start, 1, &mut temp[..])?;
// 把数据从临时buffer复制到目标buffer
temp[range.begin..range.end].copy_from_slice(&buf_slice);
BlockDevice::write_at(self, range.lba_start, 1, &temp[..])?;
}
}
return Ok(len);
}
/// 数据同步
fn sync(&self) -> Result<(), SystemError> {
BlockDevice::sync(self)
}
}
/// @brief 块设备的迭代器
/// @usage 某次操作读/写块设备的[L,R]范围内的字节,
/// 那么可以使用此结构体进行迭代遍历每次调用next()返回一个BlockRange
@ -331,3 +169,141 @@ pub fn __bytes_to_lba(addr: usize, blk_size: usize) -> BlockId {
pub fn __lba_to_bytes(lba_id: usize, blk_size: usize) -> BlockId {
return lba_id * blk_size;
}
/// @brief 块设备应该实现的操作
pub trait BlockDevice: Device {
/// @brief: 在块设备中从第lba_id_start个块开始读取count个块数据存放到buf中
///
/// @parameter lba_id_start: 起始块
/// @parameter count: 读取块的数量
/// @parameter buf: 目标数组
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
/// 否则返回Err(错误码),其中错误码为负数;
/// 如果操作异常但是并没有检查出什么错误将返回Err(已操作的长度)
fn read_at(
&self,
lba_id_start: BlockId,
count: usize,
buf: &mut [u8],
) -> Result<usize, SystemError>;
/// @brief: 在块设备中从第lba_id_start个块开始把buf中的count个块数据存放到设备中
/// @parameter lba_id_start: 起始块
/// @parameter count: 写入块的数量
/// @parameter buf: 目标数组
/// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
/// 否则返回Err(错误码),其中错误码为负数;
/// 如果操作异常但是并没有检查出什么错误将返回Err(已操作的长度)
fn write_at(
&self,
lba_id_start: BlockId,
count: usize,
buf: &[u8],
) -> Result<usize, SystemError>;
/// @brief: 同步磁盘信息把所有的dirty数据写回硬盘 - 待实现
fn sync(&self) -> Result<(), SystemError>;
/// @brief: 每个块设备都必须固定自己块大小而且该块大小必须是2的幂次
/// @return: 返回一个固定量,硬编码(编程的时候固定的常量).
fn blk_size_log2(&self) -> u8;
// TODO: 待实现 open, close
/// @brief 本函数用于实现动态转换。
/// 具体的文件系统在实现本函数时最简单的方式就是直接返回self
fn as_any_ref(&self) -> &dyn Any;
/// @brief 本函数用于将BlockDevice转换为Device。
/// 由于实现了BlockDevice的结构体本身也实现了Device Trait, 因此转换是可能的。
/// 思路在BlockDevice的结构体中新增一个self_ref变量返回self_ref.upgrade()即可。
fn device(&self) -> Arc<dyn Device>;
/// @brief 返回块设备的块大小(单位:字节)
fn block_size(&self) -> usize;
/// @brief 返回当前磁盘上的所有分区的Arc指针数组
fn partitions(&self) -> Vec<Arc<Partition>>;
fn write_at_bytes(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
// assert!(len <= buf.len());
if len > buf.len() {
return Err(SystemError::E2BIG);
}
let iter = BlockIter::new_multiblock(offset, offset + len, self.blk_size_log2());
let multi = iter.multiblock;
for range in iter {
let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
let buf_end = range.origin_end() - offset;
let buf_slice = &buf[buf_begin..buf_end];
let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
let full = multi && range.is_multi() || !multi && range.is_full();
if full {
self.write_at(range.lba_start, count, buf_slice)?;
} else {
if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {
return Err(SystemError::E2BIG);
}
let mut temp = Vec::new();
temp.resize(1usize << self.blk_size_log2(), 0);
// 由于块设备每次读写都是整块的,在不完整写入之前,必须把不完整的地方补全
self.write_at(range.lba_start, 1, &mut temp[..])?;
// 把数据从临时buffer复制到目标buffer
temp[range.begin..range.end].copy_from_slice(&buf_slice);
self.write_at(range.lba_start, 1, &temp[..])?;
}
}
return Ok(len);
//self.0.lock().write_at(lba_id_start, count, buf)
}
fn read_at_bytes(
&self,
offset: usize,
len: usize,
buf: &mut [u8],
) -> Result<usize, SystemError> {
if len > buf.len() {
return Err(SystemError::E2BIG);
}
let iter = BlockIter::new_multiblock(offset, offset + len, self.blk_size_log2());
let multi = iter.multiblock;
// 枚举每一个range
for range in iter {
let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
let buf_end = range.origin_end() - offset;
let buf_slice = &mut buf[buf_begin..buf_end];
let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
let full = multi && range.is_multi() || !multi && range.is_full();
if full {
// 调用 BlockDevice::read_at() 直接把引用传进去不是把整个数组move进去
self.read_at(range.lba_start, count, buf)?;
} else {
// 判断块的长度不能超过最大值
if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {
return Err(SystemError::E2BIG);
}
let mut temp = Vec::new();
temp.resize(1usize << self.blk_size_log2(), 0);
self.read_at(range.lba_start, 1, &mut temp[..])?;
// 把数据从临时buffer复制到目标buffer
buf_slice.copy_from_slice(&temp[range.begin..range.end]);
}
}
return Ok(len);
// kdebug!(
// "ahci read at {lba_id_start}, count={count}, lock={:?}",
// self.0
// );
}
}

View File

@ -1,8 +1,8 @@
#![allow(dead_code)]
use super::device::BlockDevice;
use alloc::sync::{Arc, Weak};
use super::block_device::BlockDevice;
pub type SectorT = u64;
pub const BLK_TYPE_AHCI: u64 = 0;

View File

@ -1,5 +1,4 @@
pub mod block;
pub mod device;
pub mod block_device;
pub mod disk_info;
#[derive(Debug)]

View File

@ -1,285 +1,25 @@
use super::{
device::{mkdev, DeviceNumber, KObject},
map::{kobj_map, kobj_unmap, LockedKObjMap},
};
use crate::{filesystem::vfs::IndexNode, kerror, libs::spinlock::SpinLock, syscall::SystemError};
use alloc::{sync::Arc, vec::Vec};
use core::cmp::Ordering;
use crate::syscall::SystemError;
const CHARDEV_MAJOR_HASH_SIZE: usize = 255;
const CHARDEV_MAJOR_MAX: usize = 512;
const MINOR_BITS: usize = 20;
const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
/* Marks the bottom of the first segment of free char majors */
const CHARDEV_MAJOR_DYN_END: usize = 234;
/* Marks the top and bottom of the second segment of free char majors */
const CHARDEV_MAJOR_DYN_EXT_START: usize = 511;
const CHARDEV_MAJOR_DYN_EXT_END: usize = 384;
use super::device::Device;
lazy_static! {
// 全局字符设备号管理实例
pub static ref CHARDEVS: Arc<LockedChrDevs> = Arc::new(LockedChrDevs::default());
pub trait CharDevice: Device {
/// Notice buffer对应设备按字节划分使用u8类型
/// Notice offset应该从0开始计数
// 全局字符设备管理实例
pub static ref CDEVMAP: Arc<LockedKObjMap> = Arc::new(LockedKObjMap::default());
}
pub trait CharDevice: KObject {
/// @brief: 打开设备
/// @parameter: file: devfs inode
/// @return: 打开成功返回OK(()),失败,返回错误代码
fn open(&self, file: Arc<dyn IndexNode>) -> Result<(), SystemError>;
/// @brief: 关闭设备
/// @parameter: file: devfs inode
/// @return: 关闭成功返回OK(()),失败,返回错误代码
fn close(&self, file: Arc<dyn IndexNode>) -> Result<(), SystemError>;
}
// 管理字符设备号的map(加锁)
pub struct LockedChrDevs(SpinLock<ChrDevs>);
impl Default for LockedChrDevs {
fn default() -> Self {
LockedChrDevs(SpinLock::new(ChrDevs::default()))
}
}
// 管理字符设备号的map
#[derive(Debug)]
struct ChrDevs(Vec<Vec<CharDeviceStruct>>);
impl Default for ChrDevs {
fn default() -> Self {
ChrDevs(vec![Vec::new(); CHARDEV_MAJOR_HASH_SIZE])
}
}
// 字符设备在系统中的实例devfs通过该结构与实际字符设备进行联系
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CharDeviceStruct {
dev_t: DeviceNumber, //起始设备号
minorct: usize, // 次设备号数量
name: &'static str, //字符设备名
}
impl CharDeviceStruct {
/// @brief: 创建实例
/// @parameter: dev_t: 设备号
/// minorct: 次设备号数量
/// name: 字符设备名
/// char: 字符设备实例
/// @return: 实例
///
#[allow(dead_code)]
pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self {
Self {
dev_t,
minorct,
name,
}
}
/// @brief: 获取起始次设备号
/// @parameter: None
/// @return: 起始设备号
///
#[allow(dead_code)]
pub fn device_number(&self) -> DeviceNumber {
self.dev_t
}
/// @brief: 获取起始次设备号
/// @parameter: None
/// @return: 起始设备号
///
#[allow(dead_code)]
pub fn base_minor(&self) -> usize {
self.dev_t.minor()
}
/// @brief: 获取次设备号数量
/// @parameter: None
/// @return: 次设备号数量
#[allow(dead_code)]
pub fn minorct(&self) -> usize {
self.minorct
}
}
/// @brief 字符设备框架函数集
pub struct CharDevOps;
impl CharDevOps {
/// @brief: 主设备号转下标
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % CHARDEV_MAJOR_HASH_SIZE;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
let chardevs = CHARDEVS.0.lock();
// 寻找主设备号为234255的设备
for index in (CHARDEV_MAJOR_DYN_END..CHARDEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = chardevs.0.get(index) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (CHARDEV_MAJOR_DYN_EXT_END + 1..CHARDEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(chardevss) = chardevs.0.get(Self::major_to_index(index)) {
let mut flag = true;
for item in chardevss {
if item.device_number().major() == index {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 注册设备号,该函数需要指定主设备号
/// @parameter: from: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
#[allow(dead_code)]
pub fn register_chardev_region(
from: DeviceNumber,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(from, count, name)
}
/// @brief: 注册设备号,该函数自动分配主设备号
/// @parameter: baseminor: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_chardev_region(
baseminor: usize,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(mkdev(0, baseminor), count, name)
}
/// @brief: 注册设备号
/// @parameter: device_number: 设备号主设备号如果为0则动态分配
/// minorct: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_chardev_region(
device_number: DeviceNumber,
minorct: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
let mut major = device_number.major();
let baseminor = device_number.minor();
if major >= CHARDEV_MAJOR_MAX {
kerror!(
"CHARDEV {} major requested {} is greater than the maximum {}\n",
name,
major,
CHARDEV_MAJOR_MAX - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
kerror!("CHARDEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
}
let chardev = CharDeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
if let Some(items) = CHARDEVS.0.lock().0.get_mut(Self::major_to_index(major)) {
let mut insert_index: usize = 0;
for (index, item) in items.iter().enumerate() {
insert_index = index;
match item.device_number().major().cmp(&major) {
Ordering::Less => continue,
Ordering::Greater => {
break; // 大于则向后插入
}
Ordering::Equal => {
if item.device_number().minor() + item.minorct() <= baseminor {
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
}
if item.base_minor() >= baseminor + minorct {
break; // 在此处插入
}
return Err(SystemError::EBUSY); // 存在重合的次设备号
}
}
}
items.insert(insert_index, chardev);
}
return Ok(mkdev(major, baseminor));
}
/// @brief: 注销设备号
/// @parameter: major: 主设备号如果为0动态分配
/// baseminor: 起始次设备号
/// minorct: 次设备号数量
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_chardev_region(
device_number: DeviceNumber,
minorct: usize,
) -> Result<(), SystemError> {
if let Some(items) = CHARDEVS
.0
.lock()
.0
.get_mut(Self::major_to_index(device_number.major()))
{
for (index, item) in items.iter().enumerate() {
if item.device_number() == device_number && item.minorct() == minorct {
// 设备号和数量都相等
items.remove(index);
return Ok(());
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 字符设备注册
/// @parameter: cdev: 字符设备实例
/// dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn cdev_add(cdev: Arc<dyn CharDevice>, dev_t: DeviceNumber, range: usize) {
if Into::<usize>::into(dev_t) == 0 {
kerror!("Device number can't be 0!\n");
}
kobj_map(CDEVMAP.clone(), dev_t, range, cdev);
}
/// @brief: 字符设备注销
/// @parameter: dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn cdev_del(dev_t: DeviceNumber, range: usize) {
kobj_unmap(CDEVMAP.clone(), dev_t, range);
}
/// @brief: 从设备的第offset个字节开始读取len个byte存放到buf中
/// @parameter offset: 起始字节偏移量
/// @parameter len: 读取字节的数量
/// @parameter buf: 目标数组
/// @return: 如果操作成功,返回操作的长度(单位是字节);否则返回错误码;如果操作异常,但是并没有检查出什么错误,将返回已操作的长度
fn read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError>;
/// @brief: 从设备的第offset个字节开始把buf数组的len个byte写入到设备中
/// @parameter offset: 起始字节偏移量
/// @parameter len: 读取字节的数量
/// @parameter buf: 目标数组
/// @return: 如果操作成功,返回操作的长度(单位是字节);否则返回错误码;如果操作异常,但是并没有检查出什么错误,将返回已操作的长度
fn write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError>;
/// @brief: 同步信息把所有的dirty数据写回设备 - 待实现
fn sync(&self) -> Result<(), SystemError>;
}

View File

@ -1,9 +1,10 @@
use super::{
device_register, device_unregister,
driver::{driver_register, driver_unregister, Driver, DriverError},
driver::{driver_register, driver_unregister, DriverError},
Device, DeviceError, DeviceState, IdTable,
};
use crate::{
driver::Driver,
filesystem::{
sysfs::{
bus::{sys_bus_init, sys_bus_register},
@ -176,7 +177,7 @@ impl LockedBusManager {
/// @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().to_name()) {
match sys_bus_register(&bus.id_table().name()) {
Ok(inode) => {
let _ = sys_bus_init(&inode);
return device_register(bus);
@ -197,7 +198,7 @@ pub fn bus_unregister<T: Bus>(bus: Arc<T>) -> Result<(), DeviceError> {
/// @brief: 总线驱动注册,将总线驱动加入全局总线管理器中
/// @parameter bus: Bus设备驱动实体
/// @return: 成功:() 失败:DeviceError
pub fn bus_driver_register<T: BusDriver>(bus_driver: Arc<T>) -> Result<(), DriverError> {
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);
}
@ -206,7 +207,7 @@ pub fn bus_driver_register<T: BusDriver>(bus_driver: Arc<T>) -> Result<(), Drive
/// @parameter bus: Bus设备驱动实体
/// @return: 成功:() 失败:DeviceError
#[allow(dead_code)]
pub fn bus_driver_unregister<T: BusDriver>(bus_driver: Arc<T>) -> Result<(), DriverError> {
pub fn bus_driver_unregister(bus_driver: Arc<dyn BusDriver>) -> Result<(), DriverError> {
BUS_MANAGER.add_driver(bus_driver.id_table(), bus_driver.clone());
return driver_unregister(bus_driver);
}

View File

@ -1,5 +1,7 @@
use super::{IdTable, KObject};
use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError};
use super::IdTable;
use crate::{
driver::Driver, filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError,
};
use alloc::{collections::BTreeMap, sync::Arc};
use core::fmt::Debug;
@ -11,42 +13,25 @@ lazy_static! {
#[allow(dead_code)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum DriverError {
ProbeError,
RegisterError,
ProbeError, // 探测设备失败(该驱动不能初始化这个设备)
RegisterError, // 设备注册失败
AllocateResourceError, // 获取设备所需资源失败
UnsupportedOperation, // 不支持的操作
UnInitialized, // 未初始化
}
impl Into<SystemError> for DriverError {
fn into(self) -> SystemError {
match self {
DriverError::ProbeError => SystemError::EIO,
DriverError::RegisterError => SystemError::EIO,
DriverError::ProbeError => SystemError::ENODEV,
DriverError::RegisterError => SystemError::ENODEV,
DriverError::AllocateResourceError => SystemError::EIO,
DriverError::UnsupportedOperation => SystemError::EIO,
DriverError::UnInitialized => SystemError::ENODEV,
}
}
}
/// @brief: 所有驱动驱动都应该实现该trait
pub trait Driver: KObject {
/// @brief: 本函数用于实现动态转换
/// @parameter: None
/// @return: any
fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
/// @brief: 获取驱动驱动标识符
/// @parameter: None
/// @return: 该驱动驱动唯一标识符
fn id_table(&self) -> IdTable;
/// @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>>;
}
/// @brief: 驱动管理器(锁)
#[derive(Debug)]
pub struct LockedDriverManager(SpinLock<DriverManager>);
@ -111,7 +96,7 @@ pub struct DriverManager {
impl DriverManager {
/// @brief: 创建一个新的设备管理器
/// @parameter: None
/// @return: DeviceManager实体
/// @return: Manager实体
#[inline]
fn new() -> DriverManager {
DriverManager {
@ -124,7 +109,7 @@ impl DriverManager {
/// @brief: 驱动注册
/// @parameter: name: 驱动名
/// @return: 操作成功,返回(),操作失败,返回错误码
pub fn driver_register<T: Driver>(driver: Arc<T>) -> Result<(), DriverError> {
pub fn driver_register(driver: Arc<dyn Driver>) -> Result<(), DriverError> {
DRIVER_MANAGER.add_driver(driver.id_table(), driver);
return Ok(());
}
@ -133,7 +118,7 @@ pub fn driver_register<T: Driver>(driver: Arc<T>) -> Result<(), DriverError> {
/// @parameter: name: 驱动名
/// @return: 操作成功,返回(),操作失败,返回错误码
#[allow(dead_code)]
pub fn driver_unregister<T: Driver>(driver: Arc<T>) -> Result<(), DriverError> {
pub fn driver_unregister(driver: Arc<dyn Driver>) -> Result<(), DriverError> {
DRIVER_MANAGER.add_driver(driver.id_table(), driver);
return Ok(());
}

View File

@ -0,0 +1,16 @@
use crate::{driver::uart::uart_device::uart_init, kinfo, syscall::SystemError};
#[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;
}
pub fn device_init() -> Result<(), SystemError> {
uart_init()?;
kinfo!("device init success");
return Ok(());
}

View File

@ -1,6 +1,11 @@
use alloc::{collections::BTreeMap, string::String, sync::Arc};
use alloc::{
collections::BTreeMap,
string::{String, ToString},
sync::Arc,
};
use crate::{
driver::base::map::{LockedDevsMap, LockedKObjMap},
filesystem::{
sysfs::{
devices::{sys_device_register, sys_device_unregister},
@ -13,18 +18,113 @@ use crate::{
};
use core::{any::Any, fmt::Debug};
use super::platform::CompatibleTable;
pub mod bus;
pub mod driver;
pub mod init;
lazy_static! {
pub static ref DEVICE_MANAGER: Arc<LockedDeviceManager> = Arc::new(LockedDeviceManager::new());
}
lazy_static! {
// 全局字符设备号管理实例
pub static ref CHARDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default());
// 全局块设备管理实例
pub static ref BLOCKDEVS: Arc<LockedDevsMap> = Arc::new(LockedDevsMap::default());
// 全局设备管理实例
pub static ref DEVMAP: Arc<LockedKObjMap> = Arc::new(LockedKObjMap::default());
}
pub trait KObject: Any + Send + Sync + Debug {}
/// @brief 设备应该实现的操作
/// @usage Device::read_at()
pub trait Device: KObject {
// TODO: 待实现 open, close
fn as_any_ref(&self) -> &dyn core::any::Any;
/// @brief: 获取设备类型
/// @parameter: None
/// @return: 实现该trait的设备所属类型
fn dev_type(&self) -> DeviceType;
/// @brief: 设备号实例
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
pub struct DeviceNumber(usize);
/// @brief: 获取设备标识
/// @parameter: None
/// @return: 该设备唯一标识
fn id_table(&self) -> IdTable;
/// @brief: 设置sysfs info
/// @parameter: None
/// @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>>;
}
// 暂定是不可修改的,在初始化的时候就要确定。以后可能会包括例如硬件中断包含的信息
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DevicePrivateData {
id_table: IdTable,
resource: Option<DeviceResource>,
compatible_table: CompatibleTable,
state: DeviceState,
}
impl DevicePrivateData {
pub fn new(
id_table: IdTable,
resource: Option<DeviceResource>,
compatible_table: CompatibleTable,
state: DeviceState,
) -> Self {
Self {
id_table,
resource,
compatible_table,
state,
}
}
pub fn id_table(&self) -> &IdTable {
&self.id_table
}
pub fn state(&self) -> DeviceState {
self.state
}
#[allow(dead_code)]
pub fn resource(&self) -> Option<&DeviceResource> {
self.resource.as_ref()
}
pub fn compatible_table(&self) -> &CompatibleTable {
&self.compatible_table
}
pub fn set_state(&mut self, state: DeviceState) {
self.state = state;
}
}
#[derive(Debug, Clone)]
pub struct DeviceResource {
//可能会用来保存例如 IRQ PWM 内存地址等需要申请的资源,将来由资源管理器+Framework框架进行管理。
}
impl Default for DeviceResource {
fn default() -> Self {
return Self {};
}
}
int_like!(DeviceNumber, usize);
impl Default for DeviceNumber {
fn default() -> Self {
@ -44,6 +144,12 @@ impl Into<usize> for DeviceNumber {
}
}
impl core::hash::Hash for DeviceNumber {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl DeviceNumber {
/// @brief: 设备号创建
/// @parameter: dev_t: 设备号
@ -65,6 +171,10 @@ impl DeviceNumber {
pub fn minor(&self) -> usize {
self.0 & 0xfffff
}
pub fn from_major_minor(major: usize, minor: usize) -> usize {
((major & 0xffffff) << 8) | (minor & 0xff)
}
}
/// @brief: 根据主次设备号创建设备号实例
@ -92,7 +202,7 @@ pub enum DeviceType {
/// @brief: 设备标识符类型
#[derive(Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)]
pub struct IdTable(&'static str, u32);
pub struct IdTable(String, DeviceNumber);
/// @brief: 设备标识符操作方法集
impl IdTable {
@ -100,18 +210,29 @@ impl IdTable {
/// @parameter name: 设备名
/// @parameter id: 设备id
/// @return: 设备标识符
pub fn new(name: &'static str, id: u32) -> IdTable {
pub fn new(name: String, id: DeviceNumber) -> IdTable {
Self(name, id)
}
/// @brief: 将设备标识符转换成name
/// @parameter None
/// @return: 设备名
pub fn to_name(&self) -> String {
return format!("{}:{}", self.0, self.1);
pub fn name(&self) -> String {
return format!("{}:{:?}", self.0, self.1 .0);
}
pub fn device_number(&self) -> DeviceNumber {
return self.1;
}
}
impl Default for IdTable {
fn default() -> Self {
IdTable("unknown".to_string(), DeviceNumber::new(0))
}
}
// 以现在的模型,设备在加载到系统中就是已经初始化的状态了,因此可以考虑把这个删掉
/// @brief: 设备当前状态
#[derive(Debug, Clone, Copy)]
pub enum DeviceState {
@ -121,14 +242,17 @@ pub enum DeviceState {
}
/// @brief: 设备错误类型
#[allow(dead_code)]
#[derive(Debug, Copy, Clone)]
pub enum DeviceError {
DriverExists, // 设备已存在
DeviceExists, // 驱动已存在
InitializeFailed, // 初始化错误
NoDeviceForDriver, // 没有合适的设备匹配驱动
NoDriverForDevice, // 没有合适的驱动匹配设备
RegisterError, // 注册失败
DriverExists, // 设备已存在
DeviceExists, // 驱动已存在
InitializeFailed, // 初始化错误
NotInitialized, // 未初始化的设备
NoDeviceForDriver, // 没有合适的设备匹配驱动
NoDriverForDevice, // 没有合适的驱动匹配设备
RegisterError, // 注册失败
UnsupportedOperation, // 不支持的操作
}
impl Into<SystemError> for DeviceError {
@ -137,9 +261,11 @@ impl Into<SystemError> for DeviceError {
DeviceError::DriverExists => SystemError::EEXIST,
DeviceError::DeviceExists => SystemError::EEXIST,
DeviceError::InitializeFailed => SystemError::EIO,
DeviceError::NotInitialized => SystemError::ENODEV,
DeviceError::NoDeviceForDriver => SystemError::ENODEV,
DeviceError::NoDriverForDevice => SystemError::ENODEV,
DeviceError::RegisterError => SystemError::EIO,
DeviceError::UnsupportedOperation => SystemError::EIO,
}
}
}
@ -166,34 +292,6 @@ impl From<DeviceState> for u32 {
}
}
/// @brief: 所有设备都应该实现该trait
pub trait Device: KObject {
/// @brief: 本函数用于实现动态转换
/// @parameter: None
/// @return: any
fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
/// @brief: 获取设备类型
/// @parameter: None
/// @return: 实现该trait的设备所属类型
fn dev_type(&self) -> DeviceType;
/// @brief: 获取设备标识
/// @parameter: None
/// @return: 该设备唯一标识
fn id_table(&self) -> IdTable;
/// @brief: 设置sysfs info
/// @parameter: None
/// @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>>;
}
/// @brief Device管理器(锁)
#[derive(Debug)]
pub struct LockedDeviceManager(SpinLock<DeviceManager>);
@ -269,7 +367,7 @@ impl DeviceManager {
/// @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().to_name()) {
match sys_device_register(&device.id_table().name()) {
Ok(sys_info) => {
device.set_sys_info(Some(sys_info));
return Ok(());
@ -283,7 +381,7 @@ pub fn device_register<T: Device>(device: Arc<T>) -> Result<(), DeviceError> {
/// @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().to_name()) {
match sys_device_unregister(&device.id_table().name()) {
Ok(_) => {
device.set_sys_info(None);
return Ok(());

View File

@ -1,8 +1,23 @@
use super::device::{mkdev, DeviceNumber, KObject};
use crate::libs::spinlock::SpinLock;
use core::cmp::Ordering;
use super::{
block::block_device::BlockDevice,
char::CharDevice,
device::{mkdev, DeviceNumber, IdTable, KObject, BLOCKDEVS, CHARDEVS, DEVICE_MANAGER, DEVMAP},
};
use crate::{kerror, libs::spinlock::SpinLock, syscall::SystemError};
use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
const KOBJMAP_HASH_SIZE: usize = 255;
const DEV_MAJOR_HASH_SIZE: usize = 255;
const DEV_MAJOR_MAX: usize = 512;
const MINOR_BITS: usize = 20;
const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
/* Marks the bottom of the first segment of free char majors */
const DEV_MAJOR_DYN_END: usize = 234;
/* Marks the top and bottom of the second segment of free char majors */
const DEV_MAJOR_DYN_EXT_START: usize = 511;
const DEV_MAJOR_DYN_EXT_END: usize = 384;
/// @brief: 字符设备与块设备管理结构体
#[derive(Debug, Clone)]
@ -96,3 +111,435 @@ pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Ar
}
return None;
}
// 管理字符设备号的map(加锁)
pub struct LockedDevsMap(SpinLock<DevsMap>);
impl Default for LockedDevsMap {
fn default() -> Self {
LockedDevsMap(SpinLock::new(DevsMap::default()))
}
}
// 管理字符设备号的map
#[derive(Debug)]
struct DevsMap(Vec<Vec<DeviceStruct>>);
impl Default for DevsMap {
fn default() -> Self {
DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE])
}
}
// 字符设备在系统中的实例devfs通过该结构与实际字符设备进行联系
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DeviceStruct {
dev_t: DeviceNumber, //起始设备号
minorct: usize, // 次设备号数量
name: &'static str, //字符设备名
}
impl DeviceStruct {
/// @brief: 创建实例
/// @parameter: dev_t: 设备号
/// minorct: 次设备号数量
/// name: 字符设备名
/// char: 字符设备实例
/// @return: 实例
///
#[allow(dead_code)]
pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self {
Self {
dev_t,
minorct,
name,
}
}
/// @brief: 获取起始次设备号
/// @parameter: None
/// @return: 起始设备号
///
#[allow(dead_code)]
pub fn device_number(&self) -> DeviceNumber {
self.dev_t
}
/// @brief: 获取起始次设备号
/// @parameter: None
/// @return: 起始设备号
///
#[allow(dead_code)]
pub fn base_minor(&self) -> usize {
self.dev_t.minor()
}
/// @brief: 获取次设备号数量
/// @parameter: None
/// @return: 次设备号数量
#[allow(dead_code)]
pub fn minorct(&self) -> usize {
self.minorct
}
}
// 这下面是考虑到 块设备的注册和字符设备的注册在设备号的自动分配上要有所区别,
// 暂时没有去查具体是怎么做区分的,因此暂时还是一样的
/// @brief 块设备框架函数集
pub struct BlockDeviceOps;
impl BlockDeviceOps {
/// @brief: 主设备号转下标
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % DEV_MAJOR_HASH_SIZE;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
let blockdevs = BLOCKDEVS.0.lock();
// 寻找主设备号为234255的设备
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = blockdevs.0.get(index) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(blockdevss) = blockdevs.0.get(Self::major_to_index(index)) {
let mut flag = true;
for item in blockdevss {
if item.device_number().major() == index {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 注册设备号,该函数需要指定主设备号
/// @parameter: from: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
#[allow(dead_code)]
pub fn register_blockdev_region(
from: DeviceNumber,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_blockdev_region(from, count, name)
}
/// @brief: 注册设备号,该函数自动分配主设备号
/// @parameter: baseminor: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_blockdev_region(
baseminor: usize,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_blockdev_region(mkdev(0, baseminor), count, name)
}
/// @brief: 注册设备号
/// @parameter: device_number: 设备号主设备号如果为0则动态分配
/// minorct: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_blockdev_region(
device_number: DeviceNumber,
minorct: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
let mut major = device_number.major();
let baseminor = device_number.minor();
if major >= DEV_MAJOR_MAX {
kerror!(
"DEV {} major requested {} is greater than the maximum {}\n",
name,
major,
DEV_MAJOR_MAX - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
}
let blockdev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
if let Some(items) = BLOCKDEVS.0.lock().0.get_mut(Self::major_to_index(major)) {
let mut insert_index: usize = 0;
for (index, item) in items.iter().enumerate() {
insert_index = index;
match item.device_number().major().cmp(&major) {
Ordering::Less => continue,
Ordering::Greater => {
break; // 大于则向后插入
}
Ordering::Equal => {
if item.device_number().minor() + item.minorct() <= baseminor {
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
}
if item.base_minor() >= baseminor + minorct {
break; // 在此处插入
}
return Err(SystemError::EBUSY); // 存在重合的次设备号
}
}
}
items.insert(insert_index, blockdev);
}
return Ok(mkdev(major, baseminor));
}
/// @brief: 注销设备号
/// @parameter: major: 主设备号如果为0动态分配
/// baseminor: 起始次设备号
/// minorct: 次设备号数量
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_blockdev_region(
device_number: DeviceNumber,
minorct: usize,
) -> Result<(), SystemError> {
if let Some(items) = BLOCKDEVS
.0
.lock()
.0
.get_mut(Self::major_to_index(device_number.major()))
{
for (index, item) in items.iter().enumerate() {
if item.device_number() == device_number && item.minorct() == minorct {
// 设备号和数量都相等
items.remove(index);
return Ok(());
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 块设备注册
/// @parameter: cdev: 字符设备实例
/// dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn bdev_add(bdev: Arc<dyn BlockDevice>, id_table: IdTable) {
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())
}
/// @brief: block设备注销
/// @parameter: dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn bdev_del(_devnum: DeviceNumber, _range: usize) {}
}
/// @brief 字符设备框架函数集
pub struct CharDevOps;
impl CharDevOps {
/// @brief: 主设备号转下标
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % DEV_MAJOR_HASH_SIZE;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
let chardevs = CHARDEVS.0.lock();
// 寻找主设备号为234255的设备
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = chardevs.0.get(index) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(chardevss) = chardevs.0.get(Self::major_to_index(index)) {
let mut flag = true;
for item in chardevss {
if item.device_number().major() == index {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 注册设备号,该函数需要指定主设备号
/// @parameter: from: 主设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
#[allow(dead_code)]
pub fn register_chardev_region(
from: DeviceNumber,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(from, count, name)
}
/// @brief: 注册设备号,该函数自动分配主设备号
/// @parameter: baseminor: 次设备号
/// count: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_chardev_region(
baseminor: usize,
count: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(mkdev(0, baseminor), count, name)
}
/// @brief: 注册设备号
/// @parameter: device_number: 设备号主设备号如果为0则动态分配
/// minorct: 次设备号数量
/// name: 字符设备名
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_chardev_region(
device_number: DeviceNumber,
minorct: usize,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
let mut major = device_number.major();
let baseminor = device_number.minor();
if major >= DEV_MAJOR_MAX {
kerror!(
"DEV {} major requested {} is greater than the maximum {}\n",
name,
major,
DEV_MAJOR_MAX - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
name, baseminor, baseminor + minorct - 1, 0, MINOR_MASK);
}
let chardev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
if let Some(items) = CHARDEVS.0.lock().0.get_mut(Self::major_to_index(major)) {
let mut insert_index: usize = 0;
for (index, item) in items.iter().enumerate() {
insert_index = index;
match item.device_number().major().cmp(&major) {
Ordering::Less => continue,
Ordering::Greater => {
break; // 大于则向后插入
}
Ordering::Equal => {
if item.device_number().minor() + item.minorct() <= baseminor {
continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
}
if item.base_minor() >= baseminor + minorct {
break; // 在此处插入
}
return Err(SystemError::EBUSY); // 存在重合的次设备号
}
}
}
items.insert(insert_index, chardev);
}
return Ok(mkdev(major, baseminor));
}
/// @brief: 注销设备号
/// @parameter: major: 主设备号如果为0动态分配
/// baseminor: 起始次设备号
/// minorct: 次设备号数量
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_chardev_region(
device_number: DeviceNumber,
minorct: usize,
) -> Result<(), SystemError> {
if let Some(items) = CHARDEVS
.0
.lock()
.0
.get_mut(Self::major_to_index(device_number.major()))
{
for (index, item) in items.iter().enumerate() {
if item.device_number() == device_number && item.minorct() == minorct {
// 设备号和数量都相等
items.remove(index);
return Ok(());
}
}
}
return Err(SystemError::EBUSY);
}
/// @brief: 字符设备注册
/// @parameter: cdev: 字符设备实例
/// dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn cdev_add(cdev: Arc<dyn CharDevice>, id_table: IdTable, range: usize) {
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());
kobj_map(
DEVMAP.clone(),
id_table.device_number(),
range,
cdev.clone(),
)
}
/// @brief: 字符设备注销
/// @parameter: dev_t: 字符设备号
/// range: 次设备号范围
/// @return: none
#[allow(dead_code)]
pub fn cdev_del(id_table: IdTable, range: usize) {
DEVICE_MANAGER.remove_device(&id_table);
kobj_unmap(DEVMAP.clone(), id_table.device_number(), range);
}
}

View File

@ -1,3 +1,4 @@
pub mod block;
pub mod char;
pub mod device;
pub mod map;

View File

@ -1,11 +1,15 @@
use super::device::{
bus::{bus_driver_register, bus_register, Bus, BusDriver, BusState},
driver::Driver,
Device, DeviceError, DeviceState, DeviceType, IdTable, KObject,
driver::DriverError,
Device, DeviceError, DeviceNumber, DevicePrivateData, DeviceResource, DeviceType, IdTable,
KObject,
};
use crate::{
driver::Driver, filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError,
};
use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError};
use alloc::{
collections::{BTreeMap, BTreeSet},
string::ToString,
sync::Arc,
vec::Vec,
};
@ -19,7 +23,7 @@ pub mod platform_driver;
/// @brief: platform总线匹配表
/// 总线上的设备和驱动都存在一份匹配表
/// 根据匹配表条目是否匹配来辨识设备和驱动能否进行匹配
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct CompatibleTable(BTreeSet<&'static str>);
/// @brief: 匹配表操作方法集
@ -38,12 +42,16 @@ impl CompatibleTable {
/// @return: 如果匹配成功返回true否则返回false
#[allow(dead_code)]
pub fn matches(&self, other: &CompatibleTable) -> bool {
for id in &self.0 {
if other.0.contains(id) {
return true;
}
self.0.intersection(&other.0).next().is_some()
}
/// @brief: 添加一组匹配条目
/// @param:
#[allow(dead_code)]
pub fn add_device(&mut self, devices: Vec<&'static str>) {
for str in devices {
self.0.insert(str);
}
return false;
}
}
@ -111,9 +119,13 @@ impl LockedPlatformBusDriver {
/// @return: None
#[allow(dead_code)]
#[inline]
fn unregister_platform_driver(&mut self, driver: Arc<dyn PlatformDriver>) {
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类型设备
@ -144,63 +156,6 @@ impl LockedPlatformBusDriver {
let id_table = device.id_table();
self.0.lock().devices.remove(&id_table);
}
/// @brief: 匹配platform类型驱动
/// @parameter driver: platform类型驱动
/// @return: 如果匹配成功返回成功驱动的设备数否则返回BusError类型
#[allow(dead_code)]
fn driver_match_device(&self, driver: Arc<dyn PlatformDriver>) -> Result<i32, DeviceError> {
let mut num = 0;
let devices = &self.0.lock().devices;
for (_dev_id_table, device) in devices.iter() {
if device
.compatible_table()
.matches(&driver.compatible_table())
{
if !device.is_initialized() {
// 设备未初始化调用驱动probe函数
match driver.probe(device.clone()) {
Ok(()) => {
num = num + 1;
device.set_state(DeviceState::Initialized)
}
// 可以驱动很多设备,一个设备初始化出错即返回
Err(_) => return Err(DeviceError::InitializeFailed),
}
}
}
}
if num == 0 {
return Err(DeviceError::NoDeviceForDriver);
} else {
return Ok(num);
}
}
/// @brief: 匹配platform上的设备
/// @parameter driver: platform类型设备
/// @return: 如果匹配成功返回Ok(())否则返回BusError类型
#[allow(dead_code)]
fn device_match_driver(&self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
let drivers = &mut self.0.lock().drivers;
for (_drv_id_table, driver) in drivers.into_iter() {
if driver
.compatible_table()
.matches(&device.compatible_table())
{
match driver.probe(device.clone()) {
Ok(_driver) => {
// 将设备状态置为已初始化
device.set_state(DeviceState::Initialized);
return Ok(());
}
Err(_) => return Err(DeviceError::InitializeFailed),
}
}
}
return Err(DeviceError::NoDriverForDevice);
}
}
/// @brief: platform总线驱动
@ -235,7 +190,7 @@ impl Driver for LockedPlatformBusDriver {
#[inline]
fn id_table(&self) -> IdTable {
IdTable::new("PlatformBusDriver", 0)
return IdTable::new("PlatformBusDriver".to_string(), DeviceNumber::new(0));
}
#[inline]
@ -249,6 +204,18 @@ impl Driver for LockedPlatformBusDriver {
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
@ -271,8 +238,8 @@ impl LockedPlatform {
/// @brief: 创建一个加锁的platform总线实例
/// @parameter: None
/// @return: platform总线实例
pub fn new() -> LockedPlatform {
LockedPlatform(SpinLock::new(Platform::new()))
pub fn new(data: DevicePrivateData) -> LockedPlatform {
LockedPlatform(SpinLock::new(Platform::new(data)))
}
/// @brief: 获取总线的匹配表
@ -316,22 +283,22 @@ impl LockedPlatform {
return state;
}
/// @brief:
/// @parameter: None
/// @return: 总线状态
#[inline]
#[allow(dead_code)]
fn set_driver(&self, driver: Option<Arc<LockedPlatformBusDriver>>) {
self.0.lock().driver = driver;
}
// /// @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 {
state: BusState, // 总线状态
driver: Option<Arc<LockedPlatformBusDriver>>, // 总线驱动
sys_info: Option<Arc<dyn IndexNode>>, // 总线sys information
_data: DevicePrivateData,
state: BusState, // 总线状态
sys_info: Option<Arc<dyn IndexNode>>, // 总线sys information
}
/// @brief: platform方法集
@ -339,10 +306,10 @@ impl Platform {
/// @brief: 创建一个platform总线实例
/// @parameter: None
/// @return: platform总线实例
pub fn new() -> Self {
pub fn new(_data: DevicePrivateData) -> Self {
Self {
_data,
state: BusState::NotInitialized,
driver: Option::None,
sys_info: Option::None,
}
}
@ -359,7 +326,7 @@ impl Device for LockedPlatform {
#[inline]
#[allow(dead_code)]
fn id_table(&self) -> IdTable {
IdTable::new("platform", 0)
IdTable::new("platform".to_string(), DeviceNumber::new(0))
}
#[inline]
@ -373,7 +340,7 @@ impl Device for LockedPlatform {
return self.0.lock().sys_info.clone();
}
fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
}
@ -388,10 +355,16 @@ impl KObject for LockedPlatform {}
/// @return: None
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());
let platform_device: Arc<LockedPlatform> =
Arc::new(LockedPlatform::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()));
//platform_device.set_driver(Some(platform_driver.clone()));
bus_driver_register(platform_driver.clone()).map_err(|e| e.into())?;
return Ok(());

View File

@ -1,18 +1,11 @@
use super::{
super::device::{Device, DeviceState},
platform_driver::PlatformDriver,
CompatibleTable,
};
use alloc::sync::Arc;
use crate::driver::base::device::Device;
use super::{super::device::DeviceState, CompatibleTable};
/// @brief: 实现该trait的设备实例应挂载在platform总线上
/// 同时应该实现Device trait
pub trait PlatformDevice: Device {
/// @brief: 获取设备匹配表
/// @parameter: None
/// @return: 设备匹配表
fn compatible_table(&self) -> CompatibleTable;
/// @brief: 判断设备是否初始化
/// @parameter: None
/// @return: 如果已经初始化返回true否则返回false
@ -22,9 +15,4 @@ pub trait PlatformDevice: Device {
/// @parameter set_state: 设备状态
/// @return: None
fn set_state(&self, set_state: DeviceState);
/// @brief: 设置platform设备驱动
/// @parameter driver: platform设备驱动
/// @return: None
fn set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>);
}

View File

@ -1,20 +1,21 @@
use super::{
super::device::driver::{Driver, DriverError},
platform_device::PlatformDevice,
CompatibleTable,
};
use alloc::sync::Arc;
use crate::driver::{base::device::DevicePrivateData, Driver};
use super::{super::device::driver::DriverError, CompatibleTable};
lazy_static! {
static ref PLATFORM_COMPAT_TABLE: CompatibleTable = CompatibleTable::new(vec!["platform"]);
}
/// @brief: 实现该trait的设备驱动实例应挂载在platform总线上
/// 同时应该实现Driver trait
pub trait PlatformDriver: Driver {
/// @brief: 设备驱动探测函数,此函数在设备和驱动匹配成功后调用
/// @parameter device: 匹配成功的设备实例
/// @return: 成功驱动设备返回Ok(())否则返回DriverError
fn probe(&self, device: Arc<dyn PlatformDevice>) -> Result<(), DriverError>;
/// @brief: 获取驱动匹配表
/// @parameter: None
/// @return: 驱动匹配表
fn compatible_table(&self) -> CompatibleTable;
/// @brief 探测设备
/// @param data 设备初始拥有的基本信息
fn probe(&self, data: DevicePrivateData) -> Result<(), DriverError> {
if data.compatible_table().matches(&PLATFORM_COMPAT_TABLE) {
return Ok(());
} else {
return Err(DriverError::UnsupportedOperation);
}
}
}

View File

@ -1,6 +1,6 @@
use crate::driver::base::block::block_device::BlockDevice;
use crate::filesystem::devfs::{DevFS, DeviceINode};
use crate::filesystem::vfs::file::FileMode;
use crate::filesystem::vfs::io::device::BlockDevice;
use crate::filesystem::vfs::{
core::generate_inode_id, make_rawdev, FilePrivateData, FileSystem, FileType, IndexNode,
Metadata, PollStatus,
@ -124,7 +124,7 @@ impl IndexNode for LockedAhciInode {
}
if let FilePrivateData::Unused = data {
return self.0.lock().disk.read_at(offset, len, buf);
return self.0.lock().disk.read_at_bytes(offset, len, buf);
}
return Err(SystemError::EINVAL);
@ -143,7 +143,7 @@ impl IndexNode for LockedAhciInode {
}
if let FilePrivateData::Unused = data {
return self.0.lock().disk.write_at(offset, len, buf);
return self.0.lock().disk.write_at_bytes(offset, len, buf);
}
return Err(SystemError::EINVAL);

View File

@ -1,9 +1,13 @@
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::disk::ahci::HBA_PxIS_TFES;
use crate::filesystem::mbr::MbrDiskPartionTable;
use crate::filesystem::vfs::io::{device::BlockDevice, disk_info::Partition, SeekFrom};
use crate::include::bindings::bindings::verify_area;
use crate::kdebug;
use crate::libs::{spinlock::SpinLock, vec_cursor::VecCursor};
use crate::mm::phys_2_virt;
use crate::syscall::SystemError;
@ -52,8 +56,8 @@ impl Debug for AhciDisk {
impl AhciDisk {
fn read_at(
&self,
lba_id_start: crate::filesystem::vfs::io::device::BlockId, // 起始lba编号
count: usize, // 读取lba的数量
lba_id_start: BlockId, // 起始lba编号
count: usize, // 读取lba的数量
buf: &mut [u8],
) -> Result<usize, SystemError> {
compiler_fence(core::sync::atomic::Ordering::SeqCst);
@ -211,7 +215,7 @@ impl AhciDisk {
fn write_at(
&self,
lba_id_start: crate::filesystem::vfs::io::device::BlockId,
lba_id_start: BlockId,
count: usize,
buf: &[u8],
) -> Result<usize, SystemError> {
@ -392,7 +396,6 @@ impl LockedAhciDisk {
));
}
}
result.0.lock().partitions = part_s;
result.0.lock().self_ref = weak_this;
return Ok(result);
@ -406,14 +409,13 @@ impl LockedAhciDisk {
let mut buf: Vec<u8> = Vec::new();
buf.resize(size_of::<MbrDiskPartionTable>(), 0);
self.read_at(0, 1, &mut buf)?;
BlockDevice::read_at(self, 0, 1, &mut buf)?;
// 创建 Cursor 用于按字节读取
let mut cursor = VecCursor::new(buf);
cursor.seek(SeekFrom::SeekCurrent(446))?;
for i in 0..4 {
// kdebug!("infomation of partition {}:\n", i);
kdebug!("infomation of partition {}:\n", i);
table.dpte[i].flags = cursor.read_u8()?;
table.dpte[i].starting_head = cursor.read_u8()?;
@ -424,7 +426,7 @@ impl LockedAhciDisk {
table.dpte[i].starting_lba = cursor.read_u32()?;
table.dpte[i].total_sectors = cursor.read_u32()?;
// kdebug!("dpte[i] = {:?}", table.dpte[i]);
kdebug!("dpte[i] = {:?}", table.dpte[i]);
}
table.bs_trailsig = cursor.read_u16()?;
// kdebug!("bs_trailsig = {}", unsafe {
@ -435,6 +437,30 @@ impl LockedAhciDisk {
}
}
impl KObject for LockedAhciDisk {}
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 {
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 BlockDevice for LockedAhciDisk {
#[inline]
fn as_any_ref(&self) -> &dyn core::any::Any {
@ -446,36 +472,12 @@ impl BlockDevice for LockedAhciDisk {
9
}
#[inline]
fn read_at(
&self,
lba_id_start: crate::filesystem::vfs::io::device::BlockId,
count: usize,
buf: &mut [u8],
) -> Result<usize, SystemError> {
// kdebug!(
// "ahci read at {lba_id_start}, count={count}, lock={:?}",
// self.0
// );
return self.0.lock().read_at(lba_id_start, count, buf);
}
#[inline]
fn write_at(
&self,
lba_id_start: crate::filesystem::vfs::io::device::BlockId,
count: usize,
buf: &[u8],
) -> Result<usize, SystemError> {
self.0.lock().write_at(lba_id_start, count, buf)
}
fn sync(&self) -> Result<(), SystemError> {
return self.0.lock().sync();
}
#[inline]
fn device(&self) -> Arc<dyn crate::filesystem::vfs::io::device::Device> {
fn device(&self) -> Arc<dyn Device> {
return self.0.lock().self_ref.upgrade().unwrap();
}
@ -486,4 +488,24 @@ impl BlockDevice for LockedAhciDisk {
fn partitions(&self) -> Vec<Arc<Partition>> {
return self.0.lock().partitions.clone();
}
#[inline]
fn read_at(
&self,
lba_id_start: BlockId, // 起始lba编号
count: usize, // 读取lba的数量
buf: &mut [u8],
) -> Result<usize, SystemError> {
self.0.lock().read_at(lba_id_start, count, buf)
}
#[inline]
fn write_at(
&self,
lba_id_start: BlockId,
count: usize,
buf: &[u8],
) -> Result<usize, SystemError> {
self.0.lock().write_at(lba_id_start, count, buf)
}
}

View File

@ -3,13 +3,13 @@ pub mod ahci_inode;
pub mod ahcidisk;
pub mod hba;
use crate::filesystem::vfs::io::device::BlockDevice;
use crate::driver::base::block::block_device::BlockDevice;
use crate::driver::base::block::disk_info::BLK_GF_AHCI;
// 依赖的rust工具包
use crate::driver::pci::pci::{
get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
};
use crate::filesystem::devfs::devfs_register;
use crate::filesystem::vfs::io::disk_info::BLK_GF_AHCI;
use crate::kerror;
use crate::libs::rwlock::RwLockWriteGuard;
use crate::libs::spinlock::{SpinLock, SpinLockGuard};

View File

@ -1,81 +0,0 @@
#include "ata.h"
#include <common/kprint.h>
#include <driver/interrupt/apic/apic.h>
struct apic_IO_APIC_RTE_entry entry;
/**
* @brief 硬盘中断上半部处理程序
*
* @param irq_num
* @param param
* @param regs
*/
void ata_disk_handler(ul irq_num, ul param, struct pt_regs *regs)
{
struct ata_identify_device_data info;
kdebug("irq_num=%ld", irq_num);
// 从端口读入磁盘配置信息
io_insw(PORT_DISK0_DATA, &info, 256);
kdebug("General_Config=%#018lx", info.General_Config);
printk("Serial number:");
unsigned char buf[64];
int js=0;
//printk("%d", info.Serial_Number);
for(int i = 0;i<10;i++)
{
buf[js++]=(info.Serial_Number[i] & 0xff);
}
buf[js] = '\0';
printk("%s", buf);
printk("\n");
}
hardware_intr_controller ata_disk_intr_controller =
{
.enable = apic_ioapic_enable,
.disable = apic_ioapic_disable,
.install = apic_ioapic_install,
.uninstall = apic_ioapic_uninstall,
.ack = apic_ioapic_edge_ack,
};
/**
* @brief 初始化ATA磁盘驱动程序
*
*/
void ata_init()
{
entry.vector = 0x2e;
entry.deliver_mode = IO_APIC_FIXED;
entry.dest_mode = DEST_PHYSICAL;
entry.deliver_status = IDLE;
entry.polarity = POLARITY_HIGH;
entry.remote_IRR = IRR_RESET;
entry.trigger_mode = EDGE_TRIGGER;
entry.mask = MASKED;
entry.reserved = 0;
entry.destination.physical.reserved1 = 0;
entry.destination.physical.reserved2 = 0;
entry.destination.physical.phy_dest = 0; // 投递至BSP
irq_register(entry.vector, &entry, &ata_disk_handler, 0, &ata_disk_intr_controller, "ATA Disk 1");
io_out8(PORT_DISK0_STATUS_CTRL_REG, 0); // 使能中断请求
io_out8(PORT_DISK0_ERR_STATUS, 0);
io_out8(PORT_DISK0_SECTOR_CNT, 0);
io_out8(PORT_DISK0_LBA_7_0, 0);
io_out8(PORT_DISK0_LBA_15_8, 0);
io_out8(PORT_DISK0_LBA_23_16, 0);
io_out8(PORT_DISK0_DEVICE_CONFIGURE_REG, 0);
io_out8(PORT_DISK0_CONTROLLER_STATUS_CMD, 0xec); // 获取硬件设备识别信息
}

View File

@ -11,6 +11,60 @@ pub mod video;
pub mod virtio;
use core::fmt::Debug;
use alloc::sync::Arc;
use crate::filesystem::vfs::IndexNode;
use self::base::{
device::{driver::DriverError, Device, DevicePrivateData, DeviceResource, IdTable},
platform::CompatibleTable,
};
pub trait Driver: Sync + Send + Debug {
fn as_any_ref(&'static self) -> &'static dyn core::any::Any;
//对于不需要匹配,在系统初始化的时候就生成的设备,例如 PlatformBus 就不需要匹配表
/// @brief: 获取驱动匹配表
/// @parameter: None
/// @return: 驱动匹配表
fn compatible_table(&self) -> CompatibleTable {
//TODO 要完善每个 CompatibleTable ,将来要把这个默认实现删除
return CompatibleTable::new(vec!["unknown"]);
}
/// @brief 添加可支持的设备
/// @parameter: device 新增的匹配项
fn append_compatible_table(&self, _device: &CompatibleTable) -> Result<(), DriverError> {
Err(DriverError::UnsupportedOperation)
}
/// @brief 探测设备
/// @param data 设备初始拥有的基本信息
fn probe(&self, data: &DevicePrivateData) -> Result<(), DriverError>;
/// @brief 加载设备,包括检查资源可用性,和注册到相应的管理器中。
/// @param data 设备初始拥有的信息
/// @param resource 设备可能申请的资源(或者像伪设备不需要就为None)
fn load(
&self,
data: DevicePrivateData,
resource: Option<DeviceResource>,
) -> Result<Arc<dyn Device>, DriverError>;
/// @brief: 获取驱动标识符
/// @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

@ -9,7 +9,11 @@ use smoltcp::{phy, wire};
use virtio_drivers::{device::net::VirtIONet, transport::Transport};
use crate::{
driver::{virtio::virtio_impl::HalImpl, Driver},
driver::{
base::device::{driver::DriverError, Device, DevicePrivateData, DeviceResource, IdTable},
virtio::virtio_impl::HalImpl,
Driver,
},
kerror, kinfo,
libs::spinlock::SpinLock,
net::{generate_iface_id, NET_DRIVERS},
@ -240,6 +244,30 @@ impl<T: Transport> Driver for VirtioInterface<T> {
fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
self
}
fn probe(&self, _data: &DevicePrivateData) -> Result<(), DriverError> {
todo!()
}
fn load(
&self,
_data: DevicePrivateData,
_resource: Option<DeviceResource>,
) -> Result<Arc<dyn Device>, DriverError> {
todo!()
}
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> {

View File

@ -1 +1,2 @@
pub mod uart;
pub mod uart_device;
pub mod uart_driver;

View File

@ -1,22 +1,38 @@
use super::super::base::device::Device;
use crate::{
driver::base::{
char::CharDevice,
device::{driver::Driver, DeviceState, DeviceType, IdTable, KObject},
platform::{
self, platform_device::PlatformDevice, platform_driver::PlatformDriver, CompatibleTable,
driver::{
base::{
char::CharDevice,
device::{
driver::DriverError, Device, DeviceError, DeviceNumber, DevicePrivateData,
DeviceResource, DeviceState, DeviceType, IdTable, KObject, DEVICE_MANAGER,
},
platform::{
platform_device::PlatformDevice, platform_driver::PlatformDriver, CompatibleTable,
},
},
Driver,
},
filesystem::{
devfs::{devfs_register, DevFS, DeviceINode},
sysfs::bus::{bus_device_register, bus_driver_register},
vfs::IndexNode,
vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata, PollStatus},
},
include::bindings::bindings::{io_in8, io_out8},
kinfo,
libs::spinlock::SpinLock,
syscall::SystemError,
};
use alloc::sync::Arc;
use core::{char, intrinsics::offset, str};
use alloc::{
string::{String, ToString},
sync::{Arc, Weak},
vec::Vec,
};
use core::{
any::Any,
char,
intrinsics::offset,
str::{self, from_utf8},
};
const UART_SUCCESS: i32 = 0;
const E_UART_BITS_RATE_ERROR: i32 = 1;
@ -100,17 +116,34 @@ struct UartRegister {
// @brief 串口设备结构体
#[derive(Debug)]
pub struct Uart {
state: DeviceState, // 设备状态
private_data: DevicePrivateData, // 设备状态
sys_info: Option<Arc<dyn IndexNode>>,
driver: Option<Arc<dyn PlatformDriver>>,
fs: Weak<DevFS>, // 文件系统
port: UartPort,
baud_rate: u32,
metadata: Metadata,
}
impl Default for Uart {
fn default() -> Self {
let mut metadata = Metadata::default();
metadata.file_type = FileType::CharDevice;
c_uart_init(UartPort::COM1.to_u16(), 115200);
Self {
state: DeviceState::NotInitialized,
private_data: DevicePrivateData::new(
IdTable::new(
"uart".to_string(),
DeviceNumber::new(DeviceNumber::from_major_minor(4, 64)),
),
None,
CompatibleTable::new(vec!["uart"]),
DeviceState::NotInitialized,
),
sys_info: None,
driver: None,
fs: Weak::default(),
port: UartPort::COM1,
baud_rate: 115200,
metadata,
}
}
}
@ -128,12 +161,8 @@ impl Default for LockedUart {
impl KObject for LockedUart {}
impl PlatformDevice for LockedUart {
fn compatible_table(&self) -> platform::CompatibleTable {
platform::CompatibleTable::new(vec!["uart"])
}
fn is_initialized(&self) -> bool {
let state = self.0.lock().state;
let state = self.0.lock().private_data.state();
match state {
DeviceState::Initialized => true,
_ => false,
@ -141,18 +170,20 @@ impl PlatformDevice for LockedUart {
}
fn set_state(&self, set_state: DeviceState) {
let state = &mut self.0.lock().state;
*state = set_state;
self.0.lock().private_data.set_state(set_state);
}
fn set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>) {
self.0.lock().driver = driver;
fn compatible_table(&self) -> CompatibleTable {
return self.0.lock().private_data.compatible_table().clone();
}
}
impl Device for LockedUart {
fn id_table(&self) -> IdTable {
IdTable::new("uart", 0)
return IdTable::new(
"uart".to_string(),
DeviceNumber::new(DeviceNumber::from_major_minor(4, 64)),
);
}
fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
@ -167,121 +198,222 @@ impl Device for LockedUart {
DeviceType::Serial
}
fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
fn as_any_ref(&self) -> &dyn Any {
self
}
}
// @brief 串口驱动结构体
#[repr(C)]
#[derive(Debug)]
pub struct UartDriver {
port: UartPort,
baud_rate: u32,
sys_info: Option<Arc<dyn IndexNode>>,
}
impl Default for UartDriver {
fn default() -> Self {
Self {
port: UartPort::COM1,
baud_rate: 115200,
sys_info: None,
impl CharDevice for LockedUart {
fn read(&self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
let device = self.0.lock();
if len > buf.len() {
return Err(SystemError::E2BIG);
}
kinfo!("------len: {:?}", len);
for i in 0..len {
buf[i] = Self::uart_read_byte(&device.port) as u8;
kinfo!("------buf[{:?}] = {:?}", i, buf[i]);
}
return Ok(len);
}
fn write(&self, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
let device = self.0.lock();
if len > buf.len() {
return Err(SystemError::E2BIG);
}
Self::uart_send(
&device.port,
from_utf8(&buf[0..len]).map_err(|_| SystemError::EIO)?,
);
return Ok(len);
}
fn sync(&self) -> Result<(), SystemError> {
todo!()
}
}
// @brief 串口驱动结构体(加锁)
#[derive(Debug)]
pub struct LockedUartDriver(SpinLock<UartDriver>);
// impl TtyDevice for LockedUart {
// fn ioctl(&self, cmd: String) -> Result<(), DeviceError> {
// //TODO 补充详细信息
// Err(DeviceError::UnsupportedOperation)
// }
// fn state(&self) -> Result<TtyState, TtyError> {
// todo!()
// }
// }
impl Default for LockedUartDriver {
fn default() -> Self {
Self(SpinLock::new(UartDriver::default()))
}
}
impl KObject for LockedUartDriver {}
impl Driver for LockedUartDriver {
fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
self
}
fn id_table(&self) -> IdTable {
return IdTable::new("uart_driver", 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();
}
}
impl CharDevice for LockedUartDriver {
fn open(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError> {
return Ok(());
}
fn close(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError> {
return Ok(());
}
}
impl LockedUartDriver {
/// @brief 创建串口驱动
/// @param port 端口号
/// baud_rate 波特率
/// sys_info: sys文件系统inode
/// @return
#[allow(dead_code)]
pub fn new(port: UartPort, baud_rate: u32, sys_info: Option<Arc<dyn IndexNode>>) -> Self {
Self(SpinLock::new(UartDriver::new(port, baud_rate, sys_info)))
}
}
impl PlatformDriver for LockedUartDriver {
fn probe(
impl IndexNode for LockedUart {
fn read_at(
&self,
_device: Arc<dyn PlatformDevice>,
) -> Result<(), crate::driver::base::device::driver::DriverError> {
_offset: usize,
len: usize,
buf: &mut [u8],
_data: &mut FilePrivateData,
) -> Result<usize, SystemError> {
CharDevice::read(self, len, buf)
}
fn write_at(
&self,
_offset: usize,
len: usize,
buf: &[u8],
_data: &mut FilePrivateData,
) -> Result<usize, SystemError> {
CharDevice::write(self, len, buf)
}
fn poll(&self) -> Result<PollStatus, SystemError> {
todo!()
}
fn fs(&self) -> Arc<dyn FileSystem> {
return self
.0
.lock()
.fs
.clone()
.upgrade()
.expect("DevFS is not initialized inside Uart Device");
}
fn as_any_ref(&self) -> &dyn Any {
todo!()
}
fn list(&self) -> Result<Vec<String>, SystemError> {
todo!()
}
fn metadata(&self) -> Result<Metadata, SystemError> {
return Ok(self.0.lock().metadata.clone());
}
fn open(
&self,
_data: &mut FilePrivateData,
_mode: &crate::filesystem::vfs::file::FileMode,
) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Ok(());
}
fn compatible_table(&self) -> platform::CompatibleTable {
return CompatibleTable::new(vec!["uart"]);
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Ok(());
}
fn set_metadata(&self, _metadata: &Metadata) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Ok(self.0.lock().metadata = _metadata.clone());
}
fn create(
&self,
name: &str,
file_type: FileType,
mode: u32,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 若文件系统没有实现此方法则默认调用其create_with_data方法。如果仍未实现则会得到一个Err(-EOPNOTSUPP_OR_ENOTSUP)的返回值
return self.create_with_data(name, file_type, mode, 0);
}
fn create_with_data(
&self,
_name: &str,
_file_type: FileType,
_mode: u32,
_data: usize,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn link(&self, _name: &str, _other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn unlink(&self, _name: &str) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn rmdir(&self, _name: &str) -> Result<(), SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn move_(
&self,
_old_name: &str,
_target: &Arc<dyn IndexNode>,
_new_name: &str,
) -> Result<(), SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn find(&self, _name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn get_entry_name(&self, _ino: crate::filesystem::vfs::InodeId) -> Result<String, SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn get_entry_name_and_metadata(
&self,
ino: crate::filesystem::vfs::InodeId,
) -> Result<(String, Metadata), SystemError> {
// 如果有条件,请在文件系统中使用高效的方式实现本接口,而不是依赖这个低效率的默认实现。
let name = self.get_entry_name(ino)?;
let entry = self.find(&name)?;
return Ok((name, entry.metadata()?));
}
fn ioctl(&self, _cmd: u32, _data: usize) -> Result<usize, SystemError> {
// 若文件系统没有实现此方法,则返回“不支持”
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn mount(
&self,
_fs: Arc<dyn FileSystem>,
) -> Result<Arc<crate::filesystem::vfs::MountFS>, SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn truncate(&self, _len: usize) -> Result<(), SystemError> {
return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
}
fn sync(&self) -> Result<(), SystemError> {
return Ok(());
}
}
impl UartDriver {
/// @brief 创建串口驱动
/// @param port 端口号
/// baud_rate 波特率
/// sys_info: sys文件系统inode
/// @return 返回串口驱动
#[allow(dead_code)]
pub fn new(port: UartPort, baud_rate: u32, sys_info: Option<Arc<dyn IndexNode>>) -> Self {
Self {
port,
baud_rate,
sys_info,
}
impl DeviceINode for LockedUart {
fn set_fs(&self, fs: Weak<DevFS>) {
self.0.lock().fs = fs;
}
}
impl LockedUart {
/// @brief 串口初始化
/// @param uart_port 端口号
/// @param baud_rate 波特率
/// @return 初始化成功返回0,失败,返回错误信息
#[allow(dead_code)]
pub fn uart_init(uart_port: &UartPort, baud_rate: u32) -> Result<i32, &'static str> {
pub fn uart_init(uart_port: &UartPort, baud_rate: u32) -> Result<(), DeviceError> {
let message: &'static str = "uart init.";
let port = uart_port.to_u16();
// 错误的比特率
if baud_rate > UART_MAX_BITS_RATE || UART_MAX_BITS_RATE % baud_rate != 0 {
return Err("uart init error.");
return Err(DeviceError::InitializeFailed);
}
unsafe {
@ -300,15 +432,15 @@ impl UartDriver {
// Check if serial is faulty (i.e: not same byte as sent)
if io_in8(port + 0) != 0xAE {
return Err("uart faulty");
return Err(DeviceError::InitializeFailed);
}
// If serial is not faulty set it in normal operation mode
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
io_out8(port + 4, 0x08);
}
UartDriver::uart_send(uart_port, message);
Ok(0)
Self::uart_send(uart_port, message);
Ok(())
/*
Notice that the initialization code above writes to [PORT + 1]
twice with different values. This is once to write to the Divisor
@ -342,13 +474,12 @@ impl UartDriver {
#[allow(dead_code)]
fn uart_send(uart_port: &UartPort, s: &str) {
let port = uart_port.to_u16();
while UartDriver::is_transmit_empty(port) == false {
for c in s.bytes() {
unsafe {
io_out8(port, c);
}
while Self::is_transmit_empty(port) == false {} //TODO:pause
for c in s.bytes() {
unsafe {
io_out8(port, c);
}
} //TODO:pause
}
}
/// @brief 串口接收一个字节
@ -357,8 +488,8 @@ impl UartDriver {
#[allow(dead_code)]
fn uart_read_byte(uart_port: &UartPort) -> char {
let port = uart_port.to_u16();
while UartDriver::serial_received(port) == false {} //TODO:pause
unsafe { io_in8(port) as char }
while Self::serial_received(port) == false {} //TODO:pause
return unsafe { io_in8(port) as char };
}
#[allow(dead_code)]
@ -367,12 +498,112 @@ impl UartDriver {
}
}
// @brief 串口驱动结构体
#[repr(C)]
#[derive(Debug)]
pub struct UartDriver {
id_table: IdTable,
sys_info: Option<Arc<dyn IndexNode>>,
}
impl Default for UartDriver {
fn default() -> Self {
Self {
id_table: IdTable::new(
"ttyS".to_string(),
DeviceNumber::new(DeviceNumber::from_major_minor(4, 64)),
),
sys_info: None,
}
}
}
// @brief 串口驱动结构体(加锁)
#[derive(Debug)]
pub struct LockedUartDriver(SpinLock<UartDriver>);
impl Default for LockedUartDriver {
fn default() -> Self {
Self(SpinLock::new(UartDriver::default()))
}
}
impl KObject for LockedUartDriver {}
impl Driver for LockedUartDriver {
fn as_any_ref(&self) -> &dyn Any {
self
}
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"])) {
return Ok(());
}
return Err(DriverError::ProbeError);
}
fn load(
&self,
_data: DevicePrivateData,
_resource: Option<DeviceResource>,
) -> Result<Arc<dyn Device>, DriverError> {
return Err(DriverError::UnsupportedOperation);
}
}
impl LockedUartDriver {
/// @brief 创建串口驱动
/// @param sys_info: sys文件系统inode
/// @return
#[allow(dead_code)]
pub fn new(sys_info: Option<Arc<dyn IndexNode>>) -> Self {
Self(SpinLock::new(UartDriver::new(sys_info)))
}
}
impl PlatformDriver for LockedUartDriver {
fn compatible_table(&self) -> CompatibleTable {
return CompatibleTable::new(vec!["uart"]);
}
}
impl UartDriver {
/// @brief 创建串口驱动
/// @param sys_info: sys文件系统inode
/// @return 返回串口驱动
#[allow(dead_code)]
pub fn new(sys_info: Option<Arc<dyn IndexNode>>) -> Self {
Self {
id_table: IdTable::new(
"ttyS".to_string(),
DeviceNumber::new(DeviceNumber::from_major_minor(4, 64)),
),
sys_info,
}
}
}
///@brief 发送数据
///@param port 端口号
///@param c 要发送的数据
#[no_mangle]
pub extern "C" fn c_uart_send(port: u16, c: u8) {
while UartDriver::is_transmit_empty(port) == false {} //TODO:pause
while LockedUart::is_transmit_empty(port) == false {} //TODO:pause
unsafe {
io_out8(port, c);
}
@ -383,7 +614,7 @@ pub extern "C" fn c_uart_send(port: u16, c: u8) {
///@return u8 接收到的数据
#[no_mangle]
pub extern "C" fn c_uart_read(port: u16) -> u8 {
while UartDriver::serial_received(port) == false {} //TODO:pause
while LockedUart::serial_received(port) == false {} //TODO:pause
unsafe { io_in8(port) }
}
@ -455,13 +686,18 @@ pub extern "C" fn c_uart_init(port: u16, baud_rate: u32) -> i32 {
/// @param none
/// @return 初始化成功,返回(),失败,返回错误码
pub fn uart_init() -> Result<(), SystemError> {
let device_inode = bus_device_register("platform:0", &UART_DEV.id_table().to_name())
// 以后设备管理初始化完善后不应该出现这种代码,应该在 Driver load 一个设备,即返回设备实例之前就完成设备的 init ,不应该用 lazy_init 在设备上
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().to_name())
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_driver(Some(UART_DRV.clone()));
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());
return Ok(());
}

View File

@ -0,0 +1,81 @@
use alloc::sync::Arc;
use crate::driver::base::device::{Device, DeviceResource, DEVICE_MANAGER};
use crate::driver::base::map::CharDevOps;
use crate::driver::base::platform::CompatibleTable;
use crate::{
driver::{
base::device::{driver::DriverError, DevicePrivateData, IdTable},
Driver,
},
libs::spinlock::SpinLock,
};
use super::uart_device::LockedUart;
lazy_static! {
pub static ref UART_COMPAT_TABLE: CompatibleTable = CompatibleTable::new(vec!["uart"]);
}
#[derive(Debug)]
pub struct InnerUartDriver {
id_table: IdTable,
}
#[derive(Debug)]
pub struct UartDriver(SpinLock<InnerUartDriver>);
impl Default for UartDriver {
fn default() -> Self {
Self(SpinLock::new(InnerUartDriver {
id_table: IdTable::default(),
}))
}
}
impl Driver for UartDriver {
fn probe(&self, data: &DevicePrivateData) -> Result<(), DriverError> {
let compatible_table = data.compatible_table();
if compatible_table.matches(&UART_COMPAT_TABLE) {
return Ok(());
}
return Err(DriverError::ProbeError);
}
fn load(
&self,
data: DevicePrivateData,
_resource: Option<DeviceResource>,
) -> Result<Arc<dyn Device>, DriverError> {
if let Some(device) = DEVICE_MANAGER.get_device(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);
}
return Err(DriverError::ProbeError);
}
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

@ -8,8 +8,11 @@ use super::vfs::{
FileSystem, FileType, FsInfo, IndexNode, Metadata, PollStatus,
};
use crate::{
kerror,
libs::spinlock::{SpinLock, SpinLockGuard},
kerror, kinfo,
libs::{
once::Once,
spinlock::{SpinLock, SpinLockGuard},
},
syscall::SystemError,
time::TimeSpec,
};
@ -529,3 +532,23 @@ pub fn devfs_register<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(),
pub fn devfs_unregister<T: DeviceINode>(name: &str, device: Arc<T>) -> Result<(), SystemError> {
return devfs_exact_ref!().unregister_device(name, device);
}
pub fn devfs_init() -> Result<(), SystemError> {
static INIT: Once = Once::new();
let mut result = None;
INIT.call_once(|| {
kinfo!("Initializing ProcFS...");
// 创建 devfs 实例
let devfs: Arc<DevFS> = DevFS::new();
// devfs 挂载
let _t = ROOT_INODE()
.find("dev")
.expect("Cannot find /dev")
.mount(devfs)
.expect("Failed to mount devfs");
kinfo!("DevFS mounted.");
result = Some(Ok(()));
});
return result.unwrap();
}

View File

@ -2,7 +2,7 @@
use alloc::{sync::Arc, vec::Vec};
use crate::{
filesystem::vfs::io::{device::LBA_SIZE, disk_info::Partition, SeekFrom},
driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom},
kerror,
libs::vec_cursor::VecCursor,
syscall::SystemError,

View File

@ -2,7 +2,7 @@
use core::{cmp::min, intrinsics::unlikely};
use crate::{
filesystem::vfs::io::{device::LBA_SIZE, SeekFrom},
driver::base::block::{block_device::LBA_SIZE, SeekFrom},
kwarn,
libs::vec_cursor::VecCursor,
syscall::SystemError,
@ -130,7 +130,7 @@ impl FATFile {
// 从磁盘上读取数据
let offset = fs.cluster_bytes_offset(current_cluster) + in_cluster_offset;
let r = fs.partition.disk().device().read_at(
let r = fs.partition.disk().read_at_bytes(
offset as usize,
end_len,
&mut buf[start..start + end_len],
@ -198,7 +198,7 @@ impl FATFile {
// 计算本次写入位置在磁盘上的偏移量
let offset = fs.cluster_bytes_offset(current_cluster) + in_cluster_bytes_offset;
// 写入磁盘
let w: usize = fs.partition.disk().device().write_at(
let w: usize = fs.partition.disk().write_at(
offset as usize,
end_len,
&buf[start..start + end_len],
@ -326,11 +326,9 @@ impl FATFile {
}
let zeroes: Vec<u8> = vec![0u8; (range_end - range_start) as usize];
fs.partition.disk().device().write_at(
range_start as usize,
zeroes.len(),
zeroes.as_slice(),
)?;
fs.partition
.disk()
.write_at(range_start as usize, zeroes.len(), zeroes.as_slice())?;
return Ok(());
}
@ -612,11 +610,10 @@ impl FATDir {
LongDirEntry::validate_long_name(name)?;
// 目标目录项
let mut short_entry = ShortDirEntry::default();
// kdebug!("to allocate cluster");
let first_cluster: Cluster = fs.allocate_cluster(None)?;
short_entry.set_first_cluster(first_cluster);
// kdebug!("to create dot");
// === 接下来在子目录中创建'.'目录项和'..'目录项
let mut offset = 0;
// '.'目录项
@ -632,7 +629,6 @@ impl FATDir {
// 偏移量加上一个目录项的长度
offset += FATRawDirEntry::DIR_ENTRY_LEN;
// kdebug!("to create dot dot");
// '..'目录项
let mut dot_dot_entry = ShortDirEntry::default();
dot_dot_entry.name = ShortNameGenerator::new("..").generate().unwrap();

View File

@ -9,7 +9,7 @@ use alloc::{
};
use crate::{
filesystem::vfs::io::{device::LBA_SIZE, disk_info::Partition, SeekFrom},
driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom},
filesystem::vfs::{
core::generate_inode_id,
file::{FileMode, FilePrivateData},
@ -1174,8 +1174,7 @@ impl FATFileSystem {
let offset: usize = self.cluster_bytes_offset(cluster) as usize;
self.partition
.disk()
.device()
.write_at(offset, zeros.len(), zeros.as_slice())?;
.write_at_bytes(offset, zeros.len(), zeros.as_slice())?;
return Ok(());
}
}
@ -1425,7 +1424,6 @@ impl IndexNode for LockedFATInode {
_mode: u32,
) -> Result<Arc<dyn IndexNode>, SystemError> {
// 由于FAT32不支持文件权限的功能因此忽略mode参数
let mut guard: SpinLockGuard<FATInode> = self.0.lock();
let fs: &Arc<FATFileSystem> = &guard.fs.upgrade().unwrap();

View File

@ -16,8 +16,11 @@ use crate::{
FileType,
},
include::bindings::bindings::{pid_t, process_find_pcb_by_pid},
kerror,
libs::spinlock::{SpinLock, SpinLockGuard},
kerror, kinfo,
libs::{
once::Once,
spinlock::{SpinLock, SpinLockGuard},
},
syscall::SystemError,
time::TimeSpec,
};
@ -704,3 +707,24 @@ pub fn procfs_unregister_pid(pid: pid_t) -> Result<(), SystemError> {
// 调用解除注册函数
return procfs.unregister_pid(pid);
}
pub fn procfs_init() -> Result<(), SystemError> {
static INIT: Once = Once::new();
let mut result = None;
INIT.call_once(|| {
kinfo!("Initializing ProcFS...");
// 创建 sysfs 实例
let procfs: Arc<ProcFS> = ProcFS::new();
// sysfs 挂载
let _t = ROOT_INODE()
.find("proc")
.expect("Cannot find /proc")
.mount(procfs)
.expect("Failed to mount proc");
kinfo!("ProcFS mounted.");
result = Some(Ok(()));
});
return result.unwrap();
}

View File

@ -3,7 +3,13 @@ use super::vfs::{
PollStatus,
};
use crate::{
libs::spinlock::{SpinLock, SpinLockGuard},
driver::base::platform::platform_bus_init,
filesystem::{sysfs::bus::sys_bus_init, vfs::ROOT_INODE},
kdebug, kinfo,
libs::{
once::Once,
spinlock::{SpinLock, SpinLockGuard},
},
syscall::SystemError,
time::TimeSpec,
};
@ -136,10 +142,7 @@ impl SysFS {
},
Err(_) => panic!("SysFS: Failed to create /sys/fs"),
}
// 初始化platform总线
crate::driver::base::platform::platform_bus_init().expect("platform bus init failed");
// 初始化串口
crate::driver::uart::uart::uart_init().expect("initilize uart error");
return sysfs;
}
}
@ -446,3 +449,33 @@ impl SysFSInode {
};
}
}
pub fn sysfs_init() -> Result<(), SystemError> {
static INIT: Once = Once::new();
let mut result = None;
INIT.call_once(|| {
kinfo!("Initializing SysFS...");
// 创建 sysfs 实例
let sysfs: Arc<SysFS> = SysFS::new();
// sysfs 挂载
let _t = ROOT_INODE()
.find("sys")
.expect("Cannot find /sys")
.mount(sysfs)
.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());
result = Some(Ok(()));
});
return result.unwrap();
}

View File

@ -7,17 +7,20 @@ use core::{
use alloc::{boxed::Box, format, string::ToString, sync::Arc};
use crate::{
driver::disk::ahci::{self},
driver::{
base::block::disk_info::Partition,
disk::ahci::{self},
},
filesystem::{
devfs::DevFS,
devfs::devfs_init,
fat::fs::FATFileSystem,
procfs::ProcFS,
procfs::procfs_init,
ramfs::RamFS,
sysfs::SysFS,
sysfs::sysfs_init,
vfs::{mount::MountFS, FileSystem, FileType},
},
include::bindings::bindings::PAGE_4K_SIZE,
kerror, kinfo,
kdebug, kerror, kinfo,
syscall::SystemError,
};
@ -65,37 +68,13 @@ pub extern "C" fn vfs_init() -> i32 {
root_inode
.create("sys", FileType::Dir, 0o777)
.expect("Failed to create /sys");
kdebug!("dir in root:{:?}", root_inode.list());
// // 创建procfs实例
let procfs: Arc<ProcFS> = ProcFS::new();
procfs_init().expect("Failed to initialize procfs");
// procfs挂载
let _t = root_inode
.find("proc")
.expect("Cannot find /proc")
.mount(procfs)
.expect("Failed to mount procfs.");
kinfo!("ProcFS mounted.");
devfs_init().expect("Failed to initialize devfs");
// 创建 devfs 实例
let devfs: Arc<DevFS> = DevFS::new();
// devfs 挂载
let _t = root_inode
.find("dev")
.expect("Cannot find /dev")
.mount(devfs)
.expect("Failed to mount devfs");
kinfo!("DevFS mounted.");
// 创建 sysfs 实例
let sysfs: Arc<SysFS> = SysFS::new();
// sysfs 挂载
let _t = root_inode
.find("sys")
.expect("Cannot find /sys")
.mount(sysfs)
.expect("Failed to mount sysfs");
kinfo!("SysFS mounted.");
sysfs_init().expect("Failed to initialize sysfs");
let root_inode = ROOT_INODE().list().expect("VFS init failed");
if root_inode.len() > 0 {
@ -117,14 +96,14 @@ fn do_migrate(
let mountpoint = if r.is_err() {
new_root_inode
.create(mountpoint_name, FileType::Dir, 0o777)
.expect(format!("Failed to create '/{mountpoint_name}'").as_str())
.expect(format!("Failed to create '/{mountpoint_name}' in migrating").as_str())
} else {
r.unwrap()
};
// 迁移挂载点
mountpoint
.mount(fs.inner_filesystem())
.expect(format!("Failed to migrate {mountpoint_name}").as_str());
.expect(format!("Failed to migrate {mountpoint_name} ").as_str());
return Ok(());
}
@ -168,13 +147,12 @@ fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemE
#[no_mangle]
pub extern "C" fn mount_root_fs() -> i32 {
kinfo!("Try to mount FAT32 as root fs...");
let partiton: Arc<crate::filesystem::vfs::io::disk_info::Partition> =
ahci::get_disks_by_name("ahci_disk_0".to_string())
.unwrap()
.0
.lock()
.partitions[0]
.clone();
let partiton: Arc<Partition> = ahci::get_disks_by_name("ahci_disk_0".to_string())
.unwrap()
.0
.lock()
.partitions[0]
.clone();
let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton);
if fatfs.is_err() {

View File

@ -3,9 +3,15 @@ use core::mem::MaybeUninit;
use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec};
use crate::{
arch::asm::current::current_pcb, driver::tty::TtyFilePrivateData,
filesystem::procfs::ProcfsFilePrivateData, filesystem::vfs::io::SeekFrom,
include::bindings::bindings::process_control_block, kerror, syscall::SystemError,
arch::asm::current::current_pcb,
driver::{
base::{block::SeekFrom, device::DevicePrivateData},
tty::TtyFilePrivateData,
},
filesystem::procfs::ProcfsFilePrivateData,
include::bindings::bindings::process_control_block,
kerror,
syscall::SystemError,
};
use super::{Dirent, FileType, IndexNode, Metadata};
@ -15,7 +21,9 @@ use super::{Dirent, FileType, IndexNode, Metadata};
pub enum FilePrivateData {
/// procfs文件私有信息
Procfs(ProcfsFilePrivateData),
/// Tty设备的私有信息
/// 设备文件的私有信息
DevFS(DevicePrivateData),
/// tty设备文件的私有信息
Tty(TtyFilePrivateData),
/// 不需要文件私有信息
Unused,

View File

@ -3,7 +3,6 @@
pub mod core;
pub mod fcntl;
pub mod file;
pub mod io;
pub mod mount;
pub mod syscall;
mod utils;

View File

@ -2,8 +2,8 @@ use alloc::{boxed::Box, sync::Arc, vec::Vec};
use crate::{
arch::asm::current::current_pcb,
driver::base::block::SeekFrom,
filesystem::vfs::file::FileDescriptorVec,
filesystem::vfs::io::SeekFrom,
include::bindings::bindings::{verify_area, AT_REMOVEDIR, PAGE_4K_SIZE, PROC_MAX_FD_NUM},
kerror,
syscall::{Syscall, SystemError},

View File

@ -10,7 +10,7 @@ use elf::{endian::AnyEndian, file::FileHeader, segment::ProgramHeader};
use crate::{
arch::MMArch,
current_pcb,
filesystem::vfs::io::SeekFrom,
driver::base::block::SeekFrom,
kerror,
libs::align::page_align_up,
mm::{

View File

@ -7,7 +7,7 @@ use core::{
use alloc::{boxed::Box, collections::LinkedList, string::String, sync::Arc};
use crate::{
driver::uart::uart::{c_uart_send_str, UartPort},
driver::uart::uart_device::{c_uart_send_str, UartPort},
include::bindings::bindings::{
scm_buffer_info_t, video_frame_buffer_info, video_reinitialize, video_set_refresh_target,
},

View File

@ -1,5 +1,5 @@
use crate::{
driver::uart::uart::{c_uart_send, c_uart_send_str, UartPort},
driver::uart::uart_device::{c_uart_send, c_uart_send_str, UartPort},
include::bindings::bindings::video_frame_buffer_info,
kinfo,
libs::{lib_ui::font::FONT_8x16, spinlock::SpinLock},

View File

@ -4,7 +4,7 @@ use core::{
};
use crate::{
driver::uart::uart::{c_uart_send, UartPort},
driver::uart::uart_device::{c_uart_send, UartPort},
include::bindings::bindings::video_frame_buffer_info,
syscall::SystemError,
};

View File

@ -4,7 +4,7 @@ use core::mem::size_of;
use alloc::vec::Vec;
use crate::{filesystem::vfs::io::SeekFrom, syscall::SystemError};
use crate::{driver::base::block::SeekFrom, syscall::SystemError};
/// @brief 本模块用于为数组提供游标的功能,以简化其操作。
#[derive(Debug)]

View File

@ -34,7 +34,8 @@
#include <driver/interrupt/apic/apic_timer.h>
extern int rs_tty_init();
extern int rs_device_init();
extern int rs_tty_init();
extern void rs_softirq_init();
extern void rs_mm_init();
@ -141,10 +142,9 @@ void system_initialize()
io_mfence();
rs_jiffies_init();
io_mfence();
io_mfence();
vfs_init();
rs_device_init();
rs_tty_init();
io_mfence();
// 由于进程管理模块依赖于文件系统,因此必须在文件系统初始化完毕后再初始化进程管理模块

View File

@ -3,7 +3,7 @@ use core::{fmt::Debug, ptr::null};
use alloc::{collections::BTreeMap, string::String, sync::Arc, vec::Vec};
use crate::{
filesystem::vfs::io::SeekFrom,
driver::base::block::SeekFrom,
filesystem::vfs::{
file::{File, FileMode},
ROOT_INODE,

View File

@ -7,7 +7,7 @@ use num_traits::{FromPrimitive, ToPrimitive};
use crate::{
arch::{cpu::cpu_reset, MMArch},
filesystem::vfs::io::SeekFrom,
driver::base::block::SeekFrom,
filesystem::vfs::{
fcntl::FcntlCommand,
file::FileMode,