diff --git a/kernel/src/arch/x86_64/driver/mod.rs b/kernel/src/arch/x86_64/driver/mod.rs index fc9ed153..076387a4 100644 --- a/kernel/src/arch/x86_64/driver/mod.rs +++ b/kernel/src/arch/x86_64/driver/mod.rs @@ -2,3 +2,4 @@ pub mod apic; mod c_adapter; pub mod hpet; pub mod tsc; +pub mod video; diff --git a/kernel/src/arch/x86_64/driver/video/mod.rs b/kernel/src/arch/x86_64/driver/video/mod.rs new file mode 100644 index 00000000..9f567cb8 --- /dev/null +++ b/kernel/src/arch/x86_64/driver/video/mod.rs @@ -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(()); +} diff --git a/kernel/src/driver/base/block/block_device.rs b/kernel/src/driver/base/block/block_device.rs index cede3f1f..466cad04 100644 --- a/kernel/src/driver/base/block/block_device.rs +++ b/kernel/src/driver/base/block/block_device.rs @@ -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 { + fn find_dynamic_major() -> Result { let blockdevs = BLOCKDEVS.lock(); // 寻找主设备号为234~255的设备 - 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)); // 返回可用的主设备号 } } } // 寻找主设备号在384~511的设备 - 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 { 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 { - 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 { 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, id_table: IdTable) -> Result<(), DeviceError> { - if Into::::into(id_table.device_number()) == 0 { + if id_table.device_number().data() == 0 { kerror!("Device number can't be 0!\n"); } todo!("bdev_add") diff --git a/kernel/src/driver/base/char/mod.rs b/kernel/src/driver/base/char/mod.rs index 1dd85bea..cf9483c3 100644 --- a/kernel/src/driver/base/char/mod.rs +++ b/kernel/src/driver/base/char/mod.rs @@ -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 { + fn find_dynamic_major() -> Result { let chardevs = CHARDEVS.lock(); // 寻找主设备号为234~255的设备 - 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)); // 返回可用的主设备号 } } } // 寻找主设备号在384~511的设备 - 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 { 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 { - 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 { 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::::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())?; diff --git a/kernel/src/driver/base/class.rs b/kernel/src/driver/base/class.rs index 185e571d..059ae543 100644 --- a/kernel/src/driver/base/class.rs +++ b/kernel/src/driver/base/class.rs @@ -85,11 +85,8 @@ 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()); - } + if matcher.match_device(&dev, data) { + return Some(dev.clone()); } } return None; diff --git a/kernel/src/driver/base/cpu.rs b/kernel/src/driver/base/cpu.rs index 3fc91931..c9f87cb4 100644 --- a/kernel/src/driver/base/cpu.rs +++ b/kernel/src/driver/base/cpu.rs @@ -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>, - bus: Option>, + bus: Option>, kset: Option>, name: String, kern_inode: Option>, @@ -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>) { + fn set_bus(&self, bus: Option>) { self.inner.write().bus = bus; } + fn bus(&self) -> Option> { + self.inner.read().bus.clone() + } + fn driver(&self) -> Option> { None } diff --git a/kernel/src/driver/base/device/bus.rs b/kernel/src/driver/base/device/bus.rs index 8ee42c09..00584226 100644 --- a/kernel/src/driver/base/device/bus.rs +++ b/kernel/src/driver/base/device/bus.rs @@ -159,11 +159,14 @@ pub trait Bus: Debug + Send + Sync { /// - `Ok(true)` - 匹配成功 /// - `Ok(false)` - 匹配失败 /// - `Err(_)` - 由于内部错误导致匹配失败 + /// - `Err(SystemError::ENOSYS)` - 该总线不支持该操作 fn match_device( &self, - device: &Arc, - driver: &Arc, - ) -> Result; + _device: &Arc, + _driver: &Arc, + ) -> Result { + return Err(SystemError::ENOSYS); + } fn subsystem(&self) -> &SubSysPrivate; @@ -188,11 +191,8 @@ 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()); - } + if matcher.match_device(&dev, data) { + return Some(dev.clone()); } } return None; @@ -221,11 +221,8 @@ 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()); - } + 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) -> 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) -> 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,10 +436,7 @@ impl BusManager { #[allow(dead_code)] pub fn rescan_devices(&self, bus: &Arc) -> Result<(), SystemError> { for dev in bus.subsystem().devices().iter() { - let dev = dev.upgrade(); - if let Some(dev) = dev { - rescan_devices_helper(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) { - 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) -> Result<(), SystemError> { +fn rescan_devices_helper(dev: &Arc) -> 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) -> 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) { + 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) diff --git a/kernel/src/driver/base/device/dd.rs b/kernel/src/driver/base/device/dd.rs index ec94d47b..0e5d0345 100644 --- a/kernel/src/driver/base/device/dd.rs +++ b/kernel/src/driver/base/device/dd.rs @@ -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,14 +80,21 @@ 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; + 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, - _data: &mut DeviceAttachData, - ) -> Result<(), SystemError> { - todo!("do_device_attach_driver") + driver: &Arc, + data: &mut DeviceAttachData, + ) -> Result { + 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,13 +281,15 @@ impl DriverManager { /// 这个函数会遍历驱动现有的全部设备,然后尝试把他们匹配。 /// 一旦有一个设备匹配成功,就会返回,并且设备的driver字段会被设置。 pub fn driver_attach(&self, driver: &Arc) -> 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(()); - } + if self.do_driver_attach(&dev, &driver) { + // 匹配成功 + return Ok(()); } } @@ -274,7 +324,12 @@ impl DriverManager { driver: &Arc, device: &Arc, ) -> Result { - 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) -> 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, driver: &Arc, ) -> 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), diff --git a/kernel/src/driver/base/device/device_number.rs b/kernel/src/driver/base/device/device_number.rs new file mode 100644 index 00000000..a9d9482b --- /dev/null +++ b/kernel/src/driver/base/device/device_number.rs @@ -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 for DeviceNumber { + fn from(x: u32) -> Self { + Self { data: x } + } +} diff --git a/kernel/src/driver/base/device/driver.rs b/kernel/src/driver/base/device/driver.rs index dedd28d3..344803c7 100644 --- a/kernel/src/driver/base/device/driver.rs +++ b/kernel/src/driver/base/device/driver.rs @@ -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> { + fn bus(&self) -> Option> { None } - fn set_bus(&self, bus: Option>); + fn set_bus(&self, bus: Option>); fn groups(&self) -> &'static [&'static dyn AttributeGroup] { &[] @@ -171,13 +174,17 @@ impl DriverManager { /// /// 参考 https://opengrok.ringotek.cn/xref/linux-6.1.9/drivers/base/driver.c#222 pub fn register(&self, driver: Arc) -> Result<(), SystemError> { - let bus = driver.bus().ok_or_else(|| { - kerror!( - "DriverManager::register() failed: driver.bus() is None. Driver: '{:?}'", - driver.name() - ); - SystemError::EINVAL - })?; + let bus = driver + .bus() + .map(|bus| bus.upgrade()) + .flatten() + .ok_or_else(|| { + kerror!( + "DriverManager::register() failed: driver.bus() is None. Driver: '{:?}'", + driver.name() + ); + SystemError::EINVAL + })?; let drv_name = driver.name(); let other = bus.find_driver_by_name(&drv_name); diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index 7b0152cf..cfd46405 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/kernel/src/driver/base/device/mod.rs @@ -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> { + fn bus(&self) -> Option> { return None; } /// 设置当前设备所属的总线 /// - /// (一定要传入Arc,因为bus的subsysprivate里面存储的是Device的Weak指针) - fn set_bus(&self, bus: Option>); + /// (一定要传入Arc,因为bus的subsysprivate里面存储的是Device的Arc指针) + /// + /// 注意,如果实现了当前方法,那么必须实现`bus()`方法 + fn set_bus(&self, bus: Option>); /// 获取当前设备所属的类 fn class(&self) -> Option> { @@ -158,6 +162,8 @@ pub trait Device: KObject { } /// 设置当前设备所属的类 + /// + /// 注意,如果实现了当前方法,那么必须实现`class()`方法 fn set_class(&self, class: Option>); /// 返回已经与当前设备匹配好的驱动程序 @@ -221,62 +227,6 @@ impl DevicePrivateData { } } -int_like!(DeviceNumber, usize); - -impl Default for DeviceNumber { - fn default() -> Self { - DeviceNumber(0) - } -} - -impl From for DeviceNumber { - fn from(dev_t: usize) -> Self { - DeviceNumber(dev_t) - } -} - -impl Into for DeviceNumber { - fn into(self) -> usize { - self.0 - } -} - -impl core::hash::Hash for DeviceNumber { - fn hash(&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) -> 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) { - 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)); } @@ -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) -> Result<(), SystemError> { let class = dev.class(); if class.is_none() { @@ -635,6 +581,10 @@ impl DeviceManager { // 定义错误处理函数,用于在添加符号链接失败时,移除已经添加的符号链接 + let err_remove_device = |dev_kobj: &Arc| { + sysfs_instance().remove_link(dev_kobj, "device".to_string()); + }; + let err_remove_subsystem = |dev_kobj: &Arc| { 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; + 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; - return sysfs_instance().create_link(Some(¤t_kobj), &target_kobj, name); + return sysfs_instance().create_link(Some(&target_kobj), ¤t_kobj, name); } /// Delete symlink for device in `/sys/dev` or `/sys/class/` @@ -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) { 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); } diff --git a/kernel/src/driver/base/init.rs b/kernel/src/driver/base/init.rs index ac95cb6b..6629f903 100644 --- a/kernel/src/driver/base/init.rs +++ b/kernel/src/driver/base/init.rs @@ -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(()); } diff --git a/kernel/src/driver/base/kobject.rs b/kernel/src/driver/base/kobject.rs index 9dc814ff..74bd8cf7 100644 --- a/kernel/src/driver/base/kobject.rs +++ b/kernel/src/driver/base/kobject.rs @@ -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; - fn store(&self, kobj: &dyn KObject, buf: &[u8]) -> Result; +impl Default for LockedKObjectState { + fn default() -> Self { + LockedKObjectState::new(None) + } } #[derive(Debug)] diff --git a/kernel/src/driver/base/map/mod.rs b/kernel/src/driver/base/map/mod.rs index eee439cd..08a61617 100644 --- a/kernel/src/driver/base/map/mod.rs +++ b/kernel/src/driver/base/map/mod.rs @@ -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, ) { - 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, 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::::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, dev_t: DeviceNumber, range: usize) /// @return: 查找成功,返回设备实例,否则返回None #[allow(dead_code)] pub fn kobj_lookup(domain: Arc, dev_t: DeviceNumber) -> Option> { - 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>); 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 } } diff --git a/kernel/src/driver/base/platform/mod.rs b/kernel/src/driver/base/platform/mod.rs index d2836f7f..1bd3bc6a 100644 --- a/kernel/src/driver/base/platform/mod.rs +++ b/kernel/src/driver/base/platform/mod.rs @@ -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::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))), diff --git a/kernel/src/driver/base/platform/platform_device.rs b/kernel/src/driver/base/platform/platform_device.rs index 8af5e5d5..d6aff24c 100644 --- a/kernel/src/driver/base/platform/platform_device.rs +++ b/kernel/src/driver/base/platform/platform_device.rs @@ -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)); + pdev.set_bus(Some(Arc::downgrade(&(platform_bus() as Arc)))); let id = pdev.pdev_id().0; match id { @@ -195,7 +195,7 @@ pub struct InnerPlatformBusDevice { kernfs_inode: Option>, /// 当前设备挂载到的总线 - bus: Option>, + bus: Option>, /// 当前设备已经匹配的驱动 driver: Option>, @@ -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> { + fn bus(&self) -> Option> { self.inner.lock().bus.clone() } - fn set_bus(&self, bus: Option>) { + fn set_bus(&self, bus: Option>) { self.inner.lock().bus = bus; } diff --git a/kernel/src/driver/base/platform/platform_driver.rs b/kernel/src/driver/base/platform/platform_driver.rs index 36f3799b..d0fb5fed 100644 --- a/kernel/src/driver/base/platform/platform_driver.rs +++ b/kernel/src/driver/base/platform/platform_driver.rs @@ -19,7 +19,7 @@ use super::{platform_bus, platform_device::PlatformDevice}; pub trait PlatformDriver: Driver { /// 检测设备是否能绑定到这个驱动 /// - /// 如果能,则把设备的driver指向这个驱动。 + /// 如果能,则把设备的driver字段指向这个驱动。 /// 请注意,这个函数不应该把driver加入驱动的devices列表,相关工作会在外部的函数里面处理。 fn probe(&self, device: &Arc) -> Result<(), SystemError>; fn remove(&self, device: &Arc) -> 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) -> Result<(), SystemError> { - driver.set_bus(Some(platform_bus() as Arc)); + driver.set_bus(Some(Arc::downgrade(&(platform_bus() as Arc)))); return driver_manager().register(driver as Arc); } diff --git a/kernel/src/driver/base/subsys.rs b/kernel/src/driver/base/subsys.rs index a74f7efb..15018211 100644 --- a/kernel/src/driver/base/subsys.rs +++ b/kernel/src/driver/base/subsys.rs @@ -37,9 +37,9 @@ pub struct SubSysPrivate { class: SpinLock>>, drivers_autoprobe: AtomicBool, /// 当前总线上的所有设备 - devices: RwLock>>, + devices: RwLock>>, /// 当前总线上的所有驱动 - drivers: RwLock>>, + drivers: RwLock>>, interfaces: &'static [&'static dyn SubSysInterface], bus_notifier: AtomicNotifierChain>, } @@ -106,11 +106,11 @@ impl SubSysPrivate { *self.class.lock() = class; } - pub fn devices(&self) -> RwLockReadGuard>> { + pub fn devices(&self) -> RwLockReadGuard>> { return self.devices.read(); } - pub fn drivers(&self) -> RwLockReadGuard>> { + pub fn drivers(&self) -> RwLockReadGuard>> { return self.drivers.read(); } @@ -155,18 +155,16 @@ impl SubSysPrivate { pub fn add_driver_to_vec(&self, driver: &Arc) -> 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) { 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) -> 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) { 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); } diff --git a/kernel/src/driver/disk/ahci/ahcidisk.rs b/kernel/src/driver/disk/ahci/ahcidisk.rs index 16e700bb..b098e0e2 100644 --- a/kernel/src/driver/disk/ahci/ahcidisk.rs +++ b/kernel/src/driver/disk/ahci/ahcidisk.rs @@ -499,11 +499,11 @@ impl Device for LockedAhciDisk { todo!() } - fn bus(&self) -> Option> { + fn bus(&self) -> Option> { todo!("LockedAhciDisk::bus()") } - fn set_bus(&self, _bus: Option>) { + fn set_bus(&self, _bus: Option>) { todo!("LockedAhciDisk::set_bus()") } diff --git a/kernel/src/driver/net/e1000e/e1000e_driver.rs b/kernel/src/driver/net/e1000e/e1000e_driver.rs index 8534145f..29a09815 100644 --- a/kernel/src/driver/net/e1000e/e1000e_driver.rs +++ b/kernel/src/driver/net/e1000e/e1000e_driver.rs @@ -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> { + fn bus(&self) -> Option> { todo!() } - fn set_bus(&self, _bus: Option>) { + fn set_bus(&self, _bus: Option>) { todo!() } } diff --git a/kernel/src/driver/net/virtio_net.rs b/kernel/src/driver/net/virtio_net.rs index d7071667..c4a0ee41 100644 --- a/kernel/src/driver/net/virtio_net.rs +++ b/kernel/src/driver/net/virtio_net.rs @@ -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 Driver for VirtioInterface { todo!() } - fn bus(&self) -> Option> { + fn bus(&self) -> Option> { todo!() } - fn set_bus(&self, _bus: Option>) { + fn set_bus(&self, _bus: Option>) { todo!() } } diff --git a/kernel/src/driver/tty/serial/mod.rs b/kernel/src/driver/tty/serial/mod.rs index 331c02ce..8c7faddb 100644 --- a/kernel/src/driver/tty/serial/mod.rs +++ b/kernel/src/driver/tty/serial/mod.rs @@ -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; diff --git a/kernel/src/driver/tty/serial/serial8250/mod.rs b/kernel/src/driver/tty/serial/serial8250/mod.rs index 0f88d720..e10f45a4 100644 --- a/kernel/src/driver/tty/serial/serial8250/mod.rs +++ b/kernel/src/driver/tty/serial/serial8250/mod.rs @@ -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), + ))); // todo: 把驱动注册到uart层、tty层 uart_manager().register_driver(&(serial8250_isa_driver.clone() as Arc))?; @@ -216,11 +219,11 @@ impl Device for Serial8250ISADevices { fn is_dead(&self) -> bool { false } - fn bus(&self) -> Option> { + fn bus(&self) -> Option> { self.inner.read().bus.clone() } - fn set_bus(&self, bus: Option>) { + fn set_bus(&self, bus: Option>) { 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> { @@ -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>, parent_kobj: Option>, /// 当前设备所述的总线 - bus: Option>, + bus: Option>, inode: Option>, driver: Option>, device_state: DeviceState, @@ -351,7 +354,7 @@ enum Serial8250PlatformDeviceID { #[derive(Debug)] struct InnerSerial8250ISADriver { - bus: Option>, + bus: Option>, kobj_type: Option<&'static dyn KObjType>, kset: Option>, parent_kobj: Option>, @@ -486,11 +489,11 @@ impl Driver for Serial8250ISADriver { inner.devices.retain(|d| !Arc::ptr_eq(d, device)); } - fn bus(&self) -> Option> { + fn bus(&self) -> Option> { self.inner.read().bus.clone() } - fn set_bus(&self, bus: Option>) { + fn set_bus(&self, bus: Option>) { self.inner.write().bus = bus; } } diff --git a/kernel/src/driver/tty/tty_device.rs b/kernel/src/driver/tty/tty_device.rs index d41d7d7d..f5c534a7 100644 --- a/kernel/src/driver/tty/tty_device.rs +++ b/kernel/src/driver/tty/tty_device.rs @@ -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::new("tty0"); let devfs_root_inode = ROOT_INODE().lookup("/dev"); diff --git a/kernel/src/driver/video/fbdev/base/fbcon.rs b/kernel/src/driver/video/fbdev/base/fbcon.rs index b58a0238..d1ff6714 100644 --- a/kernel/src/driver/video/fbdev/base/fbcon.rs +++ b/kernel/src/driver/video/fbdev/base/fbcon.rs @@ -85,7 +85,7 @@ struct InnerFbConsoleDevice { kernfs_inode: Option>, parent: Option>, kset: Option>, - bus: Option>, + bus: Option>, driver: Option>, 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>) { + fn set_bus(&self, bus: Option>) { self.inner.lock().bus = bus; } + fn bus(&self) -> Option> { + self.inner.lock().bus.clone() + } + fn set_class(&self, _class: Option>) { // 不允许修改 kwarn!("fbcon's class can not be changed"); diff --git a/kernel/src/driver/video/fbdev/base/fbmem.rs b/kernel/src/driver/video/fbdev/base/fbmem.rs index 20951ab9..16bbdeb0 100644 --- a/kernel/src/driver/video/fbdev/base/fbmem.rs +++ b/kernel/src/driver/video/fbdev/base/fbmem.rs @@ -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::{ - class::{class_manager, Class}, - device::sys_dev_char_kset, - init::SUBSYSTEM_INITIALIZER_SLICE, - kobject::KObject, - subsys::SubSysPrivate, +use crate::{ + driver::base::{ + class::{class_manager, Class}, + 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> = 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> { 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))?; @@ -76,3 +103,236 @@ impl Class for GraphicsClass { return &self.subsystem; } } + +/// 帧缓冲区管理器 +#[derive(Debug)] +pub struct FrameBufferManager { + inner: RwLock, +} + +#[derive(Debug)] +struct InnerFrameBufferManager { + /// 已经注册的帧缓冲区 + registered_fbs: [Option>; 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) -> Result { + 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, id); + device_manager().device_default_initialize(&(fb_device.clone() as Arc)); + fb_device.set_parent(Some(Arc::downgrade(&(fb.clone() as Arc)))); + + fb.set_fb_device(Some(fb_device.clone())); + + device_manager().add_device(fb_device.clone() as Arc)?; + + // 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); + + // 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) -> Result<(), SystemError> { + todo!("unregister_fb") + } + + /// 根据id查找帧缓冲区 + pub fn find_fb_by_id(&self, id: FbId) -> Result>, 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 { + 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, + kobj_state: LockedKObjectState, +} + +impl FbDevice { + pub const BASENAME: &'static str = "fb"; + fn new(fb: Weak, id: FbId) -> Arc { + 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> { + self.inner.lock().fb.upgrade() + } +} + +#[derive(Debug)] +struct InnerFbDevice { + fb: Weak, + kern_inode: Option>, + parent: Option>, + kset: Option>, + 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>) { + self.inner.lock().kern_inode = inode; + } + + fn inode(&self) -> Option> { + self.inner.lock().kern_inode.clone() + } + + fn parent(&self) -> Option> { + self.inner.lock().parent.clone() + } + + fn set_parent(&self, parent: Option>) { + self.inner.lock().parent = parent; + } + + fn kset(&self) -> Option> { + self.inner.lock().kset.clone() + } + + fn set_kset(&self, kset: Option>) { + 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 { + self.kobj_state.read() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + 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>) { + todo!() + } + + fn class(&self) -> Option> { + sys_class_graphics_instance().map(|ins| ins.clone() as Arc) + } + fn set_class(&self, _class: Option>) { + // do nothing + } + + fn driver(&self) -> Option> { + None + } + + fn set_driver(&self, _driver: Option>) { + // 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]) + } +} diff --git a/kernel/src/driver/video/fbdev/base/fbsysfs.rs b/kernel/src/driver/video/fbdev/base/fbsysfs.rs new file mode 100644 index 00000000..df6aa938 --- /dev/null +++ b/kernel/src/driver/video/fbdev/base/fbsysfs.rs @@ -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, + _attr: &'static dyn Attribute, + ) -> Option { + 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, buf: &mut [u8]) -> Result { + let fb_dev = kobj.arc_any().downcast::().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, _buf: &[u8]) -> Result { + kwarn!("attr bits_per_pixel store not implemented"); + return Err(SystemError::ENOSYS); + } + + fn show(&self, kobj: Arc, buf: &mut [u8]) -> Result { + let fb_dev = kobj.arc_any().downcast::().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, _buf: &[u8]) -> Result { + 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, _buf: &mut [u8]) -> Result { + 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, _buf: &[u8]) -> Result { + 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, _buf: &mut [u8]) -> Result { + 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, _buf: &[u8]) -> Result { + 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, buf: &mut [u8]) -> Result { + let fb_dev = kobj.arc_any().downcast::().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, _buf: &[u8]) -> Result { + 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, buf: &mut [u8]) -> Result { + let fb_dev = kobj.arc_any().downcast::().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, _buf: &[u8]) -> Result { + 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, buf: &mut [u8]) -> Result { + let fb_dev = kobj.arc_any().downcast::().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, buf: &mut [u8]) -> Result { + let fb_dev = kobj.arc_any().downcast::().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, _buf: &[u8]) -> Result { + 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, buf: &mut [u8]) -> Result { + let fb_dev = kobj.arc_any().downcast::().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, _buf: &[u8]) -> Result { + todo!("AttrState::store") + } +} diff --git a/kernel/src/driver/video/fbdev/base/mod.rs b/kernel/src/driver/video/fbdev/base/mod.rs index 6c7302b5..29436e31 100644 --- a/kernel/src/driver/video/fbdev/base/mod.rs +++ b/kernel/src/driver/video/fbdev/base/mod.rs @@ -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>; + + /// 设置当前帧缓冲区对应的`/sys/class/graphics/fb0`或者`/sys/class/graphics/fb1`等的设备结构体 + fn set_fb_device(&self, device: Option>); + + /// 获取帧缓冲区的状态 + 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, + /// 帧缓冲区的宽度(像素) None表示未知 + pub width: Option, /// 像素时钟(皮秒) 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, // 帧缓冲区的长度 - 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, // 内存映射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, + /// 线性帧缓冲区的长度 + 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, +} diff --git a/kernel/src/driver/video/fbdev/base/modedb.rs b/kernel/src/driver/video/fbdev/base/modedb.rs new file mode 100644 index 00000000..b44d182a --- /dev/null +++ b/kernel/src/driver/video/fbdev/base/modedb.rs @@ -0,0 +1,3 @@ +//! todo: 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/video/fbdev/core/modedb.c +//! +//! 实现modedb diff --git a/kernel/src/driver/video/fbdev/mod.rs b/kernel/src/driver/video/fbdev/mod.rs index 6cf245d4..44ea30c2 100644 --- a/kernel/src/driver/video/fbdev/mod.rs +++ b/kernel/src/driver/video/fbdev/mod.rs @@ -1 +1,2 @@ pub mod base; +pub mod vesafb; diff --git a/kernel/src/driver/video/fbdev/vesafb.rs b/kernel/src/driver/video/fbdev/vesafb.rs new file mode 100644 index 00000000..3b91e0fc --- /dev/null +++ b/kernel/src/driver/video/fbdev/vesafb.rs @@ -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 = RwLock::new(FixedScreenInfo { + id: FixedScreenInfo::name2id("VESA VGA"), + fb_type: FbType::PackedPixels, + accel: FbAccel::None, + ..Default::default() + }); + static ref VESAFB_DEFINED: RwLock = 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, + 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>, + class: Option>, + driver: Option>, + kern_inode: Option>, + parent: Option>, + kset: Option>, + kobj_type: Option<&'static dyn KObjType>, + device_state: DeviceState, + pdev_id: i32, + pdev_id_auto: bool, + fb_id: FbId, + fb_device: Option>, + 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> { + self.inner.lock().bus.clone() + } + + fn set_bus(&self, bus: Option>) { + self.inner.lock().bus = bus; + } + + fn set_class(&self, class: Option>) { + self.inner.lock().class = class; + } + + fn driver(&self) -> Option> { + self.inner.lock().driver.clone()?.upgrade() + } + + fn set_driver(&self, driver: Option>) { + 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>) { + self.inner.lock().kern_inode = inode; + } + + fn inode(&self) -> Option> { + self.inner.lock().kern_inode.clone() + } + + fn parent(&self) -> Option> { + self.inner.lock().parent.clone() + } + + fn set_parent(&self, parent: Option>) { + self.inner.lock().parent = parent; + } + + fn kset(&self) -> Option> { + self.inner.lock().kset.clone() + } + + fn set_kset(&self, kset: Option>) { + 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 { + self.kobj_state.read() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + 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> { + self.inner.lock().fb_device.clone() + } + + fn set_fb_device(&self, device: Option>) { + 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, + kobj_state: LockedKObjectState, +} + +impl VesaFbDriver { + pub fn new() -> Arc { + 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>, + parent: Option>, + kernfs_inode: Option>, + devices: Vec>, + bus: Option>, + + self_ref: Weak, +} + +impl VesaFbDriver { + const NAME: &'static str = "vesa-framebuffer"; +} + +impl PlatformDriver for VesaFbDriver { + fn probe(&self, device: &Arc) -> Result<(), SystemError> { + let device = device + .clone() + .arc_any() + .downcast::() + .map_err(|_| SystemError::EINVAL)?; + + device.set_driver(Some(self.inner.lock_irqsave().self_ref.clone())); + + return Ok(()); + } + + fn remove(&self, _device: &Arc) -> Result<(), SystemError> { + todo!() + } + + fn shutdown(&self, _device: &Arc) -> Result<(), SystemError> { + // do nothing + return Ok(()); + } + + fn suspend(&self, _device: &Arc) -> Result<(), SystemError> { + // do nothing + return Ok(()); + } + + fn resume(&self, _device: &Arc) -> Result<(), SystemError> { + todo!() + } +} + +impl Driver for VesaFbDriver { + fn id_table(&self) -> Option { + Some(IdTable::new(VesaFb::NAME.to_string(), None)) + } + + fn devices(&self) -> Vec> { + self.inner.lock().devices.clone() + } + + fn add_device(&self, device: Arc) { + 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) { + let mut guard = self.inner.lock(); + guard.devices.retain(|dev| !Arc::ptr_eq(dev, device)); + } + + fn set_bus(&self, bus: Option>) { + self.inner.lock().bus = bus; + } + + fn bus(&self) -> Option> { + 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>) { + self.inner.lock().kernfs_inode = inode; + } + + fn inode(&self) -> Option> { + self.inner.lock().kernfs_inode.clone() + } + + fn parent(&self) -> Option> { + self.inner.lock().parent.clone() + } + + fn set_parent(&self, parent: Option>) { + self.inner.lock().parent = parent; + } + + fn kset(&self) -> Option> { + self.inner.lock().kset.clone() + } + + fn set_kset(&self, kset: Option>) { + 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 { + self.kobj_state.read() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + 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, + attr: &'static dyn Attribute, + ) -> Option { + 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, buf: &mut [u8]) -> Result { + 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 { + let mut _reserved: u32 = 0; + + let mut fb_info: MaybeUninit = 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)); + + platform_device_manager() + .device_add(device.clone() as Arc) + .expect("vesa_fb_device_init: platform_device_manager().device_add failed"); + + frame_buffer_manager() + .register_fb(device.clone() as Arc) + .expect("vesa_fb_device_init: frame_buffer_manager().register_fb failed"); + + // 设置vesa fb的状态为运行中 + device.inner.lock().fb_state = FbState::Running; + }); + + return Ok(()); +} diff --git a/kernel/src/driver/video/mod.rs b/kernel/src/driver/video/mod.rs index 97cc0da3..7559114e 100644 --- a/kernel/src/driver/video/mod.rs +++ b/kernel/src/driver/video/mod.rs @@ -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, - fb_info: multiboot_tag_framebuffer_info_t, refresh_target: RwLock>>>>, 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 = 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, - buf_vaddr, - ) - .unwrap(); + arch_video_early_init()?; - let init_text = "Video driver to map.\n\0"; - send_to_default_serial8250_port(init_text.as_bytes()); + 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 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); + 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(); + } 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), diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 3e7353bf..f642210d 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -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, SystemError> { let mut inode = self.0.lock(); if inode.metadata.file_type != FileType::Dir { diff --git a/kernel/src/filesystem/ramfs/mod.rs b/kernel/src/filesystem/ramfs/mod.rs index b74b9f46..5b214660 100644 --- a/kernel/src/filesystem/ramfs/mod.rs +++ b/kernel/src/filesystem/ramfs/mod.rs @@ -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, SystemError> { let mut inode = self.0.lock(); if inode.metadata.file_type != FileType::Dir { diff --git a/kernel/src/filesystem/vfs/mod.rs b/kernel/src/filesystem/vfs/mod.rs index e82e12f7..4dbc81d0 100644 --- a/kernel/src/filesystem/vfs/mod.rs +++ b/kernel/src/filesystem/vfs/mod.rs @@ -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, diff --git a/kernel/src/filesystem/vfs/mount.rs b/kernel/src/filesystem/vfs/mount.rs index e92605e8..31bca7a8 100644 --- a/kernel/src/filesystem/vfs/mount.rs +++ b/kernel/src/filesystem/vfs/mount.rs @@ -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, diff --git a/kernel/src/filesystem/vfs/syscall.rs b/kernel/src/filesystem/vfs/syscall.rs index 7875d207..77c1f3a3 100644 --- a/kernel/src/filesystem/vfs/syscall.rs +++ b/kernel/src/filesystem/vfs/syscall.rs @@ -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, diff --git a/kernel/src/init/initcall.rs b/kernel/src/init/initcall.rs new file mode 100644 index 00000000..a9e25690 --- /dev/null +++ b/kernel/src/init/initcall.rs @@ -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(()); +} diff --git a/kernel/src/process/init.rs b/kernel/src/init/initial_kthread.rs similarity index 72% rename from kernel/src/process/init.rs rename to kernel/src/init/initial_kthread.rs index 2d2d7210..20462733 100644 --- a/kernel/src/process/init.rs +++ b/kernel/src/init/initial_kthread.rs @@ -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(()); } /// 切换到用户态 diff --git a/kernel/src/init/mod.rs b/kernel/src/init/mod.rs index 42bae686..c92a4f6f 100644 --- a/kernel/src/init/mod.rs +++ b/kernel/src/init/mod.rs @@ -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 = RwLock::new(BootParams::new()); + +#[inline(always)] +pub fn boot_params() -> &'static RwLock { + &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 + } +} diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 3539c80f..36070872 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -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)] diff --git a/kernel/src/process/kthread.rs b/kernel/src/process/kthread.rs index f7567a00..a1c8f169 100644 --- a/kernel/src/process/kthread.rs +++ b/kernel/src/process/kthread.rs @@ -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>> = diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index c68779a1..f3008d69 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -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; diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 57c0aeb9..2c79b6c5 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -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 => { diff --git a/user/apps/test_sqlite3/Makefile b/user/apps/test_sqlite3/Makefile index 7d3ed8f3..1bbbca5f 100644 --- a/user/apps/test_sqlite3/Makefile +++ b/user/apps/test_sqlite3/Makefile @@ -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)