diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 1ee10e78..bed290b0 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -47,12 +47,13 @@ num-traits = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/num smoltcp = { version = "=0.11.0", default-features = false, features = ["log", "alloc", "socket-raw", "socket-udp", "socket-tcp", "socket-icmp", "socket-dhcpv4", "socket-dns", "proto-ipv4", "proto-ipv6"]} system_error = { path = "crates/system_error" } unified-init = { path = "crates/unified-init" } -virtio-drivers = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/virtio-drivers.git", rev = "61ece509c4" } +virtio-drivers = { git = "https://git.mirrors.dragonos.org.cn/DragonOS-Community/virtio-drivers", rev = "448a781" } fdt = "=0.1.5" uefi = { version = "=0.26.0", features = ["alloc"] } uefi-raw = "=0.5.0" paste = "=1.0.14" slabmalloc = { path = "crates/rust-slabmalloc" } +log = "0.4.21" # target为x86_64时,使用下面的依赖 diff --git a/kernel/src/arch/riscv64/mm/mod.rs b/kernel/src/arch/riscv64/mm/mod.rs index 44baed13..ad148cf4 100644 --- a/kernel/src/arch/riscv64/mm/mod.rs +++ b/kernel/src/arch/riscv64/mm/mod.rs @@ -110,7 +110,7 @@ impl MemoryManagementArch for RiscV64MMArch { const ENTRY_FLAG_READWRITE: usize = (1 << 2) | (1 << 1); const ENTRY_FLAG_USER: usize = (1 << 4); - + const ENTRY_ADDRESS_MASK: usize = Self::ENTRY_ADDRESS_SIZE - (1 << 10); const ENTRY_FLAG_WRITE_THROUGH: usize = (2 << 61); const ENTRY_FLAG_CACHE_DISABLE: usize = (2 << 61); diff --git a/kernel/src/arch/riscv64/pci/mod.rs b/kernel/src/arch/riscv64/pci/mod.rs index 43245143..c51efc91 100644 --- a/kernel/src/arch/riscv64/pci/mod.rs +++ b/kernel/src/arch/riscv64/pci/mod.rs @@ -5,10 +5,9 @@ use crate::{ arch::TraitPciArch, driver::{ open_firmware::fdt::open_firmware_fdt_driver, - pci::pci::{pci_init, BusDeviceFunction, PciAddr, PciError, SegmentGroupNumber}, + pci::pci::{pci_init, BusDeviceFunction, PciAddr}, }, - init::{boot_params, initcall::INITCALL_SUBSYS}, - kwarn, + init::initcall::INITCALL_SUBSYS, mm::PhysAddr, }; @@ -18,11 +17,11 @@ mod pci_host_ecam; pub struct RiscV64PciArch; impl TraitPciArch for RiscV64PciArch { - fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 { + fn read_config(_bus_device_function: &BusDeviceFunction, _offset: u8) -> u32 { unimplemented!("RiscV64PciArch::read_config") } - fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) { + fn write_config(_bus_device_function: &BusDeviceFunction, _offset: u8, _data: u32) { unimplemented!("RiscV64pci_root_0().write_config") } diff --git a/kernel/src/driver/base/device/dd.rs b/kernel/src/driver/base/device/dd.rs index e560cb65..7adb840b 100644 --- a/kernel/src/driver/base/device/dd.rs +++ b/kernel/src/driver/base/device/dd.rs @@ -72,6 +72,10 @@ impl DeviceManager { if dev.driver().is_some() { if self.device_is_bound(dev) { + kdebug!( + "do_device_attach: device '{}' is already bound.", + dev.name() + ); return Ok(true); } @@ -82,6 +86,7 @@ impl DeviceManager { return Ok(false); } } else { + kdebug!("do_device_attach: device '{}' is not bound.", dev.name()); let bus = dev .bus() .and_then(|bus| bus.upgrade()) @@ -198,15 +203,9 @@ impl DeviceManager { /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c#496 pub fn device_bind_driver(&self, dev: &Arc) -> Result<(), SystemError> { let r = driver_manager().driver_sysfs_add(dev); - if let Err(e) = r { - kerror!( - "device_bind_driver: driver_sysfs_add failed, dev: '{}', err: {:?}", - dev.name(), - e - ); + if r.is_ok() { self.device_links_force_bind(dev); driver_manager().driver_bound(dev); - return Err(e); } else if let Some(bus) = dev.bus().and_then(|bus| bus.upgrade()) { bus.subsystem().bus_notifier().call_chain( BusNotifyEvent::DriverNotBound, @@ -214,6 +213,14 @@ impl DeviceManager { None, ); } + + if let Err(e) = r.as_ref() { + kerror!( + "device_bind_driver: driver_sysfs_add failed, dev: '{}', err: {:?}", + dev.name(), + e + ); + } return r; } diff --git a/kernel/src/driver/base/device/mod.rs b/kernel/src/driver/base/device/mod.rs index 459eb842..2281d124 100644 --- a/kernel/src/driver/base/device/mod.rs +++ b/kernel/src/driver/base/device/mod.rs @@ -806,7 +806,7 @@ impl DeviceManager { /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/core.c?fi=device_links_force_bind#1226 pub fn device_links_force_bind(&self, _dev: &Arc) { - todo!("device_links_force_bind") + kwarn!("device_links_force_bind not implemented"); } /// 把device对象的一些结构进行默认初始化 diff --git a/kernel/src/driver/block/mod.rs b/kernel/src/driver/block/mod.rs index a5c08fdb..6a91ec54 100644 --- a/kernel/src/driver/block/mod.rs +++ b/kernel/src/driver/block/mod.rs @@ -1 +1,2 @@ pub mod cache; +pub mod virtio_blk; diff --git a/kernel/src/driver/block/virtio_blk.rs b/kernel/src/driver/block/virtio_blk.rs new file mode 100644 index 00000000..44937e9a --- /dev/null +++ b/kernel/src/driver/block/virtio_blk.rs @@ -0,0 +1,526 @@ +use core::{any::Any, fmt::Debug}; + +use alloc::{ + string::{String, ToString}, + sync::{Arc, Weak}, + vec::Vec, +}; +use system_error::SystemError; +use unified_init::macros::unified_init; +use virtio_drivers::device::blk::VirtIOBlk; + +use crate::{ + driver::{ + base::{ + block::{ + block_device::{BlockDevice, BlockId, LBA_SIZE}, + disk_info::Partition, + }, + class::Class, + device::{ + bus::Bus, + driver::{Driver, DriverCommonData}, + Device, DeviceCommonData, DeviceId, DeviceType, IdTable, + }, + kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, + kset::KSet, + }, + virtio::{ + sysfs::{virtio_bus, virtio_device_manager, virtio_driver_manager}, + transport::VirtIOTransport, + virtio_impl::HalImpl, + VirtIODevice, VirtIODeviceIndex, VirtIODriver, VIRTIO_VENDOR_ID, + }, + }, + filesystem::{kernfs::KernFSInode, mbr::MbrDiskPartionTable}, + init::initcall::INITCALL_POSTCORE, + libs::{ + rwlock::{RwLockReadGuard, RwLockWriteGuard}, + spinlock::{SpinLock, SpinLockGuard}, + }, +}; + +const VIRTIO_BLK_BASENAME: &str = "virtio_blk"; + +static mut VIRTIO_BLK_DRIVER: Option> = None; + +#[inline(always)] +fn virtio_blk_driver() -> Arc { + unsafe { VIRTIO_BLK_DRIVER.as_ref().unwrap().clone() } +} + +/// Get the first virtio block device +#[allow(dead_code)] +pub fn virtio_blk_0() -> Option> { + virtio_blk_driver() + .devices() + .first() + .cloned() + .map(|dev| dev.arc_any().downcast().unwrap()) +} + +pub fn virtio_blk(transport: VirtIOTransport, dev_id: Arc) { + let device = VirtIOBlkDevice::new(transport, dev_id); + if let Some(device) = device { + kdebug!("VirtIOBlkDevice '{:?}' created", device.dev_id); + virtio_device_manager() + .device_add(device.clone() as Arc) + .expect("Add virtio blk failed"); + } +} + +/// virtio block device +#[derive(Debug)] +#[cast_to([sync] VirtIODevice)] +#[cast_to([sync] Device)] +pub struct VirtIOBlkDevice { + dev_id: Arc, + inner: SpinLock, + locked_kobj_state: LockedKObjectState, + self_ref: Weak, +} + +unsafe impl Send for VirtIOBlkDevice {} +unsafe impl Sync for VirtIOBlkDevice {} + +impl VirtIOBlkDevice { + pub fn new(transport: VirtIOTransport, dev_id: Arc) -> Option> { + let device_inner = VirtIOBlk::::new(transport); + if let Err(e) = device_inner { + kerror!("VirtIOBlkDevice '{dev_id:?}' create failed: {:?}", e); + return None; + } + // !!!! 在这里临时测试virtio-blk的读写功能,后续需要删除 !!!! + // 目前read会报错 `NotReady` + let device_inner: VirtIOBlk = device_inner.unwrap(); + + let dev = Arc::new_cyclic(|self_ref| Self { + self_ref: self_ref.clone(), + dev_id, + locked_kobj_state: LockedKObjectState::default(), + inner: SpinLock::new(InnerVirtIOBlkDevice { + device_inner, + name: None, + virtio_index: None, + device_common: DeviceCommonData::default(), + kobject_common: KObjectCommonData::default(), + }), + }); + + dev.set_driver(Some(Arc::downgrade( + &(virtio_blk_driver() as Arc), + ))); + + Some(dev) + } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } +} + +impl BlockDevice for VirtIOBlkDevice { + fn read_at_sync( + &self, + lba_id_start: BlockId, + count: usize, + buf: &mut [u8], + ) -> Result { + let mut inner = self.inner(); + + inner + .device_inner + .read_blocks(lba_id_start, &mut buf[..count * LBA_SIZE]) + .map_err(|e| { + kerror!( + "VirtIOBlkDevice '{:?}' read_at_sync failed: {:?}", + self.dev_id, + e + ); + SystemError::EIO + })?; + + Ok(count) + } + + fn write_at_sync( + &self, + lba_id_start: BlockId, + count: usize, + buf: &[u8], + ) -> Result { + self.inner() + .device_inner + .write_blocks(lba_id_start, &buf[..count * LBA_SIZE]) + .map_err(|_| SystemError::EIO)?; + Ok(count) + } + + fn sync(&self) -> Result<(), SystemError> { + Ok(()) + } + + fn blk_size_log2(&self) -> u8 { + 9 + } + + fn as_any_ref(&self) -> &dyn Any { + self + } + + fn device(&self) -> Arc { + self.self_ref.upgrade().unwrap() + } + + fn block_size(&self) -> usize { + todo!() + } + + fn partitions(&self) -> Vec> { + let device = self.self_ref.upgrade().unwrap() as Arc; + let mbr_table = MbrDiskPartionTable::from_disk(device.clone()) + .expect("Failed to get MBR partition table"); + mbr_table.partitions(Arc::downgrade(&device)) + } +} + +struct InnerVirtIOBlkDevice { + device_inner: VirtIOBlk, + name: Option, + virtio_index: Option, + device_common: DeviceCommonData, + kobject_common: KObjectCommonData, +} + +impl Debug for InnerVirtIOBlkDevice { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("InnerVirtIOBlkDevice").finish() + } +} + +impl VirtIODevice for VirtIOBlkDevice { + fn handle_irq( + &self, + _irq: crate::exception::IrqNumber, + ) -> Result { + todo!("VirtIOBlkDevice::handle_irq") + } + + fn dev_id(&self) -> &Arc { + &self.dev_id + } + + fn set_device_name(&self, name: String) { + self.inner().name = Some(name); + } + + fn device_name(&self) -> String { + self.inner() + .name + .clone() + .unwrap_or_else(|| VIRTIO_BLK_BASENAME.to_string()) + } + + fn set_virtio_device_index(&self, index: VirtIODeviceIndex) { + self.inner().virtio_index = Some(index); + } + + fn virtio_device_index(&self) -> Option { + self.inner().virtio_index + } + + fn device_type_id(&self) -> u32 { + virtio_drivers::transport::DeviceType::Block as u32 + } + + fn vendor(&self) -> u32 { + VIRTIO_VENDOR_ID.into() + } +} + +impl Device for VirtIOBlkDevice { + fn dev_type(&self) -> DeviceType { + DeviceType::Net + } + + fn id_table(&self) -> IdTable { + IdTable::new(VIRTIO_BLK_BASENAME.to_string(), None) + } + + fn bus(&self) -> Option> { + self.inner().device_common.bus.clone() + } + + fn set_bus(&self, bus: Option>) { + self.inner().device_common.bus = bus; + } + + fn class(&self) -> Option> { + let mut guard = self.inner(); + let r = guard.device_common.class.clone()?.upgrade(); + if r.is_none() { + guard.device_common.class = None; + } + + return r; + } + + fn set_class(&self, class: Option>) { + self.inner().device_common.class = class; + } + + fn driver(&self) -> Option> { + let r = self.inner().device_common.driver.clone()?.upgrade(); + if r.is_none() { + self.inner().device_common.driver = None; + } + + return r; + } + + fn set_driver(&self, driver: Option>) { + self.inner().device_common.driver = driver; + } + + fn is_dead(&self) -> bool { + false + } + + fn can_match(&self) -> bool { + self.inner().device_common.can_match + } + + fn set_can_match(&self, can_match: bool) { + self.inner().device_common.can_match = can_match; + } + + fn state_synced(&self) -> bool { + true + } +} + +impl KObject for VirtIOBlkDevice { + fn as_any_ref(&self) -> &dyn Any { + self + } + + fn set_inode(&self, inode: Option>) { + self.inner().kobject_common.kern_inode = inode; + } + + fn inode(&self) -> Option> { + self.inner().kobject_common.kern_inode.clone() + } + + fn parent(&self) -> Option> { + self.inner().kobject_common.parent.clone() + } + + fn set_parent(&self, parent: Option>) { + self.inner().kobject_common.parent = parent; + } + + fn kset(&self) -> Option> { + self.inner().kobject_common.kset.clone() + } + + fn set_kset(&self, kset: Option>) { + self.inner().kobject_common.kset = kset; + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + self.inner().kobject_common.kobj_type + } + + fn name(&self) -> String { + self.device_name() + } + + fn set_name(&self, _name: String) { + // do nothing + } + + fn kobj_state(&self) -> RwLockReadGuard { + self.locked_kobj_state.read() + } + + fn kobj_state_mut(&self) -> RwLockWriteGuard { + self.locked_kobj_state.write() + } + + fn set_kobj_state(&self, state: KObjectState) { + *self.locked_kobj_state.write() = state; + } + + fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { + self.inner().kobject_common.kobj_type = ktype; + } +} + +#[unified_init(INITCALL_POSTCORE)] +fn virtio_blk_driver_init() -> Result<(), SystemError> { + let driver = VirtIOBlkDriver::new(); + virtio_driver_manager() + .register(driver.clone() as Arc) + .expect("Add virtio net driver failed"); + unsafe { + VIRTIO_BLK_DRIVER = Some(driver); + } + + return Ok(()); +} + +#[derive(Debug)] +#[cast_to([sync] VirtIODriver)] +#[cast_to([sync] Driver)] +struct VirtIOBlkDriver { + inner: SpinLock, + kobj_state: LockedKObjectState, +} + +impl VirtIOBlkDriver { + pub fn new() -> Arc { + let inner = InnerVirtIOBlkDriver { + driver_common: DriverCommonData::default(), + kobj_common: KObjectCommonData::default(), + }; + Arc::new(VirtIOBlkDriver { + inner: SpinLock::new(inner), + kobj_state: LockedKObjectState::default(), + }) + } + + fn inner(&self) -> SpinLockGuard { + return self.inner.lock(); + } +} + +#[derive(Debug)] +struct InnerVirtIOBlkDriver { + driver_common: DriverCommonData, + kobj_common: KObjectCommonData, +} + +impl VirtIODriver for VirtIOBlkDriver { + fn probe(&self, device: &Arc) -> Result<(), SystemError> { + let _dev = device + .clone() + .arc_any() + .downcast::() + .map_err(|_| { + kerror!( + "VirtIOBlkDriver::probe() failed: device is not a VirtIO block device. Device: '{:?}'", + device.name() + ); + SystemError::EINVAL + })?; + + return Ok(()); + } +} + +impl Driver for VirtIOBlkDriver { + fn id_table(&self) -> Option { + Some(IdTable::new(VIRTIO_BLK_BASENAME.to_string(), None)) + } + + fn add_device(&self, device: Arc) { + let iface = device + .arc_any() + .downcast::() + .expect("VirtIOBlkDriver::add_device() failed: device is not a VirtIOBlkDevice"); + + self.inner() + .driver_common + .devices + .push(iface as Arc); + } + + fn delete_device(&self, device: &Arc) { + let _iface = device + .clone() + .arc_any() + .downcast::() + .expect("VirtIOBlkDriver::delete_device() failed: device is not a VirtIOBlkDevice"); + + let mut guard = self.inner(); + let index = guard + .driver_common + .devices + .iter() + .position(|dev| Arc::ptr_eq(device, dev)) + .expect("VirtIOBlkDriver::delete_device() failed: device not found"); + + guard.driver_common.devices.remove(index); + } + + fn devices(&self) -> Vec> { + self.inner().driver_common.devices.clone() + } + + fn bus(&self) -> Option> { + Some(Arc::downgrade(&virtio_bus()) as Weak) + } + + fn set_bus(&self, _bus: Option>) { + // do nothing + } +} + +impl KObject for VirtIOBlkDriver { + fn as_any_ref(&self) -> &dyn Any { + self + } + + fn set_inode(&self, inode: Option>) { + self.inner().kobj_common.kern_inode = inode; + } + + fn inode(&self) -> Option> { + self.inner().kobj_common.kern_inode.clone() + } + + fn parent(&self) -> Option> { + self.inner().kobj_common.parent.clone() + } + + fn set_parent(&self, parent: Option>) { + self.inner().kobj_common.parent = parent; + } + + fn kset(&self) -> Option> { + self.inner().kobj_common.kset.clone() + } + + fn set_kset(&self, kset: Option>) { + self.inner().kobj_common.kset = kset; + } + + fn kobj_type(&self) -> Option<&'static dyn KObjType> { + self.inner().kobj_common.kobj_type + } + + fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { + self.inner().kobj_common.kobj_type = ktype; + } + + fn name(&self) -> String { + VIRTIO_BLK_BASENAME.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; + } +} diff --git a/kernel/src/driver/disk/ahci/ahcidisk.rs b/kernel/src/driver/disk/ahci/ahcidisk.rs index 22fdf22e..4aaaa799 100644 --- a/kernel/src/driver/disk/ahci/ahcidisk.rs +++ b/kernel/src/driver/disk/ahci/ahcidisk.rs @@ -1,7 +1,6 @@ use super::{_port, hba::HbaCmdTable, virt_2_phys}; use crate::driver::base::block::block_device::{BlockDevice, BlockId}; use crate::driver::base::block::disk_info::Partition; -use crate::driver::base::block::SeekFrom; use crate::driver::base::class::Class; use crate::driver::base::device::bus::Bus; @@ -14,9 +13,8 @@ use crate::driver::disk::ahci::HBA_PxIS_TFES; use crate::filesystem::kernfs::KernFSInode; use crate::filesystem::mbr::MbrDiskPartionTable; -use crate::kdebug; use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard}; -use crate::libs::{spinlock::SpinLock, vec_cursor::VecCursor}; +use crate::libs::spinlock::SpinLock; use crate::mm::{phys_2_virt, verify_area, VirtAddr}; use crate::{ driver::disk::ahci::hba::{ @@ -69,7 +67,7 @@ impl AhciDisk { buf: &mut [u8], ) -> Result { assert!((buf.len() & 511) == 0); - compiler_fence(core::sync::atomic::Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); let check_length = ((count - 1) >> 4) + 1; // prdt length if count * 512 > buf.len() || check_length > 8_usize { kerror!("ahci read: e2big"); @@ -204,7 +202,7 @@ impl AhciDisk { buf.copy_from_slice(kbuf.as_ref().unwrap()); } - compiler_fence(core::sync::atomic::Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); // successfully read return Ok(count * 512); } @@ -216,7 +214,7 @@ impl AhciDisk { buf: &[u8], ) -> Result { assert!((buf.len() & 511) == 0); - compiler_fence(core::sync::atomic::Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); let check_length = ((count - 1) >> 4) + 1; // prdt length if count * 512 > buf.len() || check_length > 8 { // 不可能的操作 @@ -235,7 +233,7 @@ impl AhciDisk { return Err(SystemError::EIO); } - compiler_fence(core::sync::atomic::Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); #[allow(unused_unsafe)] let cmdheader: &mut HbaCmdHeader = unsafe { (phys_2_virt( @@ -244,7 +242,7 @@ impl AhciDisk { .as_mut() .unwrap() }; - compiler_fence(core::sync::atomic::Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); volatile_write_bit!( cmdheader.cfl, @@ -256,7 +254,7 @@ impl AhciDisk { volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count // 设置数据存放地址 - compiler_fence(core::sync::atomic::Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); let mut buf_ptr = buf as *const [u8] as *mut usize as usize; // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间 @@ -282,7 +280,7 @@ impl AhciDisk { .unwrap() }; let mut tmp_count = count; - compiler_fence(core::sync::atomic::Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); unsafe { // 清空整个table的旧数据 @@ -343,7 +341,7 @@ impl AhciDisk { } } - compiler_fence(core::sync::atomic::Ordering::SeqCst); + compiler_fence(Ordering::SeqCst); // successfully read return Ok(count * 512); } @@ -362,70 +360,29 @@ impl LockedAhciDisk { port_num: u8, ) -> Result, SystemError> { // 构建磁盘结构体 - let result: Arc = Arc::new(LockedAhciDisk(SpinLock::new(AhciDisk { - name, - flags, - partitions: Default::default(), - ctrl_num, - port_num, - self_ref: Weak::default(), - }))); - + let result: Arc = Arc::new_cyclic(|self_ref| { + LockedAhciDisk(SpinLock::new(AhciDisk { + name, + flags, + partitions: Default::default(), + ctrl_num, + port_num, + self_ref: self_ref.clone(), + })) + }); let table: MbrDiskPartionTable = result.read_mbr_table()?; // 求出有多少可用分区 - for i in 0..4 { - compiler_fence(Ordering::SeqCst); - if table.dpte[i].part_type != 0 { - let w = Arc::downgrade(&result); - result.0.lock().partitions.push(Partition::new( - table.dpte[i].starting_sector() as u64, - table.dpte[i].starting_lba as u64, - table.dpte[i].total_sectors as u64, - w, - i as u16, - )); - } - } - - result.0.lock().self_ref = Arc::downgrade(&result); + let partitions = table.partitions(Arc::downgrade(&result) as Weak); + result.0.lock().partitions = partitions; return Ok(result); } - /// @brief: 从磁盘中读取 MBR 分区表结构体 TODO: Cursor + /// @brief: 从磁盘中读取 MBR 分区表结构体 pub fn read_mbr_table(&self) -> Result { - let mut table: MbrDiskPartionTable = Default::default(); - - // 数据缓冲区 - let mut buf: Vec = vec![0; size_of::()]; - buf.resize(size_of::(), 0); - - self.read_at_sync(0, 1, &mut buf)?; - // 创建 Cursor 用于按字节读取 - let mut cursor = VecCursor::new(buf); - cursor.seek(SeekFrom::SeekCurrent(446))?; - - for i in 0..4 { - kdebug!("infomation of partition {}:\n", i); - - table.dpte[i].flags = cursor.read_u8()?; - table.dpte[i].starting_head = cursor.read_u8()?; - table.dpte[i].starting_sector_cylinder = cursor.read_u16()?; - table.dpte[i].part_type = cursor.read_u8()?; - table.dpte[i].ending_head = cursor.read_u8()?; - table.dpte[i].ending_sector_cylingder = cursor.read_u16()?; - table.dpte[i].starting_lba = cursor.read_u32()?; - table.dpte[i].total_sectors = cursor.read_u32()?; - - kdebug!("dpte[i] = {:?}", table.dpte[i]); - } - table.bs_trailsig = cursor.read_u16()?; - // kdebug!("bs_trailsig = {}", unsafe { - // read_unaligned(addr_of!(table.bs_trailsig)) - // }); - - return Ok(table); + let disk = self.0.lock().self_ref.upgrade().unwrap() as Arc; + MbrDiskPartionTable::from_disk(disk) } } diff --git a/kernel/src/driver/input/serio/serio_driver.rs b/kernel/src/driver/input/serio/serio_driver.rs index 48deaea0..8cc3c572 100644 --- a/kernel/src/driver/input/serio/serio_driver.rs +++ b/kernel/src/driver/input/serio/serio_driver.rs @@ -46,6 +46,7 @@ pub trait SerioDriver: Driver { ///todo: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/input/serio/serio.c#810 +#[allow(dead_code)] #[inline(always)] pub fn serio_driver_manager() -> &'static SerioDriverManager { &SerioDriverManager diff --git a/kernel/src/driver/net/virtio_net.rs b/kernel/src/driver/net/virtio_net.rs index c3e61da4..f0d2622c 100644 --- a/kernel/src/driver/net/virtio_net.rs +++ b/kernel/src/driver/net/virtio_net.rs @@ -128,6 +128,7 @@ impl Debug for VirtIONicDeviceInner { } #[cast_to([sync] VirtIODevice)] +#[cast_to([sync] Device)] pub struct VirtioInterface { device_inner: VirtIONicDeviceInnerWrapper, iface_id: usize, @@ -293,7 +294,7 @@ impl Device for VirtioInterface { } fn can_match(&self) -> bool { - true + self.inner().device_common.can_match } fn set_can_match(&self, can_match: bool) { @@ -552,8 +553,10 @@ fn virtio_net_driver_init() -> Result<(), SystemError> { return Ok(()); } + #[derive(Debug)] #[cast_to([sync] VirtIODriver)] +#[cast_to([sync] Driver)] struct VirtIONetDriver { inner: SpinLock, kobj_state: LockedKObjectState, diff --git a/kernel/src/driver/open_firmware/fdt.rs b/kernel/src/driver/open_firmware/fdt.rs index c1f59276..2189ef5a 100644 --- a/kernel/src/driver/open_firmware/fdt.rs +++ b/kernel/src/driver/open_firmware/fdt.rs @@ -76,7 +76,7 @@ impl OpenFirmwareFdtDriver { /// 获取FDT的引用 pub fn fdt_ref(&self) -> Result, SystemError> { - let fdt_vaddr = boot_params().read().fdt().unwrap(); + let fdt_vaddr = boot_params().read().fdt().ok_or(SystemError::ENODEV)?; let fdt: Fdt<'_> = unsafe { fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| { kerror!("failed to parse fdt, err={:?}", e); @@ -213,10 +213,7 @@ impl OpenFirmwareFdtDriver { use crate::{ arch::MMArch, libs::align::page_align_down, - mm::{ - memblock::{mem_block_manager, MemBlockManager}, - MemoryManagementArch, PhysAddr, - }, + mm::{memblock::MemBlockManager, MemoryManagementArch}, }; let mut base = base as usize; diff --git a/kernel/src/driver/timers/mod.rs b/kernel/src/driver/timers/mod.rs index c8b950a4..e18b9f9d 100644 --- a/kernel/src/driver/timers/mod.rs +++ b/kernel/src/driver/timers/mod.rs @@ -1 +1,2 @@ +#[cfg(target_arch = "x86_64")] pub mod hpet; diff --git a/kernel/src/driver/virtio/mmio.rs b/kernel/src/driver/virtio/mmio.rs index e7fa507e..027a70bd 100644 --- a/kernel/src/driver/virtio/mmio.rs +++ b/kernel/src/driver/virtio/mmio.rs @@ -1,3 +1,30 @@ +use fdt::node::FdtNode; +use system_error::SystemError; + +use crate::driver::{ + open_firmware::fdt::open_firmware_fdt_driver, virtio::transport_mmio::VirtIOMmioTransport, +}; + +use super::{transport::VirtIOTransport, virtio::virtio_device_init}; + pub(super) fn virtio_probe_mmio() { - // todo: implement virtio_probe_mmio + if let Err(e) = do_probe_virtio_mmio() { + kerror!("virtio_probe_mmio failed: {:?}", e); + } +} + +fn do_probe_virtio_mmio() -> Result<(), SystemError> { + let fdt = open_firmware_fdt_driver().fdt_ref()?; + + let do_check = |node: FdtNode| -> Result<(), SystemError> { + let mmio_transport = VirtIOMmioTransport::new(node)?; + let device_id = mmio_transport.device_id(); + virtio_device_init(VirtIOTransport::Mmio(mmio_transport), device_id); + Ok(()) + }; + + for node in open_firmware_fdt_driver().find_node_by_compatible(&fdt, "virtio,mmio") { + do_check(node).ok(); + } + Ok(()) } diff --git a/kernel/src/driver/virtio/mod.rs b/kernel/src/driver/virtio/mod.rs index b069be82..642027a3 100644 --- a/kernel/src/driver/virtio/mod.rs +++ b/kernel/src/driver/virtio/mod.rs @@ -9,6 +9,7 @@ pub(super) mod irq; pub mod mmio; pub mod sysfs; pub mod transport; +pub mod transport_mmio; pub mod transport_pci; #[allow(clippy::module_inception)] pub mod virtio; diff --git a/kernel/src/driver/virtio/transport.rs b/kernel/src/driver/virtio/transport.rs index 72cf0ba6..f1f58a8b 100644 --- a/kernel/src/driver/virtio/transport.rs +++ b/kernel/src/driver/virtio/transport.rs @@ -1,15 +1,17 @@ use virtio_drivers::transport::Transport; -use super::transport_pci::PciTransport; +use super::{transport_mmio::VirtIOMmioTransport, transport_pci::PciTransport}; pub enum VirtIOTransport { Pci(PciTransport), + Mmio(VirtIOMmioTransport), } impl core::fmt::Debug for VirtIOTransport { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { VirtIOTransport::Pci(_) => write!(f, "VirtIOTransport::Pci"), + VirtIOTransport::Mmio(_) => write!(f, "VirtIOTransport::Mmio"), } } } @@ -19,6 +21,7 @@ impl Transport for VirtIOTransport { fn finish_init(&mut self) { match self { VirtIOTransport::Pci(transport) => transport.finish_init(), + VirtIOTransport::Mmio(transport) => transport.finish_init(), } } @@ -26,6 +29,7 @@ impl Transport for VirtIOTransport { fn device_type(&self) -> virtio_drivers::transport::DeviceType { match self { VirtIOTransport::Pci(transport) => transport.device_type(), + VirtIOTransport::Mmio(transport) => transport.device_type(), } } @@ -33,6 +37,7 @@ impl Transport for VirtIOTransport { fn read_device_features(&mut self) -> u64 { match self { VirtIOTransport::Pci(transport) => transport.read_device_features(), + VirtIOTransport::Mmio(transport) => transport.read_device_features(), } } @@ -40,6 +45,7 @@ impl Transport for VirtIOTransport { fn write_driver_features(&mut self, driver_features: u64) { match self { VirtIOTransport::Pci(transport) => transport.write_driver_features(driver_features), + VirtIOTransport::Mmio(transport) => transport.write_driver_features(driver_features), } } @@ -47,6 +53,7 @@ impl Transport for VirtIOTransport { fn max_queue_size(&mut self, queue: u16) -> u32 { match self { VirtIOTransport::Pci(transport) => transport.max_queue_size(queue), + VirtIOTransport::Mmio(transport) => transport.max_queue_size(queue), } } @@ -54,6 +61,7 @@ impl Transport for VirtIOTransport { fn notify(&mut self, queue: u16) { match self { VirtIOTransport::Pci(transport) => transport.notify(queue), + VirtIOTransport::Mmio(transport) => transport.notify(queue), } } @@ -61,6 +69,7 @@ impl Transport for VirtIOTransport { fn get_status(&self) -> virtio_drivers::transport::DeviceStatus { match self { VirtIOTransport::Pci(transport) => transport.get_status(), + VirtIOTransport::Mmio(transport) => transport.get_status(), } } @@ -68,6 +77,7 @@ impl Transport for VirtIOTransport { fn set_status(&mut self, status: virtio_drivers::transport::DeviceStatus) { match self { VirtIOTransport::Pci(transport) => transport.set_status(status), + VirtIOTransport::Mmio(transport) => transport.set_status(status), } } @@ -75,6 +85,7 @@ impl Transport for VirtIOTransport { fn set_guest_page_size(&mut self, guest_page_size: u32) { match self { VirtIOTransport::Pci(transport) => transport.set_guest_page_size(guest_page_size), + VirtIOTransport::Mmio(transport) => transport.set_guest_page_size(guest_page_size), } } @@ -82,6 +93,7 @@ impl Transport for VirtIOTransport { fn requires_legacy_layout(&self) -> bool { match self { VirtIOTransport::Pci(transport) => transport.requires_legacy_layout(), + VirtIOTransport::Mmio(transport) => transport.requires_legacy_layout(), } } @@ -98,6 +110,9 @@ impl Transport for VirtIOTransport { VirtIOTransport::Pci(transport) => { transport.queue_set(queue, size, descriptors, driver_area, device_area) } + VirtIOTransport::Mmio(transport) => { + transport.queue_set(queue, size, descriptors, driver_area, device_area) + } } } @@ -105,6 +120,7 @@ impl Transport for VirtIOTransport { fn queue_unset(&mut self, queue: u16) { match self { VirtIOTransport::Pci(transport) => transport.queue_unset(queue), + VirtIOTransport::Mmio(transport) => transport.queue_unset(queue), } } @@ -112,6 +128,7 @@ impl Transport for VirtIOTransport { fn queue_used(&mut self, queue: u16) -> bool { match self { VirtIOTransport::Pci(transport) => transport.queue_used(queue), + VirtIOTransport::Mmio(transport) => transport.queue_used(queue), } } @@ -119,6 +136,7 @@ impl Transport for VirtIOTransport { fn ack_interrupt(&mut self) -> bool { match self { VirtIOTransport::Pci(transport) => transport.ack_interrupt(), + VirtIOTransport::Mmio(transport) => transport.ack_interrupt(), } } @@ -126,6 +144,7 @@ impl Transport for VirtIOTransport { fn config_space(&self) -> virtio_drivers::Result> { match self { VirtIOTransport::Pci(transport) => transport.config_space(), + VirtIOTransport::Mmio(transport) => transport.config_space(), } } } diff --git a/kernel/src/driver/virtio/transport_mmio.rs b/kernel/src/driver/virtio/transport_mmio.rs new file mode 100644 index 00000000..435f90fc --- /dev/null +++ b/kernel/src/driver/virtio/transport_mmio.rs @@ -0,0 +1,157 @@ +use core::ptr::NonNull; + +use alloc::sync::Arc; +use fdt::node::FdtNode; +use system_error::SystemError; +use virtio_drivers::transport::{ + mmio::{MmioTransport, VirtIOHeader}, + Transport, +}; + +use crate::{ + arch::MMArch, + driver::base::device::DeviceId, + exception::HardwareIrqNumber, + libs::align::page_align_up, + mm::{ + mmio_buddy::{mmio_pool, MMIOSpaceGuard}, + MemoryManagementArch, PhysAddr, + }, +}; + +pub struct VirtIOMmioTransport { + mmio_transport: MmioTransport, + _mmio_guard: MMIOSpaceGuard, + irq: HardwareIrqNumber, + device_id: Arc, +} + +impl VirtIOMmioTransport { + pub fn new(node: FdtNode) -> Result { + let reg = node + .reg() + .ok_or(SystemError::EINVAL)? + .next() + .ok_or(SystemError::EINVAL)?; + let paddr = reg.starting_address as usize; + let size = reg.size.unwrap_or(0); + let page_offset = paddr % MMArch::PAGE_SIZE; + let paddr = paddr - page_offset; + let size = page_align_up(size + page_offset); + let irq = node + .interrupts() + .ok_or(SystemError::EINVAL)? + .next() + .ok_or(SystemError::EINVAL)?; + + let device_id = DeviceId::new(None, Some(format!("virtio_mmio_{:#X}", paddr))).unwrap(); + + let mmio_guard = mmio_pool().create_mmio(size)?; + unsafe { mmio_guard.map_phys(PhysAddr::new(paddr), size) }?; + + let vaddr = mmio_guard.vaddr() + page_offset; + let header = NonNull::new(vaddr.data() as *mut VirtIOHeader).unwrap(); + + match unsafe { MmioTransport::new(header) } { + Ok(mmio_transport) => { + kinfo!( "Detected virtio MMIO device with vendor id {:#X}, device type {:?}, version {:?}, hw irq: {}", + mmio_transport.vendor_id(), + mmio_transport.device_type(), + mmio_transport.version(), + irq as u32 + ); + + Ok(Self { + mmio_transport, + _mmio_guard: mmio_guard, + irq: HardwareIrqNumber::new(irq as u32), + device_id, + }) + } + Err(_) => { + // kwarn!("MmioTransport::new failed: {:?}", e); + Err(SystemError::EINVAL) + } + } + } + + #[allow(dead_code)] + #[inline] + pub fn irq(&self) -> HardwareIrqNumber { + self.irq + } + + pub fn device_id(&self) -> Arc { + self.device_id.clone() + } +} + +impl Transport for VirtIOMmioTransport { + fn device_type(&self) -> virtio_drivers::transport::DeviceType { + self.mmio_transport.device_type() + } + + fn read_device_features(&mut self) -> u64 { + self.mmio_transport.read_device_features() + } + + fn write_driver_features(&mut self, driver_features: u64) { + self.mmio_transport.write_driver_features(driver_features) + } + + fn max_queue_size(&mut self, queue: u16) -> u32 { + self.mmio_transport.max_queue_size(queue) + } + + fn notify(&mut self, queue: u16) { + self.mmio_transport.notify(queue) + } + + fn get_status(&self) -> virtio_drivers::transport::DeviceStatus { + self.mmio_transport.get_status() + } + + fn set_status(&mut self, status: virtio_drivers::transport::DeviceStatus) { + self.mmio_transport.set_status(status) + } + + fn set_guest_page_size(&mut self, guest_page_size: u32) { + self.mmio_transport.set_guest_page_size(guest_page_size) + } + + fn requires_legacy_layout(&self) -> bool { + self.mmio_transport.requires_legacy_layout() + } + + fn queue_set( + &mut self, + queue: u16, + size: u32, + descriptors: virtio_drivers::PhysAddr, + driver_area: virtio_drivers::PhysAddr, + device_area: virtio_drivers::PhysAddr, + ) { + self.mmio_transport + .queue_set(queue, size, descriptors, driver_area, device_area) + } + + fn queue_unset(&mut self, queue: u16) { + self.mmio_transport.queue_unset(queue) + } + + fn queue_used(&mut self, queue: u16) -> bool { + self.mmio_transport.queue_used(queue) + } + + fn ack_interrupt(&mut self) -> bool { + self.mmio_transport.ack_interrupt() + } + + fn config_space(&self) -> virtio_drivers::Result> { + self.mmio_transport.config_space() + } + + fn finish_init(&mut self) { + self.mmio_transport.finish_init() + } +} diff --git a/kernel/src/driver/virtio/virtio.rs b/kernel/src/driver/virtio/virtio.rs index db32787e..4314edbe 100644 --- a/kernel/src/driver/virtio/virtio.rs +++ b/kernel/src/driver/virtio/virtio.rs @@ -2,6 +2,7 @@ use super::mmio::virtio_probe_mmio; use super::transport_pci::PciTransport; use super::virtio_impl::HalImpl; use crate::driver::base::device::DeviceId; +use crate::driver::block::virtio_blk::virtio_blk; use crate::driver::net::virtio_net::virtio_net; use crate::driver::pci::pci::{ get_pci_device_structures_mut_by_vendor_id, PciDeviceStructure, @@ -17,10 +18,12 @@ use virtio_drivers::transport::{DeviceType, Transport}; ///@brief 寻找并加载所有virtio设备的驱动(目前只有virtio-net,但其他virtio设备也可添加) pub fn virtio_probe() { + #[cfg(not(target_arch = "riscv64"))] virtio_probe_pci(); virtio_probe_mmio(); } +#[allow(dead_code)] fn virtio_probe_pci() { let mut list = PCI_DEVICE_LINKEDLIST.write(); let virtio_list = virtio_device_search(&mut list); @@ -45,11 +48,9 @@ fn virtio_probe_pci() { } ///@brief 为virtio设备寻找对应的驱动进行初始化 -fn virtio_device_init(transport: VirtIOTransport, dev_id: Arc) { +pub(super) fn virtio_device_init(transport: VirtIOTransport, dev_id: Arc) { match transport.device_type() { - DeviceType::Block => { - kwarn!("Not support virtio_block device for now"); - } + DeviceType::Block => virtio_blk(transport, dev_id), DeviceType::GPU => { kwarn!("Not support virtio_gpu device for now"); } diff --git a/kernel/src/driver/virtio/virtio_impl.rs b/kernel/src/driver/virtio/virtio_impl.rs index 92e2edd8..92aa07cc 100644 --- a/kernel/src/driver/virtio/virtio_impl.rs +++ b/kernel/src/driver/virtio/virtio_impl.rs @@ -79,8 +79,8 @@ unsafe impl Hal for HalImpl { /// @brief mmio物理地址转换为虚拟地址,不需要使用 /// @param paddr 起始物理地址 /// @return NonNull 虚拟地址的指针 - unsafe fn mmio_phys_to_virt(_paddr: virtio_drivers::PhysAddr, _size: usize) -> NonNull { - NonNull::new((0) as _).unwrap() + unsafe fn mmio_phys_to_virt(paddr: virtio_drivers::PhysAddr, _size: usize) -> NonNull { + NonNull::new((MMArch::phys_2_virt(PhysAddr::new(paddr))).unwrap().data() as _).unwrap() } /// @brief 与真实物理设备共享 /// @param buffer 要共享的buffer _direction:设备到driver或driver到设备 diff --git a/kernel/src/filesystem/mbr.rs b/kernel/src/filesystem/mbr.rs index 807b0557..eb3af9af 100644 --- a/kernel/src/filesystem/mbr.rs +++ b/kernel/src/filesystem/mbr.rs @@ -1,5 +1,15 @@ -#![allow(dead_code)] -use core::default::Default; +use core::{default::Default, mem::size_of}; + +use alloc::{ + sync::{Arc, Weak}, + vec::Vec, +}; +use system_error::SystemError; + +use crate::{ + driver::base::block::{block_device::BlockDevice, disk_info::Partition, SeekFrom}, + libs::vec_cursor::VecCursor, +}; /// @brief MBR硬盘分区表项的结构 #[repr(packed)] @@ -10,23 +20,33 @@ pub struct MbrDiskPartitionTableEntry { pub starting_sector_cylinder: u16, // sector : 低6, cylinder : 高10; 起始扇区号 + 起始柱面号 pub part_type: u8, // 分区类型ID pub ending_head: u8, // 结束磁头号 - pub ending_sector_cylingder: u16, // ending_sector : 低6, ending_cylinder : 高10; 结束扇区号 + 结束柱面号 - pub starting_lba: u32, // 起始逻辑扇区 - pub total_sectors: u32, // 分区占用的磁盘扇区数 + pub ending_sector_cylinder: u16, // ending_sector : 低6, ending_cylinder : 高10; 结束扇区号 + 结束柱面号 + pub starting_lba: u32, // 起始逻辑扇区 + pub total_sectors: u32, // 分区占用的磁盘扇区数 } impl MbrDiskPartitionTableEntry { - pub fn starting_sector(&self) -> u16 { - return self.starting_sector_cylinder & ((1 << 6) - 1) as u16; + pub fn starting_sector(&self) -> u32 { + return (self.starting_sector_cylinder & ((1 << 6) - 1)).into(); } pub fn starting_cylinder(&self) -> u16 { return (self.starting_sector_cylinder >> 6) & ((1 << 10) - 1) as u16; } - pub fn ending_sector(&self) -> u16 { - return self.ending_sector_cylingder & ((1 << 6) - 1) as u16; + pub fn ending_sector(&self) -> u32 { + self.starting_sector() + self.total_sectors - 1 } + pub fn ending_cylinder(&self) -> u16 { - return (self.ending_sector_cylingder >> 6) & ((1 << 10) - 1) as u16; + return (self.ending_sector_cylinder >> 6) & ((1 << 10) - 1) as u16; + } + + pub fn is_valid(&self) -> bool { + // 其他更多的可能判断条件 + self.starting_sector() <= self.ending_sector() + && self.starting_cylinder() <= self.ending_cylinder() + && self.starting_lba != 0 + && self.total_sectors != 0 + && self.part_type != 0 } } @@ -48,3 +68,86 @@ impl Default for MbrDiskPartionTable { } } } + +impl MbrDiskPartionTable { + /// # 从磁盘读取MBR分区表 - 从磁盘设备中读取并解析MBR分区表 + /// + /// 这个函数从提供的磁盘设备中读取MBR分区表,并将其解析为一个`MbrDiskPartionTable`实例。 + /// + /// ## 参数 + /// + /// - `disk`: Arc - 一个磁盘设备的共享引用,用于从磁盘读取数据。 + /// + /// ## 返回值 + /// + /// - `Ok(MbrDiskPartionTable)`: 成功解析的分区表实例。 + /// - `Err(SystemError)`: 读取磁盘失败或其他系统错误。 + pub fn from_disk(disk: Arc) -> Result { + let mut table: MbrDiskPartionTable = Default::default(); + + // 数据缓冲区 + let mut buf: Vec = vec![0; size_of::()]; + buf.resize(size_of::(), 0); + + disk.read_at_sync(0, 1, &mut buf)?; + + // 创建 Cursor 用于按字节读取 + let mut cursor = VecCursor::new(buf); + cursor.seek(SeekFrom::SeekCurrent(446))?; + + for i in 0..4 { + table.dpte[i].flags = cursor.read_u8()?; + table.dpte[i].starting_head = cursor.read_u8()?; + table.dpte[i].starting_sector_cylinder = cursor.read_u16()?; + table.dpte[i].part_type = cursor.read_u8()?; + table.dpte[i].ending_head = cursor.read_u8()?; + table.dpte[i].ending_sector_cylinder = cursor.read_u16()?; + table.dpte[i].starting_lba = cursor.read_u32()?; + table.dpte[i].total_sectors = cursor.read_u32()?; + + kdebug!("dpte[{i}] = {:?}", table.dpte[i]); + } + table.bs_trailsig = cursor.read_u16()?; + // kdebug!("bs_trailsig = {}", unsafe { + // read_unaligned(addr_of!(table.bs_trailsig)) + // }); + + if !table.is_valid() { + return Err(SystemError::EINVAL); + } + + return Ok(table); + } + + /// # partitions - 获取磁盘的分区信息 + /// + /// 该函数用于获取指定磁盘的分区信息,并将这些分区信息以分区对象的向量形式返回。分区对象包含了分区的类型、起始扇区和总扇区数等信息。 + /// + /// ## 参数 + /// + /// - `disk`: Weak: 一个对磁盘设备的弱引用。这个磁盘设备必须实现`BlockDevice` trait。 + /// + /// ## 返回值 + /// + /// 返回一个包含分区信息的`Vec`。每个分区都是一个`Arc`,它表示分区的一个强引用。 + /// + pub fn partitions(&self, disk: Weak) -> Vec> { + let mut partitions: Vec> = Vec::new(); + for i in 0..4 { + if self.dpte[i].is_valid() { + partitions.push(Partition::new( + self.dpte[i].starting_sector() as u64, + self.dpte[i].starting_lba as u64, + self.dpte[i].total_sectors as u64, + disk.clone(), + i as u16, + )); + } + } + return partitions; + } + + pub fn is_valid(&self) -> bool { + self.bs_trailsig == 0xAA55 + } +} diff --git a/kernel/src/filesystem/vfs/core.rs b/kernel/src/filesystem/vfs/core.rs index ed6badcf..eb84525d 100644 --- a/kernel/src/filesystem/vfs/core.rs +++ b/kernel/src/filesystem/vfs/core.rs @@ -113,14 +113,36 @@ fn migrate_virtual_filesystem(new_fs: Arc) -> Result<(), SystemE return Ok(()); } +fn root_partition() -> Arc { + #[cfg(target_arch = "x86_64")] + { + return ahci::get_disks_by_name("ahci_disk_0".to_string()) + .unwrap() + .0 + .lock() + .partitions[0] + .clone(); + } + + #[cfg(target_arch = "riscv64")] + { + use crate::driver::base::block::block_device::BlockDevice; + + let virtio0 = crate::driver::block::virtio_blk::virtio_blk_0(); + if virtio0.is_none() { + kerror!("Failed to get virtio_blk_0"); + loop { + spin_loop(); + } + } + + let virtio0 = virtio0.unwrap(); + return virtio0.partitions()[0].clone(); + } +} pub fn mount_root_fs() -> Result<(), SystemError> { kinfo!("Try to mount FAT32 as root fs..."); - let partiton: Arc = ahci::get_disks_by_name("ahci_disk_0".to_string()) - .unwrap() - .0 - .lock() - .partitions[0] - .clone(); + let partiton: Arc = root_partition(); let fatfs: Result, SystemError> = FATFileSystem::new(partiton); if fatfs.is_err() { diff --git a/kernel/src/init/init.rs b/kernel/src/init/init.rs index c1f2f602..309dd753 100644 --- a/kernel/src/init/init.rs +++ b/kernel/src/init/init.rs @@ -7,7 +7,6 @@ use crate::{ driver::{base::init::driver_init, serial::serial_early_init, video::VideoRefreshManager}, exception::{init::irq_init, softirq::softirq_init, InterruptArch}, filesystem::vfs::core::vfs_init, - include::bindings::bindings::acpi_init, init::init_intertrait, libs::{ futex::futex::Futex, @@ -15,6 +14,7 @@ use crate::{ screen_manager::{scm_init, scm_reinit}, textui::textui_init, }, + printk::early_init_logging, }, mm::init::mm_init, process::{kthread::kthread_init, process_init, ProcessManager}, @@ -45,6 +45,7 @@ pub fn start_kernel() -> ! { #[inline(never)] fn do_start_kernel() { init_before_mem_init(); + early_init_logging(); early_setup_arch().expect("setup_arch failed"); unsafe { mm_init() }; @@ -58,7 +59,7 @@ fn do_start_kernel() { #[cfg(target_arch = "x86_64")] unsafe { - acpi_init() + crate::include::bindings::bindings::acpi_init() }; crate::sched::sched_init(); process_init(); diff --git a/kernel/src/init/initial_kthread.rs b/kernel/src/init/initial_kthread.rs index 7f3ddc34..b883cc2c 100644 --- a/kernel/src/init/initial_kthread.rs +++ b/kernel/src/init/initial_kthread.rs @@ -5,9 +5,7 @@ use system_error::SystemError; use crate::{ arch::process::arch_switch_to_user, - driver::{ - disk::ahci::ahci_init, net::e1000e::e1000e::e1000e_init, virtio::virtio::virtio_probe, - }, + driver::{net::e1000e::e1000e::e1000e_init, virtio::virtio::virtio_probe}, filesystem::vfs::core::mount_root_fs, kdebug, kerror, net::net_core::net_init, @@ -35,11 +33,11 @@ fn kernel_init() -> Result<(), SystemError> { // scm_enable_double_buffer().expect("Failed to enable double buffer"); #[cfg(target_arch = "x86_64")] - ahci_init().expect("Failed to initialize AHCI"); - - mount_root_fs().expect("Failed to mount root fs"); + crate::driver::disk::ahci::ahci_init().expect("Failed to initialize AHCI"); virtio_probe(); + mount_root_fs().expect("Failed to mount root fs"); + e1000e_init(); net_init().unwrap_or_else(|err| { kerror!("Failed to initialize network: {:?}", err); diff --git a/kernel/src/libs/printk.rs b/kernel/src/libs/printk.rs index 6726d099..29ed9c16 100644 --- a/kernel/src/libs/printk.rs +++ b/kernel/src/libs/printk.rs @@ -4,6 +4,7 @@ use core::{ }; use alloc::string::ToString; +use log::{info, Log}; use super::lib_ui::textui::{textui_putstr, FontColor}; @@ -129,3 +130,42 @@ impl Logger { } } } + +/// 内核自定义日志器 +/// +/// todo: 完善他的功能,并且逐步把kinfo等宏,迁移到这个logger上面来。 +struct CustomLogger; + +impl Log for CustomLogger { + fn enabled(&self, _metadata: &log::Metadata) -> bool { + // 这里可以自定义日志过滤规则 + true + } + + fn log(&self, record: &log::Record) { + if self.enabled(record.metadata()) { + // todo: 接入kmsg + + writeln!( + PrintkWriter, + "[ {} ] {} ({}:{}) {}", + record.level(), + record.target(), + record.file().unwrap_or(""), + record.line().unwrap_or(0), + record.args() + ) + .unwrap(); + } + } + + fn flush(&self) { + // 如果需要的话,可以在这里实现缓冲区刷新逻辑 + } +} + +pub fn early_init_logging() { + log::set_logger(&CustomLogger).unwrap(); + log::set_max_level(log::LevelFilter::Debug); + info!("Logging initialized"); +} diff --git a/kernel/src/mm/mmio_buddy.rs b/kernel/src/mm/mmio_buddy.rs index 9d7ff2e0..e2008661 100644 --- a/kernel/src/mm/mmio_buddy.rs +++ b/kernel/src/mm/mmio_buddy.rs @@ -676,6 +676,7 @@ impl MMIOSpaceGuard { } let flags = PageFlags::mmio_flags(); + let mut kernel_mapper = KernelMapper::lock(); let r = kernel_mapper.map_phys_with_size(self.vaddr, paddr, length, flags, true); return r; diff --git a/kernel/src/mm/page.rs b/kernel/src/mm/page.rs index 5785ed4e..b13f1811 100644 --- a/kernel/src/mm/page.rs +++ b/kernel/src/mm/page.rs @@ -676,6 +676,11 @@ impl PageFlags { return self.update_flags(Arch::ENTRY_FLAG_WRITE_THROUGH, value); } + #[inline(always)] + pub fn set_page_global(self, value: bool) -> Self { + return self.update_flags(MMArch::ENTRY_FLAG_GLOBAL, value); + } + /// 获取当前页表项的写穿策略 /// /// ## 返回值 @@ -724,7 +729,8 @@ impl PageFlags { .set_write(true) .set_execute(true) .set_page_cache_disable(true) - .set_page_write_through(true); + .set_page_write_through(true) + .set_page_global(true); } } @@ -1099,6 +1105,7 @@ impl PageMapper { return self .visit(virt, |p1, i| { let mut entry = p1.entry(i)?; + entry.set_flags(flags); p1.set_entry(i, entry); Some(PageFlush::new(virt)) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 3f54948f..96143ac4 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -6,7 +6,6 @@ use core::{ use crate::{ arch::{ipc::signal::SigSet, syscall::nr::*}, - driver::base::device::device_number::DeviceNumber, filesystem::vfs::syscall::{PosixStatfs, PosixStatx}, ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey}, libs::{futex::constant::FutexFlag, rand::GRandFlags}, @@ -662,7 +661,11 @@ 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 u8, flags, DeviceNumber::from(dev_t as u32)) + Self::mknod( + path as *const u8, + flags, + crate::driver::base::device::device_number::DeviceNumber::from(dev_t as u32), + ) } SYS_CLONE => { @@ -1059,6 +1062,7 @@ impl Syscall { Err(SystemError::EINVAL) } + #[cfg(target_arch = "x86_64")] SYS_ALARM => { let second = args[0] as u32; Self::alarm(second) diff --git a/tools/run-qemu.sh b/tools/run-qemu.sh index 1cc6911b..f4efd086 100644 --- a/tools/run-qemu.sh +++ b/tools/run-qemu.sh @@ -76,7 +76,7 @@ QEMU_SERIAL="-serial file:../serial_opt.txt" QEMU_DRIVE="id=disk,file=${QEMU_DISK_IMAGE},if=none" QEMU_ACCELARATE="" QEMU_ARGUMENT="" -QEMU_DEVICES= +QEMU_DEVICES="" # 如果qemu_accel不为空 if [ -n "${qemu_accel}" ]; then