添加帧缓冲区抽象并实现vesafb的驱动 (#483)

- 添加bootparams对象
- 修正由于bus的driver、device强弱引用关系 不正确从而导致对象被释放的bug
- 添加vesafb的驱动
- 实现framebuffer抽象层
- 为通用帧缓冲区抽象实现sysfs的属性
- 修改设备号DeviceNumber的定义
- 仿照linux,添加initcall,并在第一个内核线程中,调用他们。
This commit is contained in:
LoGin 2024-01-01 11:46:51 +08:00 committed by GitHub
parent e3eb08d4d7
commit c566df451c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 2179 additions and 391 deletions

View File

@ -2,3 +2,4 @@ pub mod apic;
mod c_adapter;
pub mod hpet;
pub mod tsc;
pub mod video;

View File

@ -0,0 +1,9 @@
use system_error::SystemError;
use crate::driver::video::fbdev::vesafb::vesafb_early_init;
/// 在内存管理初始化之前,初始化视频驱动(架构相关)
pub fn arch_video_early_init() -> Result<(), SystemError> {
vesafb_early_init()?;
return Ok(());
}

View File

@ -1,10 +1,13 @@
/// 引入Module
use crate::{
driver::base::{
device::{mkdev, Device, DeviceError, DeviceNumber, IdTable, BLOCKDEVS},
device::{
device_number::{DeviceNumber, Major},
Device, DeviceError, IdTable, BLOCKDEVS,
},
map::{
DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, DEV_MAJOR_DYN_EXT_START,
DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, MINOR_MASK,
DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX,
},
},
kerror,
@ -328,37 +331,40 @@ impl BlockDeviceOps {
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % DEV_MAJOR_HASH_SIZE;
fn major_to_index(major: Major) -> usize {
return (major.data() % DEV_MAJOR_HASH_SIZE as u32) as usize;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
fn find_dynamic_major() -> Result<Major, SystemError> {
let blockdevs = BLOCKDEVS.lock();
// 寻找主设备号为234255的设备
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = blockdevs.get(index) {
for index in ((DEV_MAJOR_DYN_END.data())..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = blockdevs.get(index as usize) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
return Ok(Major::new(index)); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(blockdevss) = blockdevs.get(Self::major_to_index(index)) {
for index in
((DEV_MAJOR_DYN_EXT_END.data() + 1)..(DEV_MAJOR_DYN_EXT_START.data() + 1)).rev()
{
if let Some(blockdevss) = blockdevs.get(Self::major_to_index(Major::new(index as u32)))
{
let mut flag = true;
for item in blockdevss {
if item.device_number().major() == index {
if item.device_number().major() == Major::new(index as u32) {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
return Ok(Major::new(index)); // 返回可用的主设备号
}
}
}
@ -373,7 +379,7 @@ impl BlockDeviceOps {
#[allow(dead_code)]
pub fn register_blockdev_region(
from: DeviceNumber,
count: usize,
count: u32,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_blockdev_region(from, count, name)
@ -386,11 +392,15 @@ impl BlockDeviceOps {
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_blockdev_region(
baseminor: usize,
count: usize,
baseminor: u32,
count: u32,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_blockdev_region(mkdev(0, baseminor), count, name)
Self::__register_blockdev_region(
DeviceNumber::new(Major::UNNAMED_MAJOR, baseminor),
count,
name,
)
}
/// @brief: 注册设备号
@ -400,25 +410,25 @@ impl BlockDeviceOps {
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_blockdev_region(
device_number: DeviceNumber,
minorct: usize,
minorct: u32,
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",
"DEV {} major requested {:?} is greater than the maximum {}\n",
name,
major,
DEV_MAJOR_MAX - 1
DEV_MAJOR_MAX.data() - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
if minorct > DeviceNumber::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);
name, baseminor, baseminor + minorct - 1, 0, DeviceNumber::MINOR_MASK);
}
let blockdev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
let blockdev = DeviceStruct::new(DeviceNumber::new(major, baseminor), minorct, name);
if major == Major::UNNAMED_MAJOR {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
@ -444,7 +454,8 @@ impl BlockDeviceOps {
}
items.insert(insert_index, blockdev);
}
return Ok(mkdev(major, baseminor));
return Ok(DeviceNumber::new(major, baseminor));
}
/// @brief: 注销设备号
@ -454,7 +465,7 @@ impl BlockDeviceOps {
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_blockdev_region(
device_number: DeviceNumber,
minorct: usize,
minorct: u32,
) -> Result<(), SystemError> {
if let Some(items) = BLOCKDEVS
.lock()
@ -478,7 +489,7 @@ impl BlockDeviceOps {
/// @return: none
#[allow(dead_code)]
pub fn bdev_add(_bdev: Arc<dyn BlockDevice>, id_table: IdTable) -> Result<(), DeviceError> {
if Into::<usize>::into(id_table.device_number()) == 0 {
if id_table.device_number().data() == 0 {
kerror!("Device number can't be 0!\n");
}
todo!("bdev_add")

View File

@ -4,10 +4,14 @@ use crate::kerror;
use system_error::SystemError;
use super::{
device::{device_manager, mkdev, Device, DeviceNumber, IdTable, CHARDEVS, DEVMAP},
device::{
device_manager,
device_number::{DeviceNumber, Major},
Device, IdTable, CHARDEVS, DEVMAP,
},
map::{
kobj_map, kobj_unmap, DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END,
DEV_MAJOR_DYN_EXT_START, DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX, MINOR_MASK,
DEV_MAJOR_DYN_EXT_START, DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX,
},
};
@ -41,37 +45,39 @@ impl CharDevOps {
/// @parameter: major: 主设备号
/// @return: 返回下标
#[allow(dead_code)]
fn major_to_index(major: usize) -> usize {
return major % DEV_MAJOR_HASH_SIZE;
fn major_to_index(major: Major) -> usize {
return (major.data() % DEV_MAJOR_HASH_SIZE) as usize;
}
/// @brief: 动态获取主设备号
/// @parameter: None
/// @return: 如果成功,返回主设备号,否则,返回错误码
#[allow(dead_code)]
fn find_dynamic_major() -> Result<usize, SystemError> {
fn find_dynamic_major() -> Result<Major, SystemError> {
let chardevs = CHARDEVS.lock();
// 寻找主设备号为234255的设备
for index in (DEV_MAJOR_DYN_END..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = chardevs.get(index) {
for index in (DEV_MAJOR_DYN_END.data()..DEV_MAJOR_HASH_SIZE).rev() {
if let Some(item) = chardevs.get(index as usize) {
if item.is_empty() {
return Ok(index); // 返回可用的主设备号
return Ok(Major::new(index)); // 返回可用的主设备号
}
}
}
// 寻找主设备号在384511的设备
for index in (DEV_MAJOR_DYN_EXT_END + 1..DEV_MAJOR_DYN_EXT_START + 1).rev() {
if let Some(chardevss) = chardevs.get(Self::major_to_index(index)) {
for index in
((DEV_MAJOR_DYN_EXT_END.data() + 1)..(DEV_MAJOR_DYN_EXT_START.data() + 1)).rev()
{
if let Some(chardevss) = chardevs.get(Self::major_to_index(Major::new(index))) {
let mut flag = true;
for item in chardevss {
if item.device_number().major() == index {
if item.device_number().major().data() == index {
flag = false;
break;
}
}
if flag {
// 如果数组中不存在主设备号等于index的设备
return Ok(index); // 返回可用的主设备号
return Ok(Major::new(index)); // 返回可用的主设备号
}
}
}
@ -86,7 +92,7 @@ impl CharDevOps {
#[allow(dead_code)]
pub fn register_chardev_region(
from: DeviceNumber,
count: usize,
count: u32,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(from, count, name)
@ -99,11 +105,15 @@ impl CharDevOps {
/// @return: 如果注册成功返回否则返回false
#[allow(dead_code)]
pub fn alloc_chardev_region(
baseminor: usize,
count: usize,
baseminor: u32,
count: u32,
name: &'static str,
) -> Result<DeviceNumber, SystemError> {
Self::__register_chardev_region(mkdev(0, baseminor), count, name)
Self::__register_chardev_region(
DeviceNumber::new(Major::UNNAMED_MAJOR, baseminor),
count,
name,
)
}
/// @brief: 注册设备号
@ -113,25 +123,25 @@ impl CharDevOps {
/// @return: 如果注册成功,返回设备号,否则,返回错误码
fn __register_chardev_region(
device_number: DeviceNumber,
minorct: usize,
minorct: u32,
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",
"DEV {} major requested {:?} is greater than the maximum {}\n",
name,
major,
DEV_MAJOR_MAX - 1
DEV_MAJOR_MAX.data() - 1
);
}
if minorct > MINOR_MASK + 1 - baseminor {
if minorct > DeviceNumber::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);
name, baseminor, baseminor + minorct - 1, 0, DeviceNumber::MINOR_MASK);
}
let chardev = DeviceStruct::new(mkdev(major, baseminor), minorct, name);
if major == 0 {
let chardev = DeviceStruct::new(DeviceNumber::new(major, baseminor), minorct, name);
if major == Major::UNNAMED_MAJOR {
// 如果主设备号为0,则自动分配主设备号
major = Self::find_dynamic_major().expect("Find synamic major error.\n");
}
@ -157,7 +167,8 @@ impl CharDevOps {
}
items.insert(insert_index, chardev);
}
return Ok(mkdev(major, baseminor));
return Ok(DeviceNumber::new(major, baseminor));
}
/// @brief: 注销设备号
@ -167,7 +178,7 @@ impl CharDevOps {
/// @return: 如果注销成功,返回(),否则,返回错误码
fn __unregister_chardev_region(
device_number: DeviceNumber,
minorct: usize,
minorct: u32,
) -> Result<(), SystemError> {
if let Some(items) = CHARDEVS
.lock()
@ -195,7 +206,7 @@ impl CharDevOps {
id_table: IdTable,
range: usize,
) -> Result<(), SystemError> {
if Into::<usize>::into(id_table.device_number()) == 0 {
if id_table.device_number().data() == 0 {
kerror!("Device number can't be 0!\n");
}
device_manager().add_device(cdev.clone())?;

View File

@ -85,13 +85,10 @@ impl dyn Class {
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;
}

View File

@ -18,7 +18,7 @@ use super::{
device::{
bus::{subsystem_manager, Bus},
driver::Driver,
Device, DeviceNumber, DeviceType, IdTable,
Device, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
kset::KSet,
@ -124,7 +124,7 @@ impl CpuSubSystemFakeRootDevice {
#[derive(Debug)]
struct InnerCpuSubSystemFakeRootDevice {
parent_kobj: Option<Weak<dyn KObject>>,
bus: Option<Arc<dyn Bus>>,
bus: Option<Weak<dyn Bus>>,
kset: Option<Arc<KSet>>,
name: String,
kern_inode: Option<Arc<KernFSInode>>,
@ -150,13 +150,17 @@ impl Device for CpuSubSystemFakeRootDevice {
}
fn id_table(&self) -> IdTable {
IdTable::new("cpu".to_string(), Some(DeviceNumber::new(0)))
IdTable::new("cpu".to_string(), None)
}
fn set_bus(&self, bus: Option<Arc<dyn Bus>>) {
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
self.inner.write().bus = bus;
}
fn bus(&self) -> Option<Weak<dyn Bus>> {
self.inner.read().bus.clone()
}
fn driver(&self) -> Option<Arc<dyn Driver>> {
None
}

View File

@ -159,11 +159,14 @@ pub trait Bus: Debug + Send + Sync {
/// - `Ok(true)` - 匹配成功
/// - `Ok(false)` - 匹配失败
/// - `Err(_)` - 由于内部错误导致匹配失败
/// - `Err(SystemError::ENOSYS)` - 该总线不支持该操作
fn match_device(
&self,
device: &Arc<dyn Device>,
driver: &Arc<dyn Driver>,
) -> Result<bool, SystemError>;
_device: &Arc<dyn Device>,
_driver: &Arc<dyn Driver>,
) -> Result<bool, SystemError> {
return Err(SystemError::ENOSYS);
}
fn subsystem(&self) -> &SubSysPrivate;
@ -188,13 +191,10 @@ impl dyn Bus {
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;
}
@ -221,13 +221,10 @@ impl dyn Bus {
let subsys = self.subsystem();
let guard = subsys.drivers();
for drv in guard.iter() {
let drv = drv.upgrade();
if let Some(drv) = drv {
if matcher.match_driver(&drv, data) {
return Some(drv.clone());
}
}
}
return None;
}
@ -265,7 +262,7 @@ impl BusManager {
///
/// - `dev` - 要被添加的设备
pub fn add_device(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
let bus = dev.bus();
let bus = dev.bus().map(|bus| bus.upgrade()).flatten();
if let Some(bus) = bus {
device_manager().add_groups(dev, bus.dev_groups())?;
@ -295,7 +292,11 @@ impl BusManager {
///
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?fi=bus_add_driver#590
pub fn add_driver(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> {
let bus = driver.bus().ok_or(SystemError::EINVAL)?;
let bus = driver
.bus()
.map(|bus| bus.upgrade())
.flatten()
.ok_or(SystemError::EINVAL)?;
kdebug!("bus '{}' add driver '{}'", bus.name(), driver.name());
driver.set_kobj_type(Some(&BusDriverKType));
@ -435,11 +436,8 @@ impl BusManager {
#[allow(dead_code)]
pub fn rescan_devices(&self, bus: &Arc<dyn Bus>) -> Result<(), SystemError> {
for dev in bus.subsystem().devices().iter() {
let dev = dev.upgrade();
if let Some(dev) = dev {
rescan_devices_helper(dev)?;
}
}
return Ok(());
}
@ -447,7 +445,7 @@ impl BusManager {
///
/// Automatically probe for a driver if the bus allows it.
pub fn probe_device(&self, dev: &Arc<dyn Device>) {
let bus = dev.bus();
let bus = dev.bus().map(|bus| bus.upgrade()).flatten();
if bus.is_none() {
return;
}
@ -490,9 +488,12 @@ impl BusManager {
}
/// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?r=&mo=5649&fi=241#684
fn rescan_devices_helper(dev: Arc<dyn Device>) -> Result<(), SystemError> {
fn rescan_devices_helper(dev: &Arc<dyn Device>) -> Result<(), SystemError> {
if dev.driver().is_none() {
let need_parent_lock = dev.bus().map(|bus| bus.need_parent_lock()).unwrap_or(false);
let need_parent_lock = dev
.bus()
.map(|bus| bus.upgrade().unwrap().need_parent_lock())
.unwrap_or(false);
if unlikely(need_parent_lock) {
// todo: lock device parent
unimplemented!()
@ -580,6 +581,7 @@ pub fn bus_add_device(dev: &Arc<dyn Device>) -> Result<(), SystemError> {
///
/// 参考: https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/bus.c?fi=bus_probe_device#478
pub fn bus_probe_device(dev: &Arc<dyn Device>) {
kinfo!("bus_probe_device: dev: {:?}", dev.name());
bus_manager().probe_device(dev);
}
@ -613,7 +615,7 @@ impl Attribute for BusAttrDriversProbe {
let device = bus.find_device_by_name(name).ok_or(SystemError::ENODEV)?;
if rescan_devices_helper(device).is_ok() {
if rescan_devices_helper(&device).is_ok() {
return Ok(buf.len());
}
@ -752,7 +754,11 @@ impl Attribute for DriverAttrUnbind {
SystemError::EOPNOTSUPP_OR_ENOTSUP
})?;
let bus = driver.bus().ok_or(SystemError::ENODEV)?;
let bus = driver
.bus()
.map(|bus| bus.upgrade())
.flatten()
.ok_or(SystemError::ENODEV)?;
let s = CStr::from_bytes_with_nul(buf)
.map_err(|_| SystemError::EINVAL)?
@ -798,7 +804,11 @@ impl Attribute for DriverAttrBind {
SystemError::EOPNOTSUPP_OR_ENOTSUP
})?;
let bus = driver.bus().ok_or(SystemError::ENODEV)?;
let bus = driver
.bus()
.map(|bus| bus.upgrade())
.flatten()
.ok_or(SystemError::ENODEV)?;
let device = bus
.find_device_by_name(
CStr::from_bytes_with_nul(buf)

View File

@ -63,6 +63,8 @@ impl DeviceManager {
return Ok(false);
}
kwarn!("do_device_attach: dev: '{}'", dev.name());
let mut do_async = false;
let mut r = Ok(false);
@ -78,15 +80,22 @@ impl DeviceManager {
return Ok(false);
}
} else {
let bus = dev.bus().ok_or(SystemError::EINVAL)?;
let bus = dev
.bus()
.map(|bus| bus.upgrade())
.flatten()
.ok_or(SystemError::EINVAL)?;
let mut data = DeviceAttachData::new(dev.clone(), allow_async, false);
let mut flag = true;
let mut flag = false;
for driver in bus.subsystem().drivers().iter() {
if let Some(driver) = driver.upgrade() {
let r = self.do_device_attach_driver(&driver, &mut data);
if unlikely(r.is_err()) {
flag = false;
break;
} else {
if r.unwrap() == true {
flag = true;
break;
}
}
}
@ -116,13 +125,52 @@ impl DeviceManager {
return r;
}
/// 匹配设备和驱动
///
/// ## 参数
///
/// - `driver`: 驱动
/// - `data`: 匹配数据
///
/// ## 返回
///
/// - Ok(true): 匹配成功
/// - Ok(false): 没有匹配成功
/// - Err(SystemError): 匹配过程中出现意外错误,没有匹配成功
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/dd.c#899
fn do_device_attach_driver(
&self,
_driver: &Arc<dyn Driver>,
_data: &mut DeviceAttachData,
) -> Result<(), SystemError> {
todo!("do_device_attach_driver")
driver: &Arc<dyn Driver>,
data: &mut DeviceAttachData,
) -> Result<bool, SystemError> {
if let Some(bus) = driver.bus().map(|bus| bus.upgrade()).flatten() {
let r = bus.match_device(&data.dev, driver);
if let Err(e) = r {
// 如果不是ENOSYS则总线出错
if e != SystemError::ENOSYS {
kdebug!(
"do_device_attach_driver: bus.match_device() failed, dev: '{}', err: {:?}",
data.dev.name(),
e
);
return Err(e);
}
} else {
if r.unwrap() == false {
return Ok(false);
}
}
}
let async_allowed = driver.allows_async_probing();
if data.check_async && async_allowed != data.want_async {
return Ok(false);
}
return driver_manager()
.probe_device(driver, &data.dev)
.map(|_| true);
}
/// 检查设备是否绑定到驱动程序
@ -162,7 +210,7 @@ impl DeviceManager {
driver_manager().driver_bound(dev);
return Err(e);
} else {
if let Some(bus) = dev.bus() {
if let Some(bus) = dev.bus().map(|bus| bus.upgrade()).flatten() {
bus.subsystem().bus_notifier().call_chain(
BusNotifyEvent::DriverNotBound,
Some(dev),
@ -233,15 +281,17 @@ impl DriverManager {
/// 这个函数会遍历驱动现有的全部设备,然后尝试把他们匹配。
/// 一旦有一个设备匹配成功就会返回并且设备的driver字段会被设置。
pub fn driver_attach(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> {
let bus = driver.bus().ok_or(SystemError::EINVAL)?;
let bus = driver
.bus()
.map(|bus| bus.upgrade())
.flatten()
.ok_or(SystemError::EINVAL)?;
for dev in bus.subsystem().devices().iter() {
if let Some(dev) = dev.upgrade() {
if self.do_driver_attach(&dev, &driver) {
// 匹配成功
return Ok(());
}
}
}
return Ok(());
}
@ -274,7 +324,12 @@ impl DriverManager {
driver: &Arc<dyn Driver>,
device: &Arc<dyn Device>,
) -> Result<bool, SystemError> {
return driver.bus().unwrap().match_device(device, driver);
return driver
.bus()
.map(|bus| bus.upgrade())
.flatten()
.unwrap()
.match_device(device, driver);
}
/// 尝试把设备和驱动绑定在一起
@ -327,7 +382,7 @@ impl DriverManager {
};
let sysfs_failed = || {
if let Some(bus) = device.bus() {
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
bus.subsystem().bus_notifier().call_chain(
BusNotifyEvent::DriverNotBound,
Some(device),
@ -385,7 +440,7 @@ impl DriverManager {
e
})?;
// 我们假设所有的设备都有sync_state这个属性。如果没有的话也创建属性文件。
// 我们假设所有的设备都有 sync_state 这个属性。如果没有的话,也创建属性文件。
device_manager()
.create_file(device, &DeviceAttrStateSynced)
.map_err(|e| {
@ -410,7 +465,7 @@ impl DriverManager {
fn add_to_sysfs(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
let driver = device.driver().ok_or(SystemError::EINVAL)?;
if let Some(bus) = device.bus() {
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
bus.subsystem().bus_notifier().call_chain(
BusNotifyEvent::BindDriver,
Some(&device),
@ -455,7 +510,11 @@ impl DriverManager {
device: &Arc<dyn Device>,
driver: &Arc<dyn Driver>,
) -> Result<(), SystemError> {
let bus = device.bus().ok_or(SystemError::EINVAL)?;
let bus = device
.bus()
.map(|bus| bus.upgrade())
.flatten()
.ok_or(SystemError::EINVAL)?;
let r = bus.probe(device);
if r == Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) {
kerror!(
@ -505,7 +564,7 @@ impl DriverManager {
let driver = device.driver().unwrap();
driver.add_device(device.clone());
if let Some(bus) = device.bus() {
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
bus.subsystem().bus_notifier().call_chain(
BusNotifyEvent::BoundDriver,
Some(device),

View File

@ -0,0 +1,60 @@
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Major(u32);
impl Major {
// 常量定义参考:
//
// https://code.dragonos.org.cn/xref/linux-6.1.9/include/uapi/linux/major.h
/// 未命名的主设备
pub const UNNAMED_MAJOR: Self = Self::new(0);
/// /dev/fb* framebuffers
pub const FB_MAJOR: Self = Self::new(29);
pub const fn new(x: u32) -> Self {
Major(x)
}
pub const fn data(&self) -> u32 {
self.0
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DeviceNumber {
data: u32,
}
impl DeviceNumber {
pub const MINOR_BITS: u32 = 20;
pub const MINOR_MASK: u32 = 1 << Self::MINOR_BITS - 1;
pub const fn new(major: Major, minor: u32) -> Self {
Self {
data: (major.data() << Self::MINOR_BITS) | minor,
}
}
pub const fn major(&self) -> Major {
Major::new(self.data >> Self::MINOR_BITS)
}
pub const fn minor(&self) -> u32 {
self.data & 0xfffff
}
pub const fn data(&self) -> u32 {
self.data
}
}
impl Default for DeviceNumber {
fn default() -> Self {
Self::new(Major::UNNAMED_MAJOR, 0)
}
}
impl From<u32> for DeviceNumber {
fn from(x: u32) -> Self {
Self { data: x }
}
}

View File

@ -6,7 +6,10 @@ use crate::{
driver::base::kobject::KObject,
filesystem::sysfs::{sysfs_instance, Attribute, AttributeGroup},
};
use alloc::{sync::Arc, vec::Vec};
use alloc::{
sync::{Arc, Weak},
vec::Vec,
};
use core::fmt::Debug;
use system_error::SystemError;
@ -86,11 +89,11 @@ pub trait Driver: Sync + Send + Debug + KObject {
false
}
fn bus(&self) -> Option<Arc<dyn Bus>> {
fn bus(&self) -> Option<Weak<dyn Bus>> {
None
}
fn set_bus(&self, bus: Option<Arc<dyn Bus>>);
fn set_bus(&self, bus: Option<Weak<dyn Bus>>);
fn groups(&self) -> &'static [&'static dyn AttributeGroup] {
&[]
@ -171,7 +174,11 @@ impl DriverManager {
///
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/driver.c#222
pub fn register(&self, driver: Arc<dyn Driver>) -> Result<(), SystemError> {
let bus = driver.bus().ok_or_else(|| {
let bus = driver
.bus()
.map(|bus| bus.upgrade())
.flatten()
.ok_or_else(|| {
kerror!(
"DriverManager::register() failed: driver.bus() is None. Driver: '{:?}'",
driver.name()

View File

@ -24,6 +24,7 @@ use system_error::SystemError;
use self::{
bus::{bus_add_device, bus_probe_device, Bus},
device_number::{DeviceNumber, Major},
driver::Driver,
};
@ -36,6 +37,7 @@ use super::{
pub mod bus;
pub mod dd;
pub mod device_number;
pub mod driver;
pub mod init;
@ -143,14 +145,16 @@ pub trait Device: KObject {
}
/// 获取当前设备所属的总线
fn bus(&self) -> Option<Arc<dyn Bus>> {
fn bus(&self) -> Option<Weak<dyn Bus>> {
return None;
}
/// 设置当前设备所属的总线
///
/// 一定要传入Arc因为bus的subsysprivate里面存储的是Device的Weak指针
fn set_bus(&self, bus: Option<Arc<dyn Bus>>);
/// 一定要传入Arc因为bus的subsysprivate里面存储的是Device的Arc指针
///
/// 注意,如果实现了当前方法,那么必须实现`bus()`方法
fn set_bus(&self, bus: Option<Weak<dyn Bus>>);
/// 获取当前设备所属的类
fn class(&self) -> Option<Arc<dyn Class>> {
@ -158,6 +162,8 @@ pub trait Device: KObject {
}
/// 设置当前设备所属的类
///
/// 注意,如果实现了当前方法,那么必须实现`class()`方法
fn set_class(&self, class: Option<Arc<dyn Class>>);
/// 返回已经与当前设备匹配好的驱动程序
@ -221,62 +227,6 @@ impl DevicePrivateData {
}
}
int_like!(DeviceNumber, usize);
impl Default for DeviceNumber {
fn default() -> Self {
DeviceNumber(0)
}
}
impl From<usize> for DeviceNumber {
fn from(dev_t: usize) -> Self {
DeviceNumber(dev_t)
}
}
impl Into<usize> for DeviceNumber {
fn into(self) -> usize {
self.0
}
}
impl core::hash::Hash for DeviceNumber {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl DeviceNumber {
/// @brief: 获取主设备号
/// @parameter: none
/// @return: 主设备号
pub fn major(&self) -> usize {
(self.0 >> 8) & 0xffffff
}
/// @brief: 获取次设备号
/// @parameter: none
/// @return: 次设备号
pub fn minor(&self) -> usize {
self.0 & 0xff
}
#[inline]
#[allow(dead_code)]
pub fn from_major_minor(major: usize, minor: usize) -> usize {
((major & 0xffffff) << 8) | (minor & 0xff)
}
}
/// @brief: 根据主次设备号创建设备号实例
/// @parameter: major: 主设备号
/// minor: 次设备号
/// @return: 设备号实例
pub fn mkdev(major: usize, minor: usize) -> DeviceNumber {
DeviceNumber(((major & 0xfff) << 20) | (minor & 0xfffff))
}
/// @brief: 设备类型
#[allow(dead_code)]
#[derive(Debug, Eq, PartialEq)]
@ -317,12 +267,13 @@ impl IdTable {
if self.id.is_none() {
return self.basename.clone();
} else {
return format!("{}:{}", self.basename, self.id.unwrap().data());
let id = self.id.unwrap();
return format!("{}:{}", id.major().data(), id.minor());
}
}
pub fn device_number(&self) -> DeviceNumber {
return self.id.unwrap_or(DeviceNumber::new(0));
return self.id.unwrap_or(DeviceNumber::default());
}
}
@ -460,16 +411,10 @@ impl DeviceManager {
}
pub fn register(&self, device: Arc<dyn Device>) -> Result<(), SystemError> {
self.device_initialize(&device);
self.device_default_initialize(&device);
return self.add_device(device);
}
/// device_initialize - init device structure.
pub fn device_initialize(&self, device: &Arc<dyn Device>) {
device.set_kset(Some(sys_devices_kset()));
device.set_kobj_type(Some(&DeviceKObjType));
}
/// @brief: 添加设备
/// @parameter id_table: 总线标识符,用于唯一标识该总线
/// @parameter dev: 设备实例
@ -514,14 +459,14 @@ impl DeviceManager {
bus_add_device(&device)?;
if device.id_table().device_number().major() != 0 {
if device.id_table().device_number().major() != Major::UNNAMED_MAJOR {
self.create_file(&device, &DeviceAttrDev)?;
self.create_sys_dev_entry(&device)?;
}
// 通知客户端有关设备添加的信息。此调用必须在 dpm_sysfs_add() 之后且在 kobject_uevent() 之前执行。
if let Some(bus) = device.bus() {
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
bus.subsystem().bus_notifier().call_chain(
bus::BusNotifyEvent::AddDevice,
Some(&device),
@ -585,7 +530,7 @@ impl DeviceManager {
// subsystems can specify a default root directory for their devices
if current_parent.is_none() {
if let Some(bus) = device.bus() {
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
if let Some(root) = bus.root_device().map(|x| x.upgrade()).flatten() {
return Ok(Some(root as Arc<dyn KObject>));
}
@ -627,6 +572,7 @@ impl DeviceManager {
software_node_notify(dev);
}
// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/core.c#3224
fn add_class_symlinks(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
let class = dev.class();
if class.is_none() {
@ -635,6 +581,10 @@ impl DeviceManager {
// 定义错误处理函数,用于在添加符号链接失败时,移除已经添加的符号链接
let err_remove_device = |dev_kobj: &Arc<dyn KObject>| {
sysfs_instance().remove_link(dev_kobj, "device".to_string());
};
let err_remove_subsystem = |dev_kobj: &Arc<dyn KObject>| {
sysfs_instance().remove_link(dev_kobj, "subsystem".to_string());
};
@ -645,11 +595,20 @@ impl DeviceManager {
sysfs_instance().create_link(Some(&dev_kobj), &subsys_kobj, "subsystem".to_string())?;
// todo: 这里需要处理class的parent逻辑, 添加device链接
// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/core.c#3245
if let Some(parent) = dev.parent().map(|x| x.upgrade()).flatten() {
let parent_kobj = parent.clone() as Arc<dyn KObject>;
sysfs_instance()
.create_link(Some(&dev_kobj), &&parent_kobj, "device".to_string())
.map_err(|e| {
err_remove_subsystem(&dev_kobj);
e
})?;
}
sysfs_instance()
.create_link(Some(&subsys_kobj), &dev_kobj, dev.name())
.map_err(|e| {
err_remove_device(&dev_kobj);
err_remove_subsystem(&dev_kobj);
e
})?;
@ -776,7 +735,7 @@ impl DeviceManager {
let target_kobj = self.device_to_dev_kobj(dev);
let name = dev.id_table().name();
let current_kobj = dev.clone() as Arc<dyn KObject>;
return sysfs_instance().create_link(Some(&current_kobj), &target_kobj, name);
return sysfs_instance().create_link(Some(&target_kobj), &current_kobj, name);
}
/// Delete symlink for device in `/sys/dev` or `/sys/class/<class_name>`
@ -810,6 +769,7 @@ impl DeviceManager {
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_initialize#2976
pub fn device_default_initialize(&self, dev: &Arc<dyn Device>) {
dev.set_kset(Some(sys_devices_kset()));
dev.set_kobj_type(Some(&DeviceKObjType));
return;
}
@ -874,7 +834,11 @@ impl Attribute for DeviceAttrDev {
})?;
let device_number = dev.id_table().device_number();
let s = format!("{}:{}\n", device_number.major(), device_number.minor());
let s = format!(
"{}:{}\n",
device_number.major().data(),
device_number.minor()
);
return sysfs_emit_str(buf, &s);
}

View File

@ -1,6 +1,4 @@
use crate::driver::tty::tty_device::tty_init;
use system_error::SystemError;
use unified_init::{define_public_unified_initializer_slice, unified_init};
use super::{
class::classes_init,
@ -11,8 +9,6 @@ use super::{
platform::platform_bus_init,
};
define_public_unified_initializer_slice!(SUBSYSTEM_INITIALIZER_SLICE);
pub(super) fn driver_init() -> Result<(), SystemError> {
devices_init()?;
buses_init()?;
@ -21,7 +17,7 @@ pub(super) fn driver_init() -> Result<(), SystemError> {
hypervisor_init()?;
platform_bus_init()?;
cpu_device_manager().init()?;
subsystem_init()?;
// 至此,已完成设备驱动模型的初始化
// 接下来,初始化设备
actual_device_init()?;
@ -29,12 +25,6 @@ pub(super) fn driver_init() -> Result<(), SystemError> {
}
fn actual_device_init() -> Result<(), SystemError> {
tty_init()?;
return Ok(());
}
fn subsystem_init() -> Result<(), SystemError> {
unified_init!(SUBSYSTEM_INITIALIZER_SLICE);
// 应当使用unified_init来初始化
return Ok(());
}

View File

@ -109,11 +109,10 @@ impl Deref for LockedKObjectState {
}
}
pub trait KObjectAttribute: Attribute {
fn support(&self) -> SysFSOpsSupport;
fn show(&self, kobj: &dyn KObject, buf: &mut [u8]) -> Result<usize, SystemError>;
fn store(&self, kobj: &dyn KObject, buf: &[u8]) -> Result<usize, SystemError>;
impl Default for LockedKObjectState {
fn default() -> Self {
LockedKObjectState::new(None)
}
}
#[derive(Debug)]

View File

@ -1,22 +1,21 @@
use core::ops::{Deref, DerefMut};
use super::{
device::{mkdev, DeviceNumber},
device::device_number::{DeviceNumber, Major},
kobject::KObject,
};
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
const KOBJMAP_HASH_SIZE: usize = 255;
pub(crate) const DEV_MAJOR_HASH_SIZE: usize = 255;
pub(crate) const DEV_MAJOR_MAX: usize = 512;
pub(crate) const MINOR_BITS: usize = 20;
pub(crate) const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
pub(crate) const DEV_MAJOR_HASH_SIZE: u32 = 255;
pub(crate) const DEV_MAJOR_MAX: Major = Major::new(512);
/* Marks the bottom of the first segment of free char majors */
pub(crate) const DEV_MAJOR_DYN_END: usize = 234;
pub(crate) const DEV_MAJOR_DYN_END: Major = Major::new(234);
/* Marks the top and bottom of the second segment of free char majors */
pub(crate) const DEV_MAJOR_DYN_EXT_START: usize = 511;
pub(crate) const DEV_MAJOR_DYN_EXT_END: usize = 384;
pub(crate) const DEV_MAJOR_DYN_EXT_START: Major = Major::new(511);
pub(crate) const DEV_MAJOR_DYN_EXT_END: Major = Major::new(384);
/// @brief: 字符设备与块设备管理结构体
#[derive(Debug, Clone)]
@ -63,10 +62,15 @@ pub fn kobj_map(
range: usize,
data: Arc<dyn KObject>,
) {
if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
if let Some(map) = domain
.0
.lock()
.0
.get_mut((dev_t.major().data() % 255) as usize)
{
for i in 0..range {
map.insert(
mkdev(dev_t.major(), dev_t.minor() + i),
DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32),
Probe::new(data.clone()),
);
}
@ -79,9 +83,14 @@ pub fn kobj_map(
/// range: 次设备号范围
/// @return: none
pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
if let Some(map) = domain
.0
.lock()
.0
.get_mut((dev_t.major().data() % 255) as usize)
{
for i in 0..range {
let rm_dev_t = &DeviceNumber::new(Into::<usize>::into(dev_t) + i);
let rm_dev_t = &DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32);
match map.get(rm_dev_t) {
Some(_) => {
map.remove(rm_dev_t);
@ -98,7 +107,7 @@ pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize)
/// @return: 查找成功返回设备实例否则返回None
#[allow(dead_code)]
pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
if let Some(map) = domain.0.lock().0.get(dev_t.major() % 255) {
if let Some(map) = domain.0.lock().0.get((dev_t.major().data() % 255) as usize) {
match map.get(&dev_t) {
Some(value) => {
return Some(value.0.clone());
@ -133,7 +142,7 @@ pub struct DevsMap(Vec<Vec<DeviceStruct>>);
impl Default for DevsMap {
fn default() -> Self {
DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE])
DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE as usize])
}
}
@ -156,7 +165,7 @@ impl DerefMut for DevsMap {
#[derive(Debug, Clone)]
pub struct DeviceStruct {
dev_t: DeviceNumber, //起始设备号
minorct: usize, // 次设备号数量
minorct: u32, // 次设备号数量
name: &'static str, //字符设备名
}
@ -169,7 +178,7 @@ impl DeviceStruct {
/// @return: 实例
///
#[allow(dead_code)]
pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self {
pub fn new(dev_t: DeviceNumber, minorct: u32, name: &'static str) -> Self {
Self {
dev_t,
minorct,
@ -191,7 +200,7 @@ impl DeviceStruct {
/// @return: 起始设备号
///
#[allow(dead_code)]
pub fn base_minor(&self) -> usize {
pub fn base_minor(&self) -> u32 {
self.dev_t.minor()
}
@ -199,7 +208,7 @@ impl DeviceStruct {
/// @parameter: None
/// @return: 次设备号数量
#[allow(dead_code)]
pub fn minorct(&self) -> usize {
pub fn minorct(&self) -> u32 {
self.minorct
}
}

View File

@ -3,7 +3,7 @@ use self::{platform_device::PlatformBusDevice, subsys::PlatformBus};
use super::{
device::{
bus::{bus_register, Bus, BusState},
device_unregister, sys_devices_kset, DeviceNumber, DevicePrivateData, IdTable,
device_unregister, sys_devices_kset, DevicePrivateData, IdTable,
},
kobject::KObject,
};
@ -77,7 +77,7 @@ impl CompatibleTable {
pub fn platform_bus_init() -> Result<(), SystemError> {
let platform_device: Arc<PlatformBusDevice> = PlatformBusDevice::new(
DevicePrivateData::new(
IdTable::new("platform".to_string(), Some(DeviceNumber::new(0))),
IdTable::new("platform".to_string(), None),
BusState::NotInitialized.into(),
),
Some(Arc::downgrade(&(sys_devices_kset() as Arc<dyn KObject>))),

View File

@ -11,7 +11,7 @@ use crate::{
bus::{Bus, BusState},
device_manager,
driver::Driver,
Device, DeviceNumber, DevicePrivateData, DeviceType, IdTable,
Device, DevicePrivateData, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
kset::KSet,
@ -44,8 +44,8 @@ pub const PLATFORM_DEVID_AUTO: i32 = -2;
///
/// ## 注意
///
/// 应当在所有实现这个trait的结构体上方添加 `#[cast_to([sync] PlatformDriver)]`
/// 否则运行时将报错“该对象不是PlatformDriver
/// 应当在所有实现这个trait的结构体上方添加 `#[cast_to([sync] PlatformDevice)]`
/// 否则运行时将报错“该对象不是PlatformDevice
pub trait PlatformDevice: Device {
fn pdev_name(&self) -> &str;
/// 返回平台设备id以及这个id是否是自动生成的
@ -85,7 +85,7 @@ impl PlatformDeviceManager {
)));
}
pdev.set_bus(Some(platform_bus() as Arc<dyn Bus>));
pdev.set_bus(Some(Arc::downgrade(&(platform_bus() as Arc<dyn Bus>))));
let id = pdev.pdev_id().0;
match id {
@ -195,7 +195,7 @@ pub struct InnerPlatformBusDevice {
kernfs_inode: Option<Arc<KernFSInode>>,
/// 当前设备挂载到的总线
bus: Option<Arc<dyn Bus>>,
bus: Option<Weak<dyn Bus>>,
/// 当前设备已经匹配的驱动
driver: Option<Weak<dyn Driver>>,
@ -286,16 +286,15 @@ impl Device for PlatformBusDevice {
}
#[inline]
#[allow(dead_code)]
fn id_table(&self) -> IdTable {
IdTable::new("platform".to_string(), Some(DeviceNumber::new(0)))
IdTable::new("platform".to_string(), None)
}
fn bus(&self) -> Option<Arc<dyn Bus>> {
fn bus(&self) -> Option<Weak<dyn Bus>> {
self.inner.lock().bus.clone()
}
fn set_bus(&self, bus: Option<Arc<dyn Bus>>) {
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
self.inner.lock().bus = bus;
}

View File

@ -19,7 +19,7 @@ use super::{platform_bus, platform_device::PlatformDevice};
pub trait PlatformDriver: Driver {
/// 检测设备是否能绑定到这个驱动
///
/// 如果能则把设备的driver指向这个驱动。
/// 如果能则把设备的driver字段指向这个驱动。
/// 请注意这个函数不应该把driver加入驱动的devices列表相关工作会在外部的函数里面处理。
fn probe(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError>;
fn remove(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError>;
@ -41,7 +41,7 @@ impl PlatformDriverManager {
///
/// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/platform.c?fi=__platform_driver_register#861
pub fn register(&self, driver: Arc<dyn PlatformDriver>) -> Result<(), SystemError> {
driver.set_bus(Some(platform_bus() as Arc<dyn Bus>));
driver.set_bus(Some(Arc::downgrade(&(platform_bus() as Arc<dyn Bus>))));
return driver_manager().register(driver as Arc<dyn Driver>);
}

View File

@ -37,9 +37,9 @@ pub struct SubSysPrivate {
class: SpinLock<Option<Weak<dyn Class>>>,
drivers_autoprobe: AtomicBool,
/// 当前总线上的所有设备
devices: RwLock<Vec<Weak<dyn Device>>>,
devices: RwLock<Vec<Arc<dyn Device>>>,
/// 当前总线上的所有驱动
drivers: RwLock<Vec<Weak<dyn Driver>>>,
drivers: RwLock<Vec<Arc<dyn Driver>>>,
interfaces: &'static [&'static dyn SubSysInterface],
bus_notifier: AtomicNotifierChain<BusNotifyEvent, Arc<dyn Device>>,
}
@ -106,11 +106,11 @@ impl SubSysPrivate {
*self.class.lock() = class;
}
pub fn devices(&self) -> RwLockReadGuard<Vec<Weak<dyn Device>>> {
pub fn devices(&self) -> RwLockReadGuard<Vec<Arc<dyn Device>>> {
return self.devices.read();
}
pub fn drivers(&self) -> RwLockReadGuard<Vec<Weak<dyn Driver>>> {
pub fn drivers(&self) -> RwLockReadGuard<Vec<Arc<dyn Driver>>> {
return self.drivers.read();
}
@ -155,18 +155,16 @@ impl SubSysPrivate {
pub fn add_driver_to_vec(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> {
let mut drivers = self.drivers.write();
let driver_weak = Arc::downgrade(driver);
if drivers.iter().any(|d| d.ptr_eq(&driver_weak)) {
if drivers.iter().any(|d| Arc::ptr_eq(d, driver)) {
return Err(SystemError::EEXIST);
}
drivers.push(driver_weak);
drivers.push(driver.clone());
return Ok(());
}
pub fn remove_driver_from_vec(&self, driver: &Arc<dyn Driver>) {
let mut drivers = self.drivers.write();
let driver_weak = Arc::downgrade(driver);
let index = drivers.iter().position(|d| d.ptr_eq(&driver_weak));
let index = drivers.iter().position(|d| Arc::ptr_eq(d, driver));
if let Some(index) = index {
drivers.remove(index);
}
@ -174,19 +172,17 @@ impl SubSysPrivate {
pub fn add_device_to_vec(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
let mut devices = self.devices.write();
let device_weak = Arc::downgrade(device);
if devices.iter().any(|d| d.ptr_eq(&device_weak)) {
if devices.iter().any(|d| Arc::ptr_eq(d, device)) {
return Err(SystemError::EEXIST);
}
devices.push(device_weak);
devices.push(device.clone());
return Ok(());
}
#[allow(dead_code)]
pub fn remove_device_from_vec(&self, device: &Arc<dyn Device>) {
let mut devices = self.devices.write();
let device_weak = Arc::downgrade(device);
let index = devices.iter().position(|d| d.ptr_eq(&device_weak));
let index = devices.iter().position(|d| Arc::ptr_eq(d, device));
if let Some(index) = index {
devices.remove(index);
}

View File

@ -499,11 +499,11 @@ impl Device for LockedAhciDisk {
todo!()
}
fn bus(&self) -> Option<Arc<dyn Bus>> {
fn bus(&self) -> Option<Weak<dyn Bus>> {
todo!("LockedAhciDisk::bus()")
}
fn set_bus(&self, _bus: Option<Arc<dyn Bus>>) {
fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
todo!("LockedAhciDisk::set_bus()")
}

View File

@ -13,7 +13,10 @@ use crate::{
net::{generate_iface_id, NET_DRIVERS},
time::Instant,
};
use alloc::{string::String, sync::Arc};
use alloc::{
string::String,
sync::{Arc, Weak},
};
use core::{
cell::UnsafeCell,
fmt::Debug,
@ -218,11 +221,11 @@ impl Driver for E1000EInterface {
todo!()
}
fn bus(&self) -> Option<Arc<dyn Bus>> {
fn bus(&self) -> Option<Weak<dyn Bus>> {
todo!()
}
fn set_bus(&self, _bus: Option<Arc<dyn Bus>>) {
fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
todo!()
}
}

View File

@ -4,7 +4,10 @@ use core::{
ops::{Deref, DerefMut},
};
use alloc::{string::String, sync::Arc};
use alloc::{
string::String,
sync::{Arc, Weak},
};
use smoltcp::{phy, wire};
use virtio_drivers::{device::net::VirtIONet, transport::Transport};
@ -261,11 +264,11 @@ impl<T: Transport + 'static> Driver for VirtioInterface<T> {
todo!()
}
fn bus(&self) -> Option<Arc<dyn Bus>> {
fn bus(&self) -> Option<Weak<dyn Bus>> {
todo!()
}
fn set_bus(&self, _bus: Option<Arc<dyn Bus>>) {
fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
todo!()
}
}

View File

@ -3,7 +3,7 @@ use core::{fmt::Debug, sync::atomic::AtomicU32};
use alloc::sync::Arc;
use system_error::SystemError;
use crate::{driver::base::device::DeviceNumber, mm::VirtAddr};
use crate::{driver::base::device::device_number::DeviceNumber, mm::VirtAddr};
use self::serial8250::serial8250_manager;

View File

@ -15,8 +15,8 @@ use crate::{
base::{
class::Class,
device::{
bus::Bus, device_manager, driver::Driver, Device, DeviceKObjType, DeviceNumber,
DeviceState, DeviceType, IdTable,
bus::Bus, device_manager, device_number::DeviceNumber, driver::Driver, Device,
DeviceKObjType, DeviceState, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
kset::KSet,
@ -94,6 +94,9 @@ impl Serial8250Manager {
// todo: 把端口绑定到isa_dev、 isa_driver上
self.register_ports(&serial8250_isa_driver, &serial8250_isa_dev);
serial8250_isa_dev.set_driver(Some(Arc::downgrade(
&(serial8250_isa_driver.clone() as Arc<dyn Driver>),
)));
// todo: 把驱动注册到uart层、tty层
uart_manager().register_driver(&(serial8250_isa_driver.clone() as Arc<dyn UartDriver>))?;
@ -216,11 +219,11 @@ impl Device for Serial8250ISADevices {
fn is_dead(&self) -> bool {
false
}
fn bus(&self) -> Option<Arc<dyn Bus>> {
fn bus(&self) -> Option<Weak<dyn Bus>> {
self.inner.read().bus.clone()
}
fn set_bus(&self, bus: Option<Arc<dyn Bus>>) {
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
self.inner.write().bus = bus;
}
@ -229,7 +232,7 @@ impl Device for Serial8250ISADevices {
}
fn id_table(&self) -> IdTable {
return IdTable::new(self.name.to_string(), Some(DeviceNumber::new(0)));
return IdTable::new(self.name.to_string(), None);
}
fn driver(&self) -> Option<Arc<dyn Driver>> {
@ -291,7 +294,7 @@ impl KObject for Serial8250ISADevices {
}
fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
todo!()
// 不允许修改
}
fn name(&self) -> String {
@ -319,7 +322,7 @@ struct InnerSerial8250ISADevices {
kset: Option<Arc<KSet>>,
parent_kobj: Option<Weak<dyn KObject>>,
/// 当前设备所述的总线
bus: Option<Arc<dyn Bus>>,
bus: Option<Weak<dyn Bus>>,
inode: Option<Arc<KernFSInode>>,
driver: Option<Weak<dyn Driver>>,
device_state: DeviceState,
@ -351,7 +354,7 @@ enum Serial8250PlatformDeviceID {
#[derive(Debug)]
struct InnerSerial8250ISADriver {
bus: Option<Arc<dyn Bus>>,
bus: Option<Weak<dyn Bus>>,
kobj_type: Option<&'static dyn KObjType>,
kset: Option<Arc<KSet>>,
parent_kobj: Option<Weak<dyn KObject>>,
@ -486,11 +489,11 @@ impl Driver for Serial8250ISADriver {
inner.devices.retain(|d| !Arc::ptr_eq(d, device));
}
fn bus(&self) -> Option<Arc<dyn Bus>> {
fn bus(&self) -> Option<Weak<dyn Bus>> {
self.inner.read().bus.clone()
}
fn set_bus(&self, bus: Option<Arc<dyn Bus>>) {
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
self.inner.write().bus = bus;
}
}

View File

@ -4,6 +4,7 @@ use alloc::{
sync::{Arc, Weak},
};
use system_error::SystemError;
use unified_init::macros::unified_init;
use crate::{
filesystem::{
@ -13,6 +14,7 @@ use crate::{
ROOT_INODE,
},
},
init::initcall::INITCALL_DEVICE,
kerror,
libs::{
lib_ui::textui::{textui_putchar, FontColor},
@ -280,6 +282,7 @@ impl TtyDevicePrivateData {
}
/// @brief 初始化TTY设备
#[unified_init(INITCALL_DEVICE)]
pub fn tty_init() -> Result<(), SystemError> {
let tty: Arc<TtyDevice> = TtyDevice::new("tty0");
let devfs_root_inode = ROOT_INODE().lookup("/dev");

View File

@ -85,7 +85,7 @@ struct InnerFbConsoleDevice {
kernfs_inode: Option<Arc<KernFSInode>>,
parent: Option<Weak<dyn KObject>>,
kset: Option<Arc<KSet>>,
bus: Option<Arc<dyn Bus>>,
bus: Option<Weak<dyn Bus>>,
driver: Option<Weak<dyn Driver>>,
ktype: Option<&'static dyn KObjType>,
}
@ -183,10 +183,14 @@ impl Device for FbConsoleDevice {
IdTable::new(Self::NAME.to_string(), None)
}
fn set_bus(&self, bus: Option<Arc<dyn Bus>>) {
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
self.inner.lock().bus = bus;
}
fn bus(&self) -> Option<Weak<dyn Bus>> {
self.inner.lock().bus.clone()
}
fn set_class(&self, _class: Option<Arc<dyn Class>>) {
// 不允许修改
kwarn!("fbcon's class can not be changed");

View File

@ -1,23 +1,45 @@
use core::intrinsics::unlikely;
use alloc::{
string::ToString,
string::{String, ToString},
sync::{Arc, Weak},
};
use system_error::SystemError;
use unified_init::macros::unified_init;
use crate::driver::base::{
use crate::{
driver::base::{
class::{class_manager, Class},
device::sys_dev_char_kset,
init::SUBSYSTEM_INITIALIZER_SLICE,
kobject::KObject,
device::{
bus::Bus,
device_manager,
device_number::{DeviceNumber, Major},
driver::Driver,
sys_dev_char_kset, Device, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
kset::KSet,
subsys::SubSysPrivate,
},
filesystem::{kernfs::KernFSInode, sysfs::AttributeGroup},
init::initcall::INITCALL_SUBSYS,
libs::{
rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
spinlock::SpinLock,
},
};
use super::fbcon::fb_console_init;
use super::{fbcon::fb_console_init, fbsysfs::FbDeviceAttrGroup, FbId, FrameBuffer};
/// `/sys/class/graphics` 的 class 实例
static mut CLASS_GRAPHICS_INSTANCE: Option<Arc<GraphicsClass>> = None;
lazy_static! {
/// 帧缓冲区管理器
static ref FRAME_BUFFER_MANAGER: FrameBufferManager = FrameBufferManager::new();
}
/// 获取 `/sys/class/graphics` 的 class 实例
#[inline(always)]
#[allow(dead_code)]
@ -25,8 +47,13 @@ pub fn sys_class_graphics_instance() -> Option<&'static Arc<GraphicsClass>> {
unsafe { CLASS_GRAPHICS_INSTANCE.as_ref() }
}
#[inline(always)]
pub fn frame_buffer_manager() -> &'static FrameBufferManager {
&FRAME_BUFFER_MANAGER
}
/// 初始化帧缓冲区子系统
#[unified_init(SUBSYSTEM_INITIALIZER_SLICE)]
#[unified_init(INITCALL_SUBSYS)]
pub fn fbmem_init() -> Result<(), SystemError> {
let graphics_class = GraphicsClass::new();
class_manager().class_register(&(graphics_class.clone() as Arc<dyn Class>))?;
@ -76,3 +103,236 @@ impl Class for GraphicsClass {
return &self.subsystem;
}
}
/// 帧缓冲区管理器
#[derive(Debug)]
pub struct FrameBufferManager {
inner: RwLock<InnerFrameBufferManager>,
}
#[derive(Debug)]
struct InnerFrameBufferManager {
/// 已经注册的帧缓冲区
registered_fbs: [Option<Arc<dyn FrameBuffer>>; FrameBufferManager::FB_MAX],
}
impl FrameBufferManager {
pub const FB_MAX: usize = 32;
pub fn new() -> Self {
Self {
inner: RwLock::new(InnerFrameBufferManager {
registered_fbs: Default::default(),
}),
}
}
/// 注册一个帧缓冲区
///
/// # 参数
///
/// - fb: 帧缓冲区
pub fn register_fb(&self, fb: Arc<dyn FrameBuffer>) -> Result<FbId, SystemError> {
let id = self.generate_fb_id().expect("no more fb id");
fb.set_fb_id(id);
let fb_device = FbDevice::new(Arc::downgrade(&fb) as Weak<dyn FrameBuffer>, id);
device_manager().device_default_initialize(&(fb_device.clone() as Arc<dyn Device>));
fb_device.set_parent(Some(Arc::downgrade(&(fb.clone() as Arc<dyn KObject>))));
fb.set_fb_device(Some(fb_device.clone()));
device_manager().add_device(fb_device.clone() as Arc<dyn Device>)?;
// todo: 从Modedb中获取信息
// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbmem.c#1584
let mut inner = self.inner.write();
inner.registered_fbs[id.data() as usize] = Some(fb.clone() as Arc<dyn FrameBuffer>);
// todo: 把fb跟fbcon关联起来
return Ok(id);
}
/// 注销一个帧缓冲区
///
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbmem.c#1726
#[allow(dead_code)]
pub fn unregister_fb(&self, _fb: Arc<dyn FrameBuffer>) -> Result<(), SystemError> {
todo!("unregister_fb")
}
/// 根据id查找帧缓冲区
pub fn find_fb_by_id(&self, id: FbId) -> Result<Option<Arc<dyn FrameBuffer>>, SystemError> {
if unlikely(!id.is_valid()) {
return Err(SystemError::EINVAL);
}
let inner = self.inner.read();
return Ok(inner.registered_fbs[id.data() as usize].clone());
}
fn generate_fb_id(&self) -> Option<FbId> {
for i in 0..Self::FB_MAX {
if self.inner.read().registered_fbs[i].is_none() {
return Some(FbId::new(i as u32));
}
}
return None;
}
}
/// 抽象的帧缓冲区设备
///
/// 对应于`/sys/class/graphics/fb(x)`目录下的设备, 其中`(x)`为帧缓冲区的id
///
/// 该设备的父设备为真实的帧缓冲区设备
#[derive(Debug)]
#[cast_to([sync] Device)]
pub struct FbDevice {
inner: SpinLock<InnerFbDevice>,
kobj_state: LockedKObjectState,
}
impl FbDevice {
pub const BASENAME: &'static str = "fb";
fn new(fb: Weak<dyn FrameBuffer>, id: FbId) -> Arc<Self> {
Arc::new(Self {
inner: SpinLock::new(InnerFbDevice {
fb,
kern_inode: None,
parent: None,
kset: None,
ktype: None,
fb_id: id,
}),
kobj_state: LockedKObjectState::new(None),
})
}
pub fn framebuffer(&self) -> Option<Arc<dyn FrameBuffer>> {
self.inner.lock().fb.upgrade()
}
}
#[derive(Debug)]
struct InnerFbDevice {
fb: Weak<dyn FrameBuffer>,
kern_inode: Option<Arc<KernFSInode>>,
parent: Option<Weak<dyn KObject>>,
kset: Option<Arc<KSet>>,
ktype: Option<&'static dyn KObjType>,
/// 帧缓冲区id
fb_id: FbId,
}
impl KObject for FbDevice {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
self.inner.lock().kern_inode = inode;
}
fn inode(&self) -> Option<Arc<KernFSInode>> {
self.inner.lock().kern_inode.clone()
}
fn parent(&self) -> Option<Weak<dyn KObject>> {
self.inner.lock().parent.clone()
}
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
self.inner.lock().parent = parent;
}
fn kset(&self) -> Option<Arc<KSet>> {
self.inner.lock().kset.clone()
}
fn set_kset(&self, kset: Option<Arc<KSet>>) {
self.inner.lock().kset = kset;
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
self.inner.lock().ktype
}
fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
self.inner.lock().ktype = ktype;
}
fn name(&self) -> String {
format!("{}{}", Self::BASENAME, self.inner.lock().fb_id.data())
}
fn set_name(&self, _name: String) {
// do nothing
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
self.kobj_state.read()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
self.kobj_state.write()
}
fn set_kobj_state(&self, state: KObjectState) {
*self.kobj_state.write() = state;
}
}
impl Device for FbDevice {
fn dev_type(&self) -> DeviceType {
DeviceType::Char
}
fn id_table(&self) -> IdTable {
IdTable::new(
Self::BASENAME.to_string(),
Some(DeviceNumber::new(
Major::FB_MAJOR,
self.inner.lock().fb_id.data(),
)),
)
}
fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
todo!()
}
fn class(&self) -> Option<Arc<dyn Class>> {
sys_class_graphics_instance().map(|ins| ins.clone() as Arc<dyn Class>)
}
fn set_class(&self, _class: Option<Arc<dyn Class>>) {
// do nothing
}
fn driver(&self) -> Option<Arc<dyn Driver>> {
None
}
fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
// do nothing
}
fn is_dead(&self) -> bool {
false
}
fn can_match(&self) -> bool {
false
}
fn set_can_match(&self, _can_match: bool) {
// do nothing
}
fn state_synced(&self) -> bool {
true
}
fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
Some(&[&FbDeviceAttrGroup])
}
}

View File

@ -0,0 +1,320 @@
use alloc::sync::Arc;
use system_error::SystemError;
use crate::{
driver::base::kobject::KObject,
filesystem::{
sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport},
vfs::syscall::ModeType,
},
};
use super::fbmem::FbDevice;
/// 为FbDevice实现的sysfs属性组
#[derive(Debug)]
pub struct FbDeviceAttrGroup;
impl AttributeGroup for FbDeviceAttrGroup {
fn name(&self) -> Option<&str> {
None
}
fn attrs(&self) -> &[&'static dyn Attribute] {
&[
&AttrBitsPerPixel,
&AttrBlank,
&AttrMode,
&AttrModes,
&AttrName,
&AttrPan,
&AttrRotate,
&AttrState,
&AttrStride,
&AttrVirtualSize,
]
}
fn is_visible(
&self,
_kobj: alloc::sync::Arc<dyn KObject>,
_attr: &'static dyn Attribute,
) -> Option<ModeType> {
None
}
}
#[derive(Debug)]
struct AttrName;
impl Attribute for AttrName {
fn name(&self) -> &str {
"name"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let fb_dev = kobj.arc_any().downcast::<FbDevice>().unwrap();
let fb = fb_dev.framebuffer().ok_or(SystemError::ENODEV)?;
let name = fb.name();
return sysfs_emit_str(buf, &format!("{}\n", name));
}
}
#[derive(Debug)]
struct AttrBitsPerPixel;
impl Attribute for AttrBitsPerPixel {
fn name(&self) -> &str {
"bits_per_pixel"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO | ModeType::S_IWUSR
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE
}
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
kwarn!("attr bits_per_pixel store not implemented");
return Err(SystemError::ENOSYS);
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let fb_dev = kobj.arc_any().downcast::<FbDevice>().unwrap();
let fb = fb_dev.framebuffer().ok_or(SystemError::ENODEV)?;
let bits_per_pixel = fb.current_fb_var().bits_per_pixel;
return sysfs_emit_str(buf, &format!("{}\n", bits_per_pixel));
}
}
/// 用于清空屏幕的属性
#[derive(Debug)]
struct AttrBlank;
impl Attribute for AttrBlank {
fn name(&self) -> &str {
"blank"
}
fn mode(&self) -> ModeType {
ModeType::S_IWUSR
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::STORE
}
// todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#309
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
kwarn!("attr blank store not implemented");
return Err(SystemError::ENOSYS);
}
}
#[derive(Debug)]
struct AttrMode;
impl Attribute for AttrMode {
fn name(&self) -> &str {
"mode"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO | ModeType::S_IWUSR
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE
}
/// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#166
fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
todo!("AttrMode::show")
}
/// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#135
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
todo!("AttrMode::store")
}
}
#[derive(Debug)]
struct AttrModes;
impl Attribute for AttrModes {
fn name(&self) -> &str {
"modes"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO | ModeType::S_IWUSR
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE
}
/// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#206
fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
todo!("AttrMode::show")
}
/// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#177
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
todo!("AttrMode::store")
}
}
#[derive(Debug)]
struct AttrPan;
impl Attribute for AttrPan {
fn name(&self) -> &str {
"pan"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO | ModeType::S_IWUSR
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let fb_dev = kobj.arc_any().downcast::<FbDevice>().unwrap();
let fb = fb_dev.framebuffer().ok_or(SystemError::ENODEV)?;
let var_info = fb.current_fb_var();
return sysfs_emit_str(buf, &format!("{},{}\n", var_info.xoffset, var_info.yoffset));
}
/// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#365
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
todo!("AttrPan::store")
}
}
#[derive(Debug)]
struct AttrVirtualSize;
impl Attribute for AttrVirtualSize {
fn name(&self) -> &str {
"virtual_size"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO | ModeType::S_IWUSR
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let fb_dev = kobj.arc_any().downcast::<FbDevice>().unwrap();
let fb = fb_dev.framebuffer().ok_or(SystemError::ENODEV)?;
let var_info = fb.current_fb_var();
return sysfs_emit_str(
buf,
&format!("{},{}\n", var_info.xres_virtual, var_info.yres_virtual),
);
}
/// https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#273
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
todo!("AttrVirtualSize::store")
}
}
#[derive(Debug)]
struct AttrStride;
impl Attribute for AttrStride {
fn name(&self) -> &str {
"stride"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let fb_dev = kobj.arc_any().downcast::<FbDevice>().unwrap();
let fb = fb_dev.framebuffer().ok_or(SystemError::ENODEV)?;
let fix_info = fb.current_fb_fix();
return sysfs_emit_str(buf, &format!("{}\n", fix_info.line_length));
}
}
#[derive(Debug)]
struct AttrRotate;
impl Attribute for AttrRotate {
fn name(&self) -> &str {
"rotate"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO | ModeType::S_IWUSR
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let fb_dev = kobj.arc_any().downcast::<FbDevice>().unwrap();
let fb = fb_dev.framebuffer().ok_or(SystemError::ENODEV)?;
let var_info = fb.current_fb_var();
return sysfs_emit_str(buf, &format!("{}\n", var_info.rotate_angle));
}
/// todo https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#246
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
todo!("AttrRotate::store")
}
}
#[derive(Debug)]
struct AttrState;
impl Attribute for AttrState {
fn name(&self) -> &str {
"state"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO | ModeType::S_IWUSR
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW | SysFSOpsSupport::STORE
}
fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
let fb_dev = kobj.arc_any().downcast::<FbDevice>().unwrap();
let fb = fb_dev.framebuffer().ok_or(SystemError::ENODEV)?;
return sysfs_emit_str(buf, &format!("{}\n", fb.state() as u8));
}
/// todo https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/fbsysfs.c#406
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
todo!("AttrState::store")
}
}

View File

@ -3,14 +3,41 @@ use system_error::SystemError;
use crate::{
driver::base::device::Device,
mm::{ucontext::LockedVMA, PhysAddr},
mm::{ucontext::LockedVMA, PhysAddr, VirtAddr},
};
use self::fbmem::{FbDevice, FrameBufferManager};
pub mod fbcon;
pub mod fbmem;
pub mod fbsysfs;
pub mod modedb;
// 帧缓冲区id
int_like!(FbId, u32);
impl FbId {
/// 帧缓冲区id的初始值无效值
pub const INIT: Self = Self::new(u32::MAX);
/// 判断是否为无效的帧缓冲区id
#[allow(dead_code)]
pub const fn is_valid(&self) -> bool {
if self.0 == Self::INIT.0 || self.0 >= FrameBufferManager::FB_MAX as u32 {
return false;
}
return true;
}
}
/// 帧缓冲区应该实现的接口
pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {}
pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
/// 获取帧缓冲区的id
fn fb_id(&self) -> FbId;
/// 设置帧缓冲区的id
fn set_fb_id(&self, id: FbId);
}
/// 帧缓冲区信息
pub trait FrameBufferInfo {
@ -18,19 +45,22 @@ pub trait FrameBufferInfo {
fn screen_size(&self) -> usize;
/// 获取当前的可变帧缓冲信息
fn current_fb_var(&self) -> &FbVarScreenInfo;
/// 获取当前的可变帧缓冲信息(可变引用)
fn current_fb_var_mut(&mut self) -> &mut FbVarScreenInfo;
fn current_fb_var(&self) -> FbVarScreenInfo;
/// 获取当前的固定帧缓冲信息
fn current_fb_fix(&self) -> &FixedScreenInfo;
/// 获取当前的固定帧缓冲信息(可变引用)
fn current_fb_fix_mut(&mut self) -> &mut FixedScreenInfo;
fn current_fb_fix(&self) -> FixedScreenInfo;
/// 获取当前的视频模式
fn video_mode(&self) -> Option<&FbVideoMode>;
/// 获取当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体
fn fb_device(&self) -> Option<Arc<FbDevice>>;
/// 设置当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体
fn set_fb_device(&self, device: Option<Arc<FbDevice>>);
/// 获取帧缓冲区的状态
fn state(&self) -> FbState;
}
/// 帧缓冲区操作
@ -94,6 +124,13 @@ pub trait FrameBufferOps {
fn fb_destroy(&self);
}
/// 帧缓冲区的状态
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum FbState {
Running = 0,
Suspended = 1,
}
/// 屏幕黑屏模式。
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
@ -221,10 +258,10 @@ pub struct FbVarScreenInfo {
pub pixel_format: FbPixelFormat,
/// 激活标志参见FB_ACTIVATE_*
pub activate: FbActivateFlags,
/// 帧缓冲区的高度(像素)
pub height: u32,
/// 帧缓冲区的宽度(像素)
pub width: u32,
/// 帧缓冲区的高度(像素) None表示未知
pub height: Option<u32>,
/// 帧缓冲区的宽度(像素) None表示未知
pub width: Option<u32>,
/// 像素时钟(皮秒)
pub pixclock: u32,
/// 左边距
@ -249,6 +286,43 @@ pub struct FbVarScreenInfo {
pub colorspace: V4l2Colorspace,
}
impl Default for FbVarScreenInfo {
fn default() -> Self {
Self {
xres: Default::default(),
yres: Default::default(),
xres_virtual: Default::default(),
yres_virtual: Default::default(),
xoffset: Default::default(),
yoffset: Default::default(),
bits_per_pixel: Default::default(),
color_mode: Default::default(),
red: Default::default(),
green: Default::default(),
blue: Default::default(),
transp: Default::default(),
pixel_format: Default::default(),
activate: Default::default(),
height: None,
width: None,
pixclock: Default::default(),
left_margin: Default::default(),
right_margin: Default::default(),
upper_margin: Default::default(),
lower_margin: Default::default(),
hsync_len: Default::default(),
vsync_len: Default::default(),
sync: FbSyncFlags::empty(),
vmode: FbVModeFlags::empty(),
rotate_angle: Default::default(),
colorspace: Default::default(),
}
}
}
/// 帧缓冲区的颜色模式
///
/// 默认为彩色
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum FbColorMode {
@ -260,6 +334,12 @@ pub enum FbColorMode {
FourCC,
}
impl Default for FbColorMode {
fn default() -> Self {
FbColorMode::Color
}
}
/// `FbBitfield` 结构体用于描述颜色字段的位域。
///
/// 所有的偏移量都是从右边开始,位于一个精确为'bits_per_pixel'宽度的"像素"值内。
@ -289,6 +369,16 @@ impl FbBitfield {
}
}
impl Default for FbBitfield {
fn default() -> Self {
Self {
offset: Default::default(),
length: Default::default(),
msb_right: Default::default(),
}
}
}
bitflags! {
/// `FbActivateFlags` 用于描述帧缓冲区的激活标志。
///
@ -317,6 +407,12 @@ bitflags! {
}
}
impl Default for FbActivateFlags {
fn default() -> Self {
FbActivateFlags::FB_ACTIVATE_NOW
}
}
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum FbPixelFormat {
@ -327,6 +423,12 @@ pub enum FbPixelFormat {
Reserved,
}
impl Default for FbPixelFormat {
fn default() -> Self {
FbPixelFormat::Standard
}
}
bitflags! {
pub struct FbSyncFlags: u32 {
/// 水平同步高电平有效
@ -415,9 +517,9 @@ pub struct FixedScreenInfo {
// 字符串,用于标识屏幕,例如 "TT Builtin"
pub id: [char; 16],
// 帧缓冲区的起始物理地址
pub smem_start: PhysAddr,
pub smem_start: Option<PhysAddr>,
// 帧缓冲区的长度
pub smem_len: u32,
pub smem_len: usize,
// 屏幕类型,参考 FB_TYPE_
pub fb_type: FbType,
// 用于表示交错平面的小端辅助类型
@ -432,16 +534,61 @@ pub struct FixedScreenInfo {
pub ywrapstep: u16,
// 一行的大小(以字节为单位)
pub line_length: u32,
// 内存映射I/O的起始物理地址
pub mmio_start: PhysAddr,
// 内存映射I/O端口的起始物理地址
pub mmio_start: Option<PhysAddr>,
// 内存映射I/O的长度
pub mmio_len: u32,
pub mmio_len: usize,
// 表示驱动器拥有的特定芯片/卡片类型
pub accel: u32,
pub accel: FbAccel,
// 表示支持的特性,参考 FB_CAP_
pub capabilities: FbCapability,
}
impl FixedScreenInfo {
/// 将字符串转换为长度为16的字符数组包含结尾的`\0`
///
/// ## 参数
///
/// - `name`: 字符串,长度不超过15超过的部分将被截断
///
/// ## 返回
///
/// 长度为16的字符数组
pub const fn name2id(name: &str) -> [char; 16] {
let mut id = [0 as char; 16];
let mut i = 0;
while i < 15 && i < name.len() {
id[i] = name.as_bytes()[i] as char;
i += 1;
}
id[i] = '\0';
return id;
}
}
impl Default for FixedScreenInfo {
fn default() -> Self {
Self {
id: Default::default(),
smem_start: None,
smem_len: Default::default(),
fb_type: FbType::PackedPixels,
type_aux: Default::default(),
visual: FbVisual::Mono10,
xpanstep: Default::default(),
ypanstep: Default::default(),
ywrapstep: Default::default(),
line_length: Default::default(),
mmio_start: None,
mmio_len: Default::default(),
accel: Default::default(),
capabilities: Default::default(),
}
}
}
/// 帧缓冲类型
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
@ -488,6 +635,12 @@ pub enum FbCapability {
FourCC,
}
impl Default for FbCapability {
fn default() -> Self {
FbCapability::Default
}
}
/// 视频模式
#[allow(dead_code)]
#[derive(Debug, Clone, Eq, PartialEq)]
@ -521,3 +674,179 @@ pub struct FbVideoMode {
/// 标志
pub flag: u32,
}
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum FbAccel {
/// 没有硬件加速器
None,
AtariBlitter = 1,
AmigaBlitter = 2,
S3Trio64 = 3,
NCR77C32BLT = 4,
S3Virge = 5,
AtiMach64GX = 6,
DECTGA = 7,
AtiMach64CT = 8,
AtiMach64VT = 9,
AtiMach64GT = 10,
SunCreator = 11,
SunCGSix = 12,
SunLeo = 13,
IMSTwinTurbo = 14,
Acc3DLabsPermedia2 = 15,
MatroxMGA2064W = 16,
MatroxMGA1064SG = 17,
MatroxMGA2164W = 18,
MatroxMGA2164WAGP = 19,
MatroxMGAG400 = 20,
NV3 = 21,
NV4 = 22,
NV5 = 23,
NV6 = 24,
XGIVolariV = 25,
XGIVolariZ = 26,
Omap1610 = 27,
TridentTGUI = 28,
Trident3DImage = 29,
TridentBlade3D = 30,
TridentBladeXP = 31,
CirrusAlpine = 32,
NeoMagicNM2070 = 90,
NeoMagicNM2090 = 91,
NeoMagicNM2093 = 92,
NeoMagicNM2097 = 93,
NeoMagicNM2160 = 94,
NeoMagicNM2200 = 95,
NeoMagicNM2230 = 96,
NeoMagicNM2360 = 97,
NeoMagicNM2380 = 98,
PXA3XX = 99,
Savage4 = 0x80,
Savage3D = 0x81,
Savage3DMV = 0x82,
Savage2000 = 0x83,
SavageMXMV = 0x84,
SavageMX = 0x85,
SavageIXMV = 0x86,
SavageIX = 0x87,
ProSavagePM = 0x88,
ProSavageKM = 0x89,
S3Twister = 0x8a,
S3TwisterK = 0x8b,
SuperSavage = 0x8c,
ProSavageDDR = 0x8d,
ProSavageDDRK = 0x8e,
// Add other accelerators here
}
impl Default for FbAccel {
fn default() -> Self {
FbAccel::None
}
}
#[derive(Debug, Copy, Clone)]
pub struct BootTimeScreenInfo {
pub origin_x: u8,
pub origin_y: u8,
/// text mode时每行的字符数
pub origin_video_cols: u8,
/// text mode时行数
pub origin_video_lines: u8,
/// 标记屏幕是否为VGA类型
pub is_vga: bool,
/// video mode type
pub video_type: BootTimeVideoType,
// 以下字段用于线性帧缓冲区
/// 线性帧缓冲区的起始物理地址
pub lfb_base: PhysAddr,
/// 线性帧缓冲区在初始化阶段被映射到的起始虚拟地址
///
/// 这个值可能会被设置2次
///
/// - 内存管理初始化之前early init阶段临时映射
/// - 内存管理初始化完毕,重新映射时被设置
pub lfb_virt_base: Option<VirtAddr>,
/// 线性帧缓冲区的长度
pub lfb_size: usize,
/// 线性帧缓冲区的宽度(像素)
pub lfb_width: u32,
/// 线性帧缓冲区的高度(像素)
pub lfb_height: u32,
/// 线性帧缓冲区的深度(位数)
pub lfb_depth: u8,
/// 红色位域的大小
pub red_size: u8,
/// 红色位域的偏移量(左移位数)
pub red_pos: u8,
/// 绿色位域的大小
pub green_size: u8,
/// 绿色位域的偏移量(左移位数)
pub green_pos: u8,
/// 蓝色位域的大小
pub blue_size: u8,
/// 蓝色位域的偏移量(左移位数)
pub blue_pos: u8,
}
impl BootTimeScreenInfo {
pub const DEFAULT: Self = Self {
origin_x: 0,
origin_y: 0,
is_vga: false,
lfb_base: PhysAddr::new(0),
lfb_size: 0,
lfb_width: 0,
lfb_height: 0,
red_size: 0,
red_pos: 0,
green_size: 0,
green_pos: 0,
blue_size: 0,
blue_pos: 0,
video_type: BootTimeVideoType::UnDefined,
origin_video_cols: 0,
origin_video_lines: 0,
lfb_virt_base: None,
lfb_depth: 0,
};
}
/// Video types for different display hardware
#[allow(dead_code)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum BootTimeVideoType {
UnDefined,
/// Monochrome Text Display
Mda,
/// CGA Display
Cga,
/// EGA/VGA in Monochrome Mode
EgaM,
/// EGA in Color Mode
EgaC,
/// VGA+ in Color Mode
VgaC,
/// VESA VGA in graphic mode
Vlfb,
/// ACER PICA-61 local S3 video
PicaS3,
/// MIPS Magnum 4000 G364 video
MipsG364,
/// Various SGI graphics hardware
Sgi,
/// DEC TGA
TgaC,
/// Sun frame buffer
Sun,
/// Sun PCI based frame buffer
SunPci,
/// PowerMacintosh frame buffer
Pmac,
/// EFI graphic mode
Efi,
}

View File

@ -0,0 +1,3 @@
//! todo: 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/modedb.c
//!
//! 实现modedb

View File

@ -1 +1,2 @@
pub mod base;
pub mod vesafb;

View File

@ -0,0 +1,680 @@
use core::{
ffi::{c_uint, c_void},
mem::MaybeUninit,
sync::atomic::AtomicBool,
};
use alloc::{
string::{String, ToString},
sync::{Arc, Weak},
vec::Vec,
};
use system_error::SystemError;
use unified_init::macros::unified_init;
use crate::{
arch::MMArch,
driver::{
base::{
class::Class,
device::{
bus::Bus, device_manager, driver::Driver, Device, DeviceState, DeviceType, IdTable,
},
kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
kset::KSet,
platform::{
platform_device::{platform_device_manager, PlatformDevice},
platform_driver::{platform_driver_manager, PlatformDriver},
CompatibleTable,
},
},
tty::serial::serial8250::send_to_default_serial8250_port,
video::fbdev::base::{fbmem::frame_buffer_manager, FbVisual},
},
filesystem::{
kernfs::KernFSInode,
sysfs::{file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport},
vfs::syscall::ModeType,
},
include::bindings::bindings::{
multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
},
init::{boot_params, initcall::INITCALL_DEVICE},
libs::{
align::page_align_up,
once::Once,
rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
spinlock::SpinLock,
},
mm::{
allocator::page_frame::PageFrameCount, no_init::pseudo_map_phys, MemoryManagementArch,
PhysAddr, VirtAddr,
},
};
use super::base::{
fbmem::FbDevice, BlankMode, BootTimeVideoType, FbAccel, FbActivateFlags, FbId, FbState, FbType,
FbVModeFlags, FbVarScreenInfo, FbVideoMode, FixedScreenInfo, FrameBuffer, FrameBufferInfo,
FrameBufferOps,
};
/// 当前机器上面是否有vesa帧缓冲区
static HAS_VESA_FB: AtomicBool = AtomicBool::new(false);
lazy_static! {
static ref VESAFB_FIX_INFO: RwLock<FixedScreenInfo> = RwLock::new(FixedScreenInfo {
id: FixedScreenInfo::name2id("VESA VGA"),
fb_type: FbType::PackedPixels,
accel: FbAccel::None,
..Default::default()
});
static ref VESAFB_DEFINED: RwLock<FbVarScreenInfo> = RwLock::new(FbVarScreenInfo {
activate: FbActivateFlags::FB_ACTIVATE_NOW,
height: None,
width: None,
right_margin: 32,
upper_margin: 16,
lower_margin: 4,
vsync_len: 4,
vmode: FbVModeFlags::FB_VMODE_NONINTERLACED,
..Default::default()
});
}
#[derive(Debug)]
#[cast_to([sync] Device)]
#[cast_to([sync] PlatformDevice)]
pub struct VesaFb {
inner: SpinLock<InnerVesaFb>,
kobj_state: LockedKObjectState,
}
impl VesaFb {
pub const NAME: &'static str = "vesa_vga";
pub fn new() -> Self {
return Self {
inner: SpinLock::new(InnerVesaFb {
bus: None,
class: None,
driver: None,
kern_inode: None,
parent: None,
kset: None,
kobj_type: None,
device_state: DeviceState::NotInitialized,
pdev_id: 0,
pdev_id_auto: false,
fb_id: FbId::INIT,
fb_device: None,
fb_state: FbState::Suspended,
}),
kobj_state: LockedKObjectState::new(None),
};
}
}
#[derive(Debug)]
struct InnerVesaFb {
bus: Option<Weak<dyn Bus>>,
class: Option<Arc<dyn Class>>,
driver: Option<Weak<dyn Driver>>,
kern_inode: Option<Arc<KernFSInode>>,
parent: Option<Weak<dyn KObject>>,
kset: Option<Arc<KSet>>,
kobj_type: Option<&'static dyn KObjType>,
device_state: DeviceState,
pdev_id: i32,
pdev_id_auto: bool,
fb_id: FbId,
fb_device: Option<Arc<FbDevice>>,
fb_state: FbState,
}
impl FrameBuffer for VesaFb {
fn fb_id(&self) -> FbId {
self.inner.lock().fb_id
}
fn set_fb_id(&self, id: FbId) {
self.inner.lock().fb_id = id;
}
}
impl PlatformDevice for VesaFb {
fn pdev_name(&self) -> &str {
Self::NAME
}
fn set_pdev_id(&self, id: i32) {
self.inner.lock().pdev_id = id;
}
fn set_pdev_id_auto(&self, id_auto: bool) {
self.inner.lock().pdev_id_auto = id_auto;
}
fn compatible_table(&self) -> CompatibleTable {
todo!()
}
fn is_initialized(&self) -> bool {
self.inner.lock().device_state == DeviceState::Initialized
}
fn set_state(&self, set_state: DeviceState) {
self.inner.lock().device_state = set_state;
}
}
impl Device for VesaFb {
fn dev_type(&self) -> DeviceType {
DeviceType::Char
}
fn id_table(&self) -> IdTable {
IdTable::new(self.name(), None)
}
fn bus(&self) -> Option<Weak<dyn Bus>> {
self.inner.lock().bus.clone()
}
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
self.inner.lock().bus = bus;
}
fn set_class(&self, class: Option<Arc<dyn Class>>) {
self.inner.lock().class = class;
}
fn driver(&self) -> Option<Arc<dyn Driver>> {
self.inner.lock().driver.clone()?.upgrade()
}
fn set_driver(&self, driver: Option<Weak<dyn Driver>>) {
self.inner.lock().driver = driver;
}
fn is_dead(&self) -> bool {
false
}
fn can_match(&self) -> bool {
true
}
fn set_can_match(&self, _can_match: bool) {}
fn state_synced(&self) -> bool {
true
}
}
impl KObject for VesaFb {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
self.inner.lock().kern_inode = inode;
}
fn inode(&self) -> Option<Arc<KernFSInode>> {
self.inner.lock().kern_inode.clone()
}
fn parent(&self) -> Option<Weak<dyn KObject>> {
self.inner.lock().parent.clone()
}
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
self.inner.lock().parent = parent;
}
fn kset(&self) -> Option<Arc<KSet>> {
self.inner.lock().kset.clone()
}
fn set_kset(&self, kset: Option<Arc<KSet>>) {
self.inner.lock().kset = kset;
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
self.inner.lock().kobj_type
}
fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
self.inner.lock().kobj_type = ktype;
}
fn name(&self) -> String {
Self::NAME.to_string()
}
fn set_name(&self, _name: String) {
// do nothing
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
self.kobj_state.read()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
self.kobj_state.write()
}
fn set_kobj_state(&self, state: KObjectState) {
*self.kobj_state.write() = state;
}
}
impl FrameBufferOps for VesaFb {
fn fb_open(&self, _user: bool) {
todo!()
}
fn fb_release(&self, _user: bool) {
todo!()
}
fn fb_set_color_register(
&self,
_regno: u16,
_red: u16,
_green: u16,
_blue: u16,
) -> Result<(), SystemError> {
todo!()
}
fn fb_blank(&self, _blank_mode: BlankMode) -> Result<(), SystemError> {
todo!()
}
fn fb_destroy(&self) {
todo!()
}
}
impl FrameBufferInfo for VesaFb {
fn fb_device(&self) -> Option<Arc<FbDevice>> {
self.inner.lock().fb_device.clone()
}
fn set_fb_device(&self, device: Option<Arc<FbDevice>>) {
self.inner.lock().fb_device = device;
}
fn screen_size(&self) -> usize {
todo!()
}
fn current_fb_var(&self) -> FbVarScreenInfo {
VESAFB_DEFINED.read().clone()
}
fn current_fb_fix(&self) -> FixedScreenInfo {
VESAFB_FIX_INFO.read().clone()
}
fn video_mode(&self) -> Option<&FbVideoMode> {
todo!()
}
fn state(&self) -> FbState {
self.inner.lock().fb_state
}
}
#[derive(Debug)]
#[cast_to([sync] PlatformDriver)]
struct VesaFbDriver {
inner: SpinLock<InnerVesaFbDriver>,
kobj_state: LockedKObjectState,
}
impl VesaFbDriver {
pub fn new() -> Arc<Self> {
let r = Arc::new(Self {
inner: SpinLock::new(InnerVesaFbDriver {
ktype: None,
kset: None,
parent: None,
kernfs_inode: None,
devices: Vec::new(),
bus: None,
self_ref: Weak::new(),
}),
kobj_state: LockedKObjectState::new(None),
});
r.inner.lock().self_ref = Arc::downgrade(&r);
return r;
}
}
#[derive(Debug)]
struct InnerVesaFbDriver {
ktype: Option<&'static dyn KObjType>,
kset: Option<Arc<KSet>>,
parent: Option<Weak<dyn KObject>>,
kernfs_inode: Option<Arc<KernFSInode>>,
devices: Vec<Arc<dyn Device>>,
bus: Option<Weak<dyn Bus>>,
self_ref: Weak<VesaFbDriver>,
}
impl VesaFbDriver {
const NAME: &'static str = "vesa-framebuffer";
}
impl PlatformDriver for VesaFbDriver {
fn probe(&self, device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
let device = device
.clone()
.arc_any()
.downcast::<VesaFb>()
.map_err(|_| SystemError::EINVAL)?;
device.set_driver(Some(self.inner.lock_irqsave().self_ref.clone()));
return Ok(());
}
fn remove(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
todo!()
}
fn shutdown(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
// do nothing
return Ok(());
}
fn suspend(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
// do nothing
return Ok(());
}
fn resume(&self, _device: &Arc<dyn PlatformDevice>) -> Result<(), SystemError> {
todo!()
}
}
impl Driver for VesaFbDriver {
fn id_table(&self) -> Option<IdTable> {
Some(IdTable::new(VesaFb::NAME.to_string(), None))
}
fn devices(&self) -> Vec<Arc<dyn Device>> {
self.inner.lock().devices.clone()
}
fn add_device(&self, device: Arc<dyn Device>) {
let mut guard = self.inner.lock();
// check if the device is already in the list
if guard.devices.iter().any(|dev| Arc::ptr_eq(dev, &device)) {
return;
}
guard.devices.push(device);
}
fn delete_device(&self, device: &Arc<dyn Device>) {
let mut guard = self.inner.lock();
guard.devices.retain(|dev| !Arc::ptr_eq(dev, device));
}
fn set_bus(&self, bus: Option<Weak<dyn Bus>>) {
self.inner.lock().bus = bus;
}
fn bus(&self) -> Option<Weak<dyn Bus>> {
self.inner.lock().bus.clone()
}
fn dev_groups(&self) -> &'static [&'static dyn AttributeGroup] {
return &[&VesaFbAnonAttributeGroup];
}
}
impl KObject for VesaFbDriver {
fn as_any_ref(&self) -> &dyn core::any::Any {
self
}
fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
self.inner.lock().kernfs_inode = inode;
}
fn inode(&self) -> Option<Arc<KernFSInode>> {
self.inner.lock().kernfs_inode.clone()
}
fn parent(&self) -> Option<Weak<dyn KObject>> {
self.inner.lock().parent.clone()
}
fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
self.inner.lock().parent = parent;
}
fn kset(&self) -> Option<Arc<KSet>> {
self.inner.lock().kset.clone()
}
fn set_kset(&self, kset: Option<Arc<KSet>>) {
self.inner.lock().kset = kset;
}
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
self.inner.lock().ktype
}
fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
self.inner.lock().ktype = ktype;
}
fn name(&self) -> String {
Self::NAME.to_string()
}
fn set_name(&self, _name: String) {
// do nothing
}
fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
self.kobj_state.read()
}
fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
self.kobj_state.write()
}
fn set_kobj_state(&self, state: KObjectState) {
*self.kobj_state.write() = state;
}
}
#[derive(Debug)]
struct VesaFbAnonAttributeGroup;
impl AttributeGroup for VesaFbAnonAttributeGroup {
fn name(&self) -> Option<&str> {
None
}
fn attrs(&self) -> &[&'static dyn Attribute] {
&[&AnonAttrPhysAddr as &'static dyn Attribute]
}
fn is_visible(
&self,
_kobj: Arc<dyn KObject>,
attr: &'static dyn Attribute,
) -> Option<ModeType> {
Some(attr.mode())
}
}
#[derive(Debug)]
struct AnonAttrPhysAddr;
impl Attribute for AnonAttrPhysAddr {
fn name(&self) -> &str {
"smem_start"
}
fn mode(&self) -> ModeType {
ModeType::S_IRUGO
}
fn support(&self) -> SysFSOpsSupport {
SysFSOpsSupport::SHOW
}
fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
sysfs_emit_str(
buf,
format!(
"0x{:x}\n",
VESAFB_FIX_INFO
.read()
.smem_start
.unwrap_or(PhysAddr::new(0))
.data()
)
.as_str(),
)
}
}
#[unified_init(INITCALL_DEVICE)]
pub fn vesa_fb_driver_init() -> Result<(), SystemError> {
let driver = VesaFbDriver::new();
platform_driver_manager().register(driver)?;
return Ok(());
}
/// 在内存管理初始化之前,初始化vesafb
pub fn vesafb_early_init() -> Result<VirtAddr, SystemError> {
let mut _reserved: u32 = 0;
let mut fb_info: MaybeUninit<multiboot_tag_framebuffer_info_t> = MaybeUninit::uninit();
//从multiboot2中读取帧缓冲区信息至fb_info
// todo: 换成rust的并且检测是否成功获取
unsafe {
multiboot2_iter(
Some(multiboot2_get_Framebuffer_info),
fb_info.as_mut_ptr() as usize as *mut c_void,
&mut _reserved as *mut c_uint,
)
};
unsafe { fb_info.assume_init() };
let fb_info: multiboot_tag_framebuffer_info_t = unsafe { core::mem::transmute(fb_info) };
// todo: 判断是否有vesa帧缓冲区这里暂时直接设置true
HAS_VESA_FB.store(true, core::sync::atomic::Ordering::SeqCst);
let width = fb_info.framebuffer_width;
let height = fb_info.framebuffer_height;
let mut boot_params_guard = boot_params().write();
let boottime_screen_info = &mut boot_params_guard.screen_info;
boottime_screen_info.is_vga = true;
boottime_screen_info.lfb_base = PhysAddr::new(fb_info.framebuffer_addr as usize);
if fb_info.framebuffer_type == 2 {
//当type=2时,width与height用字符数表示,故depth=8
boottime_screen_info.origin_video_cols = width as u8;
boottime_screen_info.origin_video_lines = height as u8;
boottime_screen_info.video_type = BootTimeVideoType::Mda;
boottime_screen_info.lfb_depth = 8;
} else {
//否则为图像模式,depth应参照帧缓冲区信息里面的每个像素的位数
boottime_screen_info.lfb_width = width;
boottime_screen_info.lfb_height = height;
boottime_screen_info.video_type = BootTimeVideoType::Vlfb;
boottime_screen_info.lfb_depth = fb_info.framebuffer_bpp as u8;
}
boottime_screen_info.lfb_size =
(width * height * ((fb_info.framebuffer_bpp as u32 + 7) / 8)) as usize;
let buf_vaddr = VirtAddr::new(0xffff800003200000);
boottime_screen_info.lfb_virt_base = Some(buf_vaddr);
let init_text = "Video driver to map.\n\0";
send_to_default_serial8250_port(init_text.as_bytes());
// 地址映射
let paddr = PhysAddr::new(fb_info.framebuffer_addr as usize);
let count =
PageFrameCount::new(page_align_up(boottime_screen_info.lfb_size) / MMArch::PAGE_SIZE);
unsafe { pseudo_map_phys(buf_vaddr, paddr, count) };
return Ok(buf_vaddr);
}
#[unified_init(INITCALL_DEVICE)]
fn vesa_fb_device_init() -> Result<(), SystemError> {
// 如果没有vesa帧缓冲区直接返回
if !HAS_VESA_FB.load(core::sync::atomic::Ordering::SeqCst) {
return Ok(());
}
static INIT: Once = Once::new();
INIT.call_once(|| {
kinfo!("vesa fb device init");
let mut fix_info_guard = VESAFB_FIX_INFO.write_irqsave();
let mut var_info_guard = VESAFB_DEFINED.write_irqsave();
let boot_params_guard = boot_params().read();
let boottime_screen_info = &boot_params_guard.screen_info;
fix_info_guard.smem_start = Some(boottime_screen_info.lfb_base);
fix_info_guard.smem_len = boottime_screen_info.lfb_size;
if boottime_screen_info.video_type == BootTimeVideoType::Mda {
fix_info_guard.visual = FbVisual::Mono10;
var_info_guard.bits_per_pixel = 8;
fix_info_guard.line_length = (boottime_screen_info.origin_video_cols as u32)
* (var_info_guard.bits_per_pixel / 8);
var_info_guard.xres_virtual = boottime_screen_info.origin_video_cols as u32;
var_info_guard.yres_virtual = boottime_screen_info.origin_video_lines as u32;
} else {
fix_info_guard.visual = FbVisual::TrueColor;
var_info_guard.bits_per_pixel = boottime_screen_info.lfb_depth as u32;
fix_info_guard.line_length =
(boottime_screen_info.lfb_width as u32) * (var_info_guard.bits_per_pixel / 8);
var_info_guard.xres_virtual = boottime_screen_info.lfb_width as u32;
var_info_guard.yres_virtual = boottime_screen_info.lfb_height as u32;
}
drop(var_info_guard);
drop(fix_info_guard);
let device = Arc::new(VesaFb::new());
device_manager().device_default_initialize(&(device.clone() as Arc<dyn Device>));
platform_device_manager()
.device_add(device.clone() as Arc<dyn PlatformDevice>)
.expect("vesa_fb_device_init: platform_device_manager().device_add failed");
frame_buffer_manager()
.register_fb(device.clone() as Arc<dyn FrameBuffer>)
.expect("vesa_fb_device_init: frame_buffer_manager().register_fb failed");
// 设置vesa fb的状态为运行中
device.inner.lock().fb_state = FbState::Running;
});
return Ok(());
}

View File

@ -1,16 +1,12 @@
use core::{
ffi::{c_uint, c_void},
mem::MaybeUninit,
sync::atomic::{AtomicBool, Ordering},
};
use core::sync::atomic::{AtomicBool, Ordering};
use crate::{
arch::MMArch,
driver::tty::serial::serial8250::send_to_default_serial8250_port,
include::bindings::bindings::{
multiboot2_get_Framebuffer_info, multiboot2_iter, multiboot_tag_framebuffer_info_t,
FRAME_BUFFER_MAPPING_OFFSET, SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE,
},
init::boot_params,
kinfo,
libs::{
align::page_align_up,
@ -19,8 +15,8 @@ use crate::{
spinlock::SpinLock,
},
mm::{
allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper,
no_init::pseudo_map_phys, page::PageFlags, MemoryManagementArch, PhysAddr, VirtAddr,
allocator::page_frame::PageFrameCount, kernel_mapper::KernelMapper, page::PageFlags,
MemoryManagementArch, VirtAddr,
},
time::timer::{Timer, TimerFunction},
};
@ -42,7 +38,6 @@ pub fn video_refresh_manager() -> &'static VideoRefreshManager {
///管理显示刷新变量的结构体
pub struct VideoRefreshManager {
device_buffer: RwLock<ScmBufferInfo>,
fb_info: multiboot_tag_framebuffer_info_t,
refresh_target: RwLock<Option<Arc<SpinLock<Box<[u32]>>>>>,
running: AtomicBool,
}
@ -94,6 +89,7 @@ impl VideoRefreshManager {
let buf_vaddr = VirtAddr::new(
SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE as usize + FRAME_BUFFER_MAPPING_OFFSET as usize,
);
boot_params().write_irqsave().screen_info.lfb_virt_base = Some(buf_vaddr);
let mut frame_buffer_info_graud = self.device_buffer.write();
if let ScmBuffer::DeviceBuffer(vaddr) = &mut (frame_buffer_info_graud).buf {
@ -101,7 +97,7 @@ impl VideoRefreshManager {
}
// 地址映射
let mut paddr = PhysAddr::new(self.fb_info.framebuffer_addr as usize);
let mut paddr = boot_params().read().screen_info.lfb_base;
let count = PageFrameCount::new(
page_align_up(frame_buffer_info_graud.buf_size()) / MMArch::PAGE_SIZE,
);
@ -178,68 +174,48 @@ impl VideoRefreshManager {
}
/// 此函数用于初始化显示驱动,为后续的图形输出做好准备。
#[cfg(not(target_arch = "riscv64"))]
#[cfg(target_arch = "x86_64")]
pub unsafe fn video_init() -> Result<(), SystemError> {
static INIT: AtomicBool = AtomicBool::new(false);
if INIT
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
.is_err()
{
panic!("Try to init video twice!");
}
let mut _reserved: u32 = 0;
let mut fb_info: MaybeUninit<multiboot_tag_framebuffer_info_t> = MaybeUninit::uninit();
//从multiboot2中读取帧缓冲区信息至fb_info
multiboot2_iter(
Some(multiboot2_get_Framebuffer_info),
fb_info.as_mut_ptr() as usize as *mut c_void,
&mut _reserved as *mut c_uint,
);
fb_info.assume_init();
let fb_info: multiboot_tag_framebuffer_info_t = core::mem::transmute(fb_info);
let width = fb_info.framebuffer_width;
let height = fb_info.framebuffer_height;
//初始化帧缓冲区信息结构体
let (bit_depth, flags) = if fb_info.framebuffer_type == 2 {
//当type=2时,width与height用字符数表示,故depth=8
(8u32, ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_FB)
} else {
//否则为图像模式,depth应参照帧缓冲区信息里面的每个像素的位数
(
fb_info.framebuffer_bpp as u32,
ScmBufferFlag::SCM_BF_PIXEL | ScmBufferFlag::SCM_BF_FB,
)
use crate::{
arch::driver::video::arch_video_early_init,
driver::video::fbdev::base::BootTimeVideoType,
};
let buf_vaddr = VirtAddr::new(0xffff800003200000);
let device_buffer = ScmBufferInfo::new_device_buffer(
width,
height,
width * height * ((bit_depth + 7) / 8),
bit_depth,
flags,
arch_video_early_init()?;
let boot_params_guard = boot_params().read();
let screen_info = &boot_params_guard.screen_info;
let buf_vaddr = screen_info.lfb_virt_base.unwrap();
let buf_flag: ScmBufferFlag;
let device_buffer: ScmBufferInfo;
if screen_info.video_type == BootTimeVideoType::Mda {
buf_flag = ScmBufferFlag::SCM_BF_TEXT | ScmBufferFlag::SCM_BF_FB;
device_buffer = ScmBufferInfo::new_device_buffer(
screen_info.origin_video_cols.into(),
screen_info.origin_video_lines.into(),
screen_info.lfb_size as u32,
screen_info.lfb_depth.into(),
buf_flag,
buf_vaddr,
)
.unwrap();
let init_text = "Video driver to map.\n\0";
send_to_default_serial8250_port(init_text.as_bytes());
//地址映射
let paddr = PhysAddr::new(fb_info.framebuffer_addr as usize);
let count = PageFrameCount::new(
page_align_up(device_buffer.buf_size() as usize) / MMArch::PAGE_SIZE,
);
pseudo_map_phys(buf_vaddr, paddr, count);
} else {
// 图形模式
buf_flag = ScmBufferFlag::SCM_BF_PIXEL | ScmBufferFlag::SCM_BF_FB;
device_buffer = ScmBufferInfo::new_device_buffer(
screen_info.lfb_width,
screen_info.lfb_height,
screen_info.lfb_size as u32,
screen_info.lfb_depth.into(),
buf_flag,
buf_vaddr,
)
.unwrap();
}
let result = Self {
fb_info,
device_buffer: RwLock::new(device_buffer),
refresh_target: RwLock::new(None),
running: AtomicBool::new(false),

View File

@ -9,6 +9,7 @@ use alloc::{
vec::Vec,
};
use crate::driver::base::device::device_number::DeviceNumber;
use crate::filesystem::vfs::SpecialNodeData;
use crate::ipc::pipe::LockedPipeInode;
use crate::{
@ -1685,7 +1686,7 @@ impl IndexNode for LockedFATInode {
&self,
filename: &str,
mode: ModeType,
_dev_t: crate::driver::base::device::DeviceNumber,
_dev_t: DeviceNumber,
) -> Result<Arc<dyn IndexNode>, SystemError> {
let mut inode = self.0.lock();
if inode.metadata.file_type != FileType::Dir {

View File

@ -10,6 +10,7 @@ use alloc::{
use system_error::SystemError;
use crate::{
driver::base::device::device_number::DeviceNumber,
filesystem::vfs::{core::generate_inode_id, FileType},
ipc::pipe::LockedPipeInode,
libs::spinlock::{SpinLock, SpinLockGuard},
@ -475,7 +476,7 @@ impl IndexNode for LockedRamFSInode {
&self,
filename: &str,
mode: ModeType,
_dev_t: crate::driver::base::device::DeviceNumber,
_dev_t: DeviceNumber,
) -> Result<Arc<dyn IndexNode>, SystemError> {
let mut inode = self.0.lock();
if inode.metadata.file_type != FileType::Dir {

View File

@ -12,7 +12,9 @@ use alloc::{string::String, sync::Arc, vec::Vec};
use system_error::SystemError;
use crate::{
driver::base::{block::block_device::BlockDevice, char::CharDevice, device::DeviceNumber},
driver::base::{
block::block_device::BlockDevice, char::CharDevice, device::device_number::DeviceNumber,
},
ipc::pipe::LockedPipeInode,
libs::casting::DowncastArc,
time::TimeSpec,

View File

@ -9,7 +9,7 @@ use alloc::{
};
use system_error::SystemError;
use crate::{driver::base::device::DeviceNumber, libs::spinlock::SpinLock};
use crate::{driver::base::device::device_number::DeviceNumber, libs::spinlock::SpinLock};
use super::{
file::FileMode, syscall::ModeType, FilePrivateData, FileSystem, FileType, IndexNode, InodeId,

View File

@ -8,7 +8,7 @@ use alloc::{
use system_error::SystemError;
use crate::{
driver::base::{block::SeekFrom, device::DeviceNumber},
driver::base::{block::SeekFrom, device::device_number::DeviceNumber},
filesystem::vfs::file::FileDescriptorVec,
kerror,
libs::rwlock::RwLockWriteGuard,

View File

@ -0,0 +1,25 @@
use system_error::SystemError;
use unified_init::{define_public_unified_initializer_slice, unified_init};
define_public_unified_initializer_slice!(INITCALL_PURE);
define_public_unified_initializer_slice!(INITCALL_CORE);
define_public_unified_initializer_slice!(INITCALL_POSTCORE);
define_public_unified_initializer_slice!(INITCALL_ARCH);
define_public_unified_initializer_slice!(INITCALL_SUBSYS);
define_public_unified_initializer_slice!(INITCALL_FS);
define_public_unified_initializer_slice!(INITCALL_ROOTFS);
define_public_unified_initializer_slice!(INITCALL_DEVICE);
define_public_unified_initializer_slice!(INITCALL_LATE);
pub fn do_initcalls() -> Result<(), SystemError> {
unified_init!(INITCALL_PURE);
unified_init!(INITCALL_CORE);
unified_init!(INITCALL_POSTCORE);
unified_init!(INITCALL_ARCH);
unified_init!(INITCALL_SUBSYS);
unified_init!(INITCALL_FS);
unified_init!(INITCALL_ROOTFS);
unified_init!(INITCALL_DEVICE);
unified_init!(INITCALL_LATE);
return Ok(());
}

View File

@ -1,6 +1,7 @@
//! 这个文件内放置初始内核线程的代码。
use alloc::string::String;
use system_error::SystemError;
use crate::{
arch::process::arch_switch_to_user,
@ -13,8 +14,23 @@ use crate::{
process::{kthread::KernelThreadMechanism, process::stdio_init},
};
use super::initcall::do_initcalls;
pub fn initial_kernel_thread() -> i32 {
kernel_init().unwrap_or_else(|err| {
panic!("Failed to initialize kernel: {:?}", err);
});
switch_to_user();
loop {}
}
fn kernel_init() -> Result<(), SystemError> {
kenrel_init_freeable()?;
KernelThreadMechanism::init_stage2();
// 由于目前加锁,速度过慢,所以先不开启双缓冲
// scm_enable_double_buffer().expect("Failed to enable double buffer");
stdio_init().expect("Failed to initialize stdio");
@ -31,9 +47,16 @@ pub fn initial_kernel_thread() -> i32 {
kdebug!("initial kernel thread done.");
switch_to_user();
return Ok(());
}
loop {}
#[inline(never)]
fn kenrel_init_freeable() -> Result<(), SystemError> {
do_initcalls().unwrap_or_else(|err| {
panic!("Failed to initialize subsystems: {:?}", err);
});
return Ok(());
}
/// 切换到用户态

View File

@ -1,9 +1,23 @@
use crate::{
driver::{tty::init::tty_early_init, video::VideoRefreshManager},
libs::lib_ui::screen_manager::scm_init,
driver::{
tty::init::tty_early_init,
video::{fbdev::base::BootTimeScreenInfo, VideoRefreshManager},
},
libs::{lib_ui::screen_manager::scm_init, rwlock::RwLock},
};
pub mod c_adapter;
mod c_adapter;
pub mod initcall;
pub mod initial_kthread;
/// 启动参数
static BOOT_PARAMS: RwLock<BootParams> = RwLock::new(BootParams::new());
#[inline(always)]
pub fn boot_params() -> &'static RwLock<BootParams> {
&BOOT_PARAMS
}
fn init_intertrait() {
intertrait::init_caster_map();
@ -15,3 +29,18 @@ pub fn init_before_mem_init() {
let video_ok = unsafe { VideoRefreshManager::video_init().is_ok() };
scm_init(video_ok);
}
#[derive(Debug)]
pub struct BootParams {
pub screen_info: BootTimeScreenInfo,
}
impl BootParams {
const DEFAULT: Self = BootParams {
screen_info: BootTimeScreenInfo::DEFAULT,
};
const fn new() -> Self {
Self::DEFAULT
}
}

View File

@ -3,6 +3,7 @@
#![feature(allocator_api)]
#![feature(arbitrary_self_types)]
#![feature(asm_const)]
#![feature(const_for)]
#![feature(const_mut_refs)]
#![feature(const_trait_impl)]
#![feature(const_refs_to_cell)]

View File

@ -15,14 +15,13 @@ use system_error::SystemError;
use crate::{
arch::{sched::sched, CurrentIrqArch},
exception::InterruptArch,
init::initial_kthread::initial_kernel_thread,
kdebug, kinfo,
libs::{once::Once, spinlock::SpinLock},
process::{ProcessManager, ProcessState},
};
use super::{
fork::CloneFlags, init::initial_kernel_thread, Pid, ProcessControlBlock, ProcessFlags,
};
use super::{fork::CloneFlags, Pid, ProcessControlBlock, ProcessFlags};
/// 内核线程的创建任务列表
static KTHREAD_CREATE_LIST: SpinLock<LinkedList<Arc<KernelThreadCreateInfo>>> =

View File

@ -59,7 +59,6 @@ pub mod exec;
pub mod exit;
pub mod fork;
pub mod idle;
pub mod init;
pub mod kthread;
pub mod pid;
pub mod process;

View File

@ -5,6 +5,7 @@ use core::{
use crate::{
arch::{ipc::signal::SigSet, syscall::nr::*},
driver::base::device::device_number::DeviceNumber,
libs::{futex::constant::FutexFlag, rand::GRandFlags},
process::{
fork::KernelCloneArgs,
@ -681,11 +682,7 @@ impl Syscall {
let flags = args[1];
let dev_t = args[2];
let flags: ModeType = ModeType::from_bits_truncate(flags as u32);
Self::mknod(
path as *const i8,
flags,
crate::driver::base::device::DeviceNumber::from(dev_t),
)
Self::mknod(path as *const i8, flags, DeviceNumber::from(dev_t as u32))
}
SYS_CLONE => {

View File

@ -31,8 +31,8 @@ sqlite3.o: $(SQLITE3_DIR)/sqlite3.c
$(CC) $(CFLAGS) -c $(SQLITE3_DIR)/sqlite3.c -o sqlite3.o
__download_sqlite3:
@echo "Download sqlite3 from https://mirrors.ringotek.cn/pub/third_party/sqlite/$(SQLITE_FILENAME).zip"
@wget https://mirrors.ringotek.cn/pub/third_party/sqlite/$(SQLITE_FILENAME).zip || (@echo "Download sqlite3 failed" && rm $(SQLITE_FILENAME).zip && exit 1)
@echo "Download sqlite3 from https://mirrors.dragonos.org.cn/pub/third_party/sqlite/$(SQLITE_FILENAME).zip"
@wget https://mirrors.dragonos.org.cn/pub/third_party/sqlite/$(SQLITE_FILENAME).zip || (@echo "Download sqlite3 failed" && rm $(SQLITE_FILENAME).zip && exit 1)
@unzip -o $(SQLITE_FILENAME).zip || (@echo "Unzip sqlite3 failed" && exit 1)
@rm $(SQLITE_FILENAME).zip || (@echo "Remove $(SQLITE_FILENAME).zip failed" && exit 1)