From 9fa0e95eeed8630a8a69c874090af2f10e8eee02 Mon Sep 17 00:00:00 2001 From: LoGin Date: Mon, 2 Sep 2024 23:37:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0gendisk=E6=8A=BD?= =?UTF-8?q?=E8=B1=A1=20(#903)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 添加gendisk抽象. * 支持使用virtio磁盘作为根文件系统 * Update initial_kthread.rs to resolve conflict. --------- Co-authored-by: Donkey Kane <109840258+xiaolin2004@users.noreply.github.com> --- kernel/src/driver/base/block/block_device.rs | 118 ++++++++- kernel/src/driver/base/block/disk_info.rs | 46 +++- kernel/src/driver/base/block/gendisk.rs | 195 +++++++++++++++ kernel/src/driver/base/block/manager.rs | 238 +++++++++++++++++++ kernel/src/driver/base/block/mod.rs | 3 + kernel/src/driver/block/virtio_blk.rs | 99 +++++++- kernel/src/driver/disk/ahci/ahcidisk.rs | 77 +++--- kernel/src/driver/disk/ahci/mod.rs | 60 +---- kernel/src/driver/mod.rs | 1 + kernel/src/driver/scsi/mod.rs | 74 ++++++ kernel/src/driver/virtio/irq.rs | 3 +- kernel/src/filesystem/fat/bpb.rs | 10 +- kernel/src/filesystem/fat/entry.rs | 122 +++++----- kernel/src/filesystem/fat/fs.rs | 130 +++++----- kernel/src/filesystem/mbr.rs | 38 +++ kernel/src/filesystem/vfs/core.rs | 50 ++-- kernel/src/init/initial_kthread.rs | 4 +- 17 files changed, 980 insertions(+), 288 deletions(-) create mode 100644 kernel/src/driver/base/block/gendisk.rs create mode 100644 kernel/src/driver/base/block/manager.rs create mode 100644 kernel/src/driver/scsi/mod.rs diff --git a/kernel/src/driver/base/block/block_device.rs b/kernel/src/driver/base/block/block_device.rs index 729157a62..2a9a9b1e9 100644 --- a/kernel/src/driver/base/block/block_device.rs +++ b/kernel/src/driver/base/block/block_device.rs @@ -13,12 +13,12 @@ use crate::driver::{ block::cache::{cached_block_device::BlockCache, BlockCacheError, BLOCK_SIZE}, }; -use alloc::{sync::Arc, vec::Vec}; -use core::any::Any; +use alloc::{string::String, sync::Arc, vec::Vec}; +use core::{any::Any, fmt::Display, ops::Deref}; use log::error; use system_error::SystemError; -use super::disk_info::Partition; +use super::{disk_info::Partition, gendisk::GenDisk, manager::BlockDevMeta}; /// 该文件定义了 Device 和 BlockDevice 的接口 /// Notice 设备错误码使用 Posix 规定的 int32_t 的错误码表示,而不是自己定义错误enum @@ -36,6 +36,41 @@ pub const BLK_SIZE_LOG2_LIMIT: u8 = 12; // 设定块设备的块大小不能超 /// 在DragonOS中,我们认为磁盘的每个LBA大小均为512字节。(注意,文件系统的1个扇区可能事实上是多个LBA) pub const LBA_SIZE: usize = 512; +#[derive(Debug, Clone, Copy)] +pub struct GeneralBlockRange { + pub lba_start: usize, + pub lba_end: usize, +} + +impl GeneralBlockRange { + pub fn new(lba_start: usize, lba_end: usize) -> Option { + if lba_start >= lba_end { + return None; + } + return Some(GeneralBlockRange { lba_start, lba_end }); + } + + #[inline] + pub fn len(&self) -> usize { + return self.lba_end - self.lba_start; + } + + /// 取交集 + pub fn intersects_with(&self, rhs: &Self) -> Option { + // 检查是否相交 + if self.lba_start <= rhs.lba_end && self.lba_end >= rhs.lba_start { + // 计算相交部分的起始和结束 LBA + let start = usize::max(self.lba_start, rhs.lba_start); + let end = usize::min(self.lba_end, rhs.lba_end); + // 返回相交部分 + GeneralBlockRange::new(start, end) + } else { + // 不相交,返回 None + None + } + } +} + /// @brief 块设备的迭代器 /// @usage 某次操作读/写块设备的[L,R]范围内的字节, /// 那么可以使用此结构体进行迭代遍历,每次调用next()返回一个BlockRange @@ -186,8 +221,80 @@ pub fn __lba_to_bytes(lba_id: usize, blk_size: usize) -> BlockId { return lba_id * blk_size; } +/// 块设备的名字 +pub struct BlockDevName { + name: Arc, + id: usize, +} + +impl BlockDevName { + pub fn new(name: String, id: usize) -> Self { + return BlockDevName { + name: Arc::new(name), + id, + }; + } + + #[inline] + pub fn id(&self) -> usize { + return self.id; + } +} + +impl core::fmt::Debug for BlockDevName { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + return write!(f, "{}", self.name); + } +} + +impl Display for BlockDevName { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + return write!(f, "{}", self.name); + } +} + +impl Clone for BlockDevName { + fn clone(&self) -> Self { + return BlockDevName { + name: self.name.clone(), + id: self.id, + }; + } +} + +impl core::hash::Hash for BlockDevName { + fn hash(&self, state: &mut H) { + self.name.hash(state); + } +} + +impl Deref for BlockDevName { + type Target = String; + + fn deref(&self) -> &Self::Target { + return self.name.as_ref(); + } +} + +impl PartialEq for BlockDevName { + fn eq(&self, other: &Self) -> bool { + return self.name == other.name; + } +} + +impl Eq for BlockDevName {} + /// @brief 块设备应该实现的操作 pub trait BlockDevice: Device { + /// # dev_name + /// 返回块设备的名字 + fn dev_name(&self) -> &BlockDevName; + + fn blkdev_meta(&self) -> &BlockDevMeta; + + /// 获取设备的扇区范围 + fn disk_range(&self) -> GeneralBlockRange; + /// @brief: 在块设备中,从第lba_id_start个块开始,读取count个块数据,存放到buf中 /// /// @parameter lba_id_start: 起始块 @@ -379,6 +486,11 @@ pub trait BlockDevice: Device { } return Ok(len); } + + /// # gendisk注册成功的回调函数 + fn callback_gendisk_registered(&self, _gendisk: &Arc) -> Result<(), SystemError> { + Ok(()) + } } /// @brief 块设备框架函数集 diff --git a/kernel/src/driver/base/block/disk_info.rs b/kernel/src/driver/base/block/disk_info.rs index faaf701dd..a22dcc193 100644 --- a/kernel/src/driver/base/block/disk_info.rs +++ b/kernel/src/driver/base/block/disk_info.rs @@ -1,22 +1,19 @@ #![allow(dead_code)] use alloc::sync::{Arc, Weak}; +use system_error::SystemError; -use super::block_device::BlockDevice; +use super::block_device::{BlockDevice, GeneralBlockRange}; pub type SectorT = u64; -pub const BLK_TYPE_AHCI: u64 = 0; -pub const DISK_NAME_LEN: usize = 32; // 磁盘名称的最大长度 -pub const BLK_GF_AHCI: u16 = 1 << 0; // 定义blk_gendisk中的标志位 - /// @brief: 磁盘的分区信息 - (保留了c版本的数据信息) #[derive(Debug)] pub struct Partition { - pub start_sector: SectorT, // 该分区的起始扇区 - pub lba_start: u64, // 起始LBA号 - pub sectors_num: u64, // 该分区的扇区数 - disk: Weak, // 当前分区所属的磁盘 - pub partno: u16, // 在磁盘上的分区号 + pub start_sector: SectorT, // 该分区的起始扇区 + pub lba_start: u64, // 起始LBA号 + pub sectors_num: u64, // 该分区的扇区数 + disk: Option>, // 当前分区所属的磁盘 + pub partno: u16, // 在磁盘上的分区号 } /// @brief: 分区信息 - 成员函数 @@ -33,14 +30,39 @@ impl Partition { start_sector, lba_start, sectors_num, - disk, + disk: Some(disk), partno, }); } + pub fn new_raw(start_sector: SectorT, lba_start: u64, sectors_num: u64, partno: u16) -> Self { + return Partition { + start_sector, + lba_start, + sectors_num, + disk: None, + partno, + }; + } + /// @brief 获取当前分区所属的磁盘的Arc指针 #[inline] pub fn disk(&self) -> Arc { - return self.disk.upgrade().unwrap(); + return self.disk.as_ref().unwrap().upgrade().unwrap(); + } +} + +impl TryInto for Partition { + type Error = SystemError; + + fn try_into(self) -> Result { + if let Some(range) = GeneralBlockRange::new( + self.lba_start as usize, + (self.lba_start + self.sectors_num) as usize, + ) { + return Ok(range); + } else { + return Err(SystemError::EINVAL); + } } } diff --git a/kernel/src/driver/base/block/gendisk.rs b/kernel/src/driver/base/block/gendisk.rs new file mode 100644 index 000000000..699d01af0 --- /dev/null +++ b/kernel/src/driver/base/block/gendisk.rs @@ -0,0 +1,195 @@ +use core::{ + ops::{Deref, DerefMut}, + sync::atomic::{AtomicU32, Ordering}, +}; + +use alloc::sync::{Arc, Weak}; +use hashbrown::HashMap; +use system_error::SystemError; + +use super::block_device::{BlockDevice, BlockId, GeneralBlockRange, LBA_SIZE}; + +#[derive(Debug)] +pub struct GenDisk { + bdev: Weak, + range: GeneralBlockRange, + block_size_log2: u8, + idx: Option, +} + +impl GenDisk { + /// 如果gendisk是整个磁盘,则idx为u32::MAX + pub const ENTIRE_DISK_IDX: u32 = u32::MAX; + + pub fn new( + bdev: Weak, + range: GeneralBlockRange, + idx: Option, + ) -> Arc { + let bsizelog2 = bdev.upgrade().unwrap().blk_size_log2(); + + return Arc::new(GenDisk { + bdev, + range, + block_size_log2: bsizelog2, + idx, + }); + } + + pub fn block_device(&self) -> Arc { + return self.bdev.upgrade().unwrap(); + } + + /// # read_at + /// + /// 读取分区内的数据 + /// + /// ## 参数 + /// + /// - buf: 输出缓冲区,大小必须为LBA_SIZE的整数倍,否则返回EINVAL + /// - start_block_offset: 分区内的块号 + pub fn read_at( + &self, + buf: &mut [u8], + start_block_offset: BlockId, + ) -> Result { + if (buf.len() & (LBA_SIZE - 1)) > 0 { + return Err(SystemError::EINVAL); + } + + let blocks = buf.len() / (1 << self.block_size_log2 as usize); + let lba = self.block_offset_2_disk_blkid(start_block_offset); + + return self.block_device().read_at(lba, blocks, buf); + } + + /// # read_at_bytes + /// + /// 按字节偏移量从分区中读取数据 + /// + /// ## 参数 + /// + /// - buf: 输出缓冲区 + /// - bytes_offset: 分区内的字节偏移量 + pub fn read_at_bytes(&self, buf: &mut [u8], bytes_offset: usize) -> Result { + let start_lba = self.range.lba_start; + let bytes_offset = self.disk_blkid_2_bytes(start_lba) + bytes_offset; + return self + .block_device() + .read_at_bytes(bytes_offset, buf.len(), buf); + } + + /// # 分区内的字节偏移量转换为磁盘上的字节偏移量 + pub fn disk_bytes_offset(&self, bytes_offset: usize) -> usize { + let start_lba = self.range.lba_start; + return self.disk_blkid_2_bytes(start_lba) + bytes_offset; + } + + /// # write_at_bytes + /// + /// 按字节偏移量向分区写入数据 + /// + /// ## 参数 + /// + /// - buf: 输入缓冲区 + /// - bytes_offset: 分区内的字节偏移量 + pub fn write_at_bytes(&self, buf: &[u8], bytes_offset: usize) -> Result { + let start_lba = self.range.lba_start; + let bytes_offset = self.disk_blkid_2_bytes(start_lba) + bytes_offset; + return self + .block_device() + .write_at_bytes(bytes_offset, buf.len(), buf); + } + + /// # write_at + /// + /// 向分区内写入数据 + /// + /// ## 参数 + /// + /// - buf: 输入缓冲区,大小必须为LBA_SIZE的整数倍,否则返回EINVAL + /// - start_block_offset: 分区内的块号 + pub fn write_at(&self, buf: &[u8], start_block_offset: BlockId) -> Result { + if (buf.len() & (LBA_SIZE - 1)) > 0 { + return Err(SystemError::EINVAL); + } + + let blocks = buf.len() / (1 << self.block_size_log2 as usize); + let lba = self.block_offset_2_disk_blkid(start_block_offset); + return self.block_device().write_at(lba, blocks, buf); + } + + #[inline] + fn block_offset_2_disk_blkid(&self, block_offset: BlockId) -> BlockId { + self.range.lba_start + block_offset + } + + #[inline] + fn disk_blkid_2_bytes(&self, disk_blkid: BlockId) -> usize { + disk_blkid * LBA_SIZE + } + + #[inline] + pub fn idx(&self) -> u32 { + self.idx.unwrap_or(Self::ENTIRE_DISK_IDX) + } + + #[inline] + pub fn range(&self) -> &GeneralBlockRange { + &self.range + } + + /// # sync + /// 同步磁盘 + pub fn sync(&self) -> Result<(), SystemError> { + self.block_device().sync() + } +} + +#[derive(Default)] +pub struct GenDiskMap { + data: HashMap>, + max_idx: AtomicU32, +} + +impl GenDiskMap { + pub fn new() -> Self { + GenDiskMap { + data: HashMap::new(), + max_idx: AtomicU32::new(1), + } + } + + #[inline] + pub fn max_idx(&self) -> u32 { + self.max_idx.load(Ordering::SeqCst) + } + + #[inline] + pub fn alloc_idx(&self) -> u32 { + self.max_idx.fetch_add(1, Ordering::SeqCst) + } + + pub fn intersects(&self, range: &GeneralBlockRange) -> bool { + for (_, v) in self.iter() { + if range.intersects_with(&v.range).is_some() { + return true; + } + } + return false; + } +} + +impl Deref for GenDiskMap { + type Target = HashMap>; + + fn deref(&self) -> &Self::Target { + &self.data + } +} + +impl DerefMut for GenDiskMap { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.data + } +} diff --git a/kernel/src/driver/base/block/manager.rs b/kernel/src/driver/base/block/manager.rs new file mode 100644 index 000000000..5ebda4c7b --- /dev/null +++ b/kernel/src/driver/base/block/manager.rs @@ -0,0 +1,238 @@ +use core::fmt::Formatter; + +use alloc::sync::Arc; +use hashbrown::HashMap; +use system_error::SystemError; +use unified_init::macros::unified_init; + +use crate::{ + driver::base::block::gendisk::GenDisk, + filesystem::mbr::MbrDiskPartionTable, + init::initcall::INITCALL_POSTCORE, + libs::spinlock::{SpinLock, SpinLockGuard}, +}; + +use super::{ + block_device::{BlockDevName, BlockDevice, GeneralBlockRange}, + gendisk::GenDiskMap, +}; + +static mut BLOCK_DEV_MANAGER: Option = None; + +#[inline] +pub fn block_dev_manager() -> &'static BlockDevManager { + unsafe { BLOCK_DEV_MANAGER.as_ref().unwrap() } +} + +#[unified_init(INITCALL_POSTCORE)] +pub fn block_dev_manager_init() -> Result<(), SystemError> { + unsafe { + BLOCK_DEV_MANAGER = Some(BlockDevManager::new()); + } + Ok(()) +} + +/// 磁盘设备管理器 +pub struct BlockDevManager { + inner: SpinLock, +} + +struct InnerBlockDevManager { + disks: HashMap>, +} +impl BlockDevManager { + pub fn new() -> Self { + BlockDevManager { + inner: SpinLock::new(InnerBlockDevManager { + disks: HashMap::new(), + }), + } + } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } + + /// 注册磁盘设备 + pub fn register(&self, dev: Arc) -> Result<(), SystemError> { + let mut inner = self.inner(); + let dev_name = dev.dev_name(); + if inner.disks.contains_key(dev_name) { + return Err(SystemError::EEXIST); + } + inner.disks.insert(dev_name.clone(), dev.clone()); + + let mut out_remove = || { + inner.disks.remove(dev_name); + }; + + // 检测分区表,并创建gendisk + self.check_partitions(&dev).inspect_err(|_| out_remove())?; + Ok(()) + } + + /// 检测分区表,并创建gendisk + fn check_partitions(&self, dev: &Arc) -> Result<(), SystemError> { + if self.check_mbr(dev).is_ok() { + return Ok(()); + } + + // use entire disk as a gendisk + self.register_entire_disk_as_gendisk(dev) + } + + fn check_mbr(&self, dev: &Arc) -> Result<(), SystemError> { + let mbr = MbrDiskPartionTable::from_disk(dev.clone())?; + let piter = mbr.partitions_raw(); + for p in piter { + self.register_gendisk_with_range(dev, p.try_into()?)?; + } + Ok(()) + } + + /// 将整个磁盘注册为gendisk + fn register_entire_disk_as_gendisk( + &self, + dev: &Arc, + ) -> Result<(), SystemError> { + let range = dev.disk_range(); + self.register_gendisk_with_range(dev, range) + } + + fn register_gendisk_with_range( + &self, + dev: &Arc, + range: GeneralBlockRange, + ) -> Result<(), SystemError> { + let weak_dev = Arc::downgrade(dev); + let gendisk = GenDisk::new( + weak_dev, + range, + Some(dev.blkdev_meta().inner().gendisks.alloc_idx()), + ); + self.register_gendisk(dev, gendisk) + } + + fn register_gendisk( + &self, + dev: &Arc, + gendisk: Arc, + ) -> Result<(), SystemError> { + let blk_meta = dev.blkdev_meta(); + let idx = gendisk.idx(); + let mut meta_inner = blk_meta.inner(); + // 检查是否重复 + if meta_inner.gendisks.intersects(gendisk.range()) { + return Err(SystemError::EEXIST); + } + + meta_inner.gendisks.insert(idx, gendisk.clone()); + dev.callback_gendisk_registered(&gendisk).inspect_err(|_| { + meta_inner.gendisks.remove(&idx); + })?; + Ok(()) + } + + /// 卸载磁盘设备 + pub fn unregister(&self, dev: &Arc) { + let mut inner = self.inner(); + inner.disks.remove(dev.dev_name()); + // todo: 这里应该callback一下磁盘设备,但是现在还没实现热插拔,所以暂时没做这里 + todo!("BlockDevManager: unregister disk") + } + + /// 通过路径查找gendisk + /// + /// # 参数 + /// + /// - `path`: 分区路径 `/dev/sda1` 或者 `sda1`,或者是`/dev/sda` + pub fn lookup_gendisk_by_path(&self, path: &str) -> Option> { + let (devname, partno) = self.path2devname(path)?; + let inner = self.inner(); + for dev in inner.disks.values() { + if dev.dev_name().as_str() == devname { + return dev.blkdev_meta().inner().gendisks.get(&partno).cloned(); + } + } + None + } + + /// 打印所有的gendisk的路径 + pub fn print_gendisks(&self) { + let mut disks = alloc::vec::Vec::new(); + + let inner = self.inner(); + for dev in inner.disks.values() { + let meta = dev.blkdev_meta().inner(); + for idx in meta.gendisks.keys() { + if idx == &GenDisk::ENTIRE_DISK_IDX { + disks.push(format!("/dev/{}", dev.dev_name())); + } else { + disks.push(format!("/dev/{}{}", dev.dev_name(), idx)); + } + } + } + + log::debug!("All gendisks: {:?}", disks); + } + + /// 将路径转换为设备名以及分区号 + /// + /// 例如: sda1 -> (sda, 1) nvme0n1p1 -> (nvme0n1, 1) + fn path2devname<'a>(&self, mut path: &'a str) -> Option<(&'a str, u32)> { + // 去除开头的"/dev/" + if path.starts_with("/dev/") { + path = path.strip_prefix("/dev/")?; + } + + let mut partno = GenDisk::ENTIRE_DISK_IDX; + // 截取末尾数字 + let mut last_digit = path.len(); + while last_digit > 0 && path.chars().nth(last_digit - 1).unwrap().is_ascii_digit() { + last_digit -= 1; + } + if last_digit == 0 { + return (path, GenDisk::ENTIRE_DISK_IDX).into(); + } + + if last_digit < path.len() { + partno = path[last_digit..].parse().ok()?; + } + + let path = &path[..last_digit]; + + Some((path, partno)) + } +} + +pub struct BlockDevMeta { + pub devname: BlockDevName, + inner: SpinLock, +} + +pub struct InnerBlockDevMeta { + pub gendisks: GenDiskMap, +} + +impl BlockDevMeta { + pub fn new(devname: BlockDevName) -> Self { + BlockDevMeta { + devname, + inner: SpinLock::new(InnerBlockDevMeta { + gendisks: GenDiskMap::new(), + }), + } + } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } +} + +impl core::fmt::Debug for BlockDevMeta { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("BlockDevMeta") + .field("devname", &self.devname) + .finish() + } +} diff --git a/kernel/src/driver/base/block/mod.rs b/kernel/src/driver/base/block/mod.rs index 89bbeb011..a34479836 100644 --- a/kernel/src/driver/base/block/mod.rs +++ b/kernel/src/driver/base/block/mod.rs @@ -1,5 +1,8 @@ pub mod block_device; pub mod disk_info; +pub mod gendisk; +pub mod manager; + #[derive(Debug)] #[allow(dead_code)] pub enum SeekFrom { diff --git a/kernel/src/driver/block/virtio_blk.rs b/kernel/src/driver/block/virtio_blk.rs index 2475e9f93..73190d17b 100644 --- a/kernel/src/driver/block/virtio_blk.rs +++ b/kernel/src/driver/block/virtio_blk.rs @@ -5,17 +5,19 @@ use alloc::{ sync::{Arc, Weak}, vec::Vec, }; -use log::{debug, error}; +use bitmap::traits::BitMapOps; +use log::error; use system_error::SystemError; use unified_init::macros::unified_init; -use virtio_drivers::device::blk::VirtIOBlk; +use virtio_drivers::device::blk::{VirtIOBlk, SECTOR_SIZE}; use crate::{ driver::{ base::{ block::{ - block_device::{BlockDevice, BlockId, LBA_SIZE}, + block_device::{BlockDevName, BlockDevice, BlockId, GeneralBlockRange, LBA_SIZE}, disk_info::Partition, + manager::{block_dev_manager, BlockDevMeta}, }, class::Class, device::{ @@ -64,18 +66,82 @@ pub fn virtio_blk_0() -> Option> { pub fn virtio_blk(transport: VirtIOTransport, dev_id: Arc) { let device = VirtIOBlkDevice::new(transport, dev_id); if let Some(device) = device { - debug!("VirtIOBlkDevice '{:?}' created", device.dev_id); virtio_device_manager() .device_add(device.clone() as Arc) .expect("Add virtio blk failed"); } } +static mut VIRTIOBLK_MANAGER: Option = None; + +#[inline] +fn virtioblk_manager() -> &'static VirtIOBlkManager { + unsafe { VIRTIOBLK_MANAGER.as_ref().unwrap() } +} + +#[unified_init(INITCALL_POSTCORE)] +fn virtioblk_manager_init() -> Result<(), SystemError> { + unsafe { + VIRTIOBLK_MANAGER = Some(VirtIOBlkManager::new()); + } + Ok(()) +} + +pub struct VirtIOBlkManager { + inner: SpinLock, +} + +struct InnerVirtIOBlkManager { + id_bmp: bitmap::StaticBitmap<{ VirtIOBlkManager::MAX_DEVICES }>, + devname: [Option; VirtIOBlkManager::MAX_DEVICES], +} + +impl VirtIOBlkManager { + pub const MAX_DEVICES: usize = 25; + + pub fn new() -> Self { + Self { + inner: SpinLock::new(InnerVirtIOBlkManager { + id_bmp: bitmap::StaticBitmap::new(), + devname: [const { None }; Self::MAX_DEVICES], + }), + } + } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } + + pub fn alloc_id(&self) -> Option { + let mut inner = self.inner(); + let idx = inner.id_bmp.first_false_index()?; + inner.id_bmp.set(idx, true); + let name = Self::format_name(idx); + inner.devname[idx] = Some(name.clone()); + Some(name) + } + + /// Generate a new block device name like 'vda', 'vdb', etc. + fn format_name(id: usize) -> BlockDevName { + let x = (b'a' + id as u8) as char; + BlockDevName::new(format!("vd{}", x), id) + } + + pub fn free_id(&self, id: usize) { + if id >= Self::MAX_DEVICES { + return; + } + self.inner().id_bmp.set(id, false); + self.inner().devname[id] = None; + } +} + /// virtio block device #[derive(Debug)] #[cast_to([sync] VirtIODevice)] #[cast_to([sync] Device)] pub struct VirtIOBlkDevice { + blkdev_meta: BlockDevMeta, dev_id: Arc, inner: SpinLock, locked_kobj_state: LockedKObjectState, @@ -87,6 +153,7 @@ unsafe impl Sync for VirtIOBlkDevice {} impl VirtIOBlkDevice { pub fn new(transport: VirtIOTransport, dev_id: Arc) -> Option> { + let devname = virtioblk_manager().alloc_id()?; let irq = transport.irq().map(|irq| IrqNumber::new(irq.data())); let device_inner = VirtIOBlk::::new(transport); if let Err(e) = device_inner { @@ -97,6 +164,7 @@ impl VirtIOBlkDevice { let mut device_inner: VirtIOBlk = device_inner.unwrap(); device_inner.enable_interrupts(); let dev = Arc::new_cyclic(|self_ref| Self { + blkdev_meta: BlockDevMeta::new(devname), self_ref: self_ref.clone(), dev_id, locked_kobj_state: LockedKObjectState::default(), @@ -123,6 +191,26 @@ impl VirtIOBlkDevice { } impl BlockDevice for VirtIOBlkDevice { + fn dev_name(&self) -> &BlockDevName { + &self.blkdev_meta.devname + } + + fn blkdev_meta(&self) -> &BlockDevMeta { + &self.blkdev_meta + } + + fn disk_range(&self) -> GeneralBlockRange { + let inner = self.inner(); + let blocks = inner.device_inner.capacity() as usize * SECTOR_SIZE / LBA_SIZE; + drop(inner); + log::debug!( + "VirtIOBlkDevice '{:?}' disk_range: 0..{}", + self.dev_name(), + blocks + ); + GeneralBlockRange::new(0, blocks).unwrap() + } + fn read_at_sync( &self, lba_id_start: BlockId, @@ -411,7 +499,7 @@ struct InnerVirtIOBlkDriver { impl VirtIODriver for VirtIOBlkDriver { fn probe(&self, device: &Arc) -> Result<(), SystemError> { - let _dev = device + let dev = device .clone() .arc_any() .downcast::() @@ -423,6 +511,7 @@ impl VirtIODriver for VirtIOBlkDriver { SystemError::EINVAL })?; + block_dev_manager().register(dev as Arc)?; return Ok(()); } } diff --git a/kernel/src/driver/disk/ahci/ahcidisk.rs b/kernel/src/driver/disk/ahci/ahcidisk.rs index 2bbb15141..c2278ac66 100644 --- a/kernel/src/driver/disk/ahci/ahcidisk.rs +++ b/kernel/src/driver/disk/ahci/ahcidisk.rs @@ -1,7 +1,10 @@ use super::{_port, hba::HbaCmdTable}; use crate::arch::MMArch; -use crate::driver::base::block::block_device::{BlockDevice, BlockId}; +use crate::driver::base::block::block_device::{ + BlockDevName, BlockDevice, BlockId, GeneralBlockRange, +}; use crate::driver::base::block::disk_info::Partition; +use crate::driver::base::block::manager::BlockDevMeta; use crate::driver::base::class::Class; use crate::driver::base::device::bus::Bus; @@ -11,6 +14,7 @@ use crate::driver::base::kobject::{KObjType, KObject, KObjectState}; use crate::driver::base::kset::KSet; use crate::driver::disk::ahci::HBA_PxIS_TFES; +use crate::driver::scsi::scsi_manager; use crate::filesystem::kernfs::KernFSInode; use crate::filesystem::mbr::MbrDiskPartionTable; @@ -19,13 +23,13 @@ use crate::driver::disk::ahci::hba::{ ATA_DEV_DRQ, }; use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard}; -use crate::libs::spinlock::SpinLock; +use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use crate::mm::{verify_area, MemoryManagementArch, PhysAddr, VirtAddr}; use log::error; use system_error::SystemError; use alloc::sync::Weak; -use alloc::{string::String, sync::Arc, vec::Vec}; +use alloc::{sync::Arc, vec::Vec}; use core::fmt::Debug; use core::sync::atomic::{compiler_fence, Ordering}; @@ -33,8 +37,7 @@ use core::{mem::size_of, ptr::write_bytes}; /// @brief: 只支持MBR分区格式的磁盘结构体 pub struct AhciDisk { - pub name: String, - pub flags: u16, // 磁盘的状态flags + // 磁盘的状态flags pub partitions: Vec>, // 磁盘分区数组 // port: &'static mut HbaPort, // 控制硬盘的端口 pub ctrl_num: u8, @@ -45,16 +48,21 @@ pub struct AhciDisk { /// @brief: 带锁的AhciDisk #[derive(Debug)] -pub struct LockedAhciDisk(pub SpinLock); +pub struct LockedAhciDisk { + blkdev_meta: BlockDevMeta, + inner: SpinLock, +} + +impl LockedAhciDisk { + pub fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } +} + /// 函数实现 impl Debug for AhciDisk { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!( - f, - "{{ name: {}, flags: {}, part_s: {:?} }}", - self.name, self.flags, self.partitions - )?; - return Ok(()); + write!(f, "AhciDisk") } } @@ -371,35 +379,30 @@ impl AhciDisk { } impl LockedAhciDisk { - pub fn new( - name: String, - flags: u16, - ctrl_num: u8, - port_num: u8, - ) -> Result, SystemError> { + pub fn new(ctrl_num: u8, port_num: u8) -> Result, SystemError> { + let devname = scsi_manager().alloc_id().ok_or(SystemError::EBUSY)?; // 构建磁盘结构体 - let result: Arc = Arc::new_cyclic(|self_ref| { - LockedAhciDisk(SpinLock::new(AhciDisk { - name, - flags, - partitions: Default::default(), + let result: Arc = Arc::new_cyclic(|self_ref| LockedAhciDisk { + blkdev_meta: BlockDevMeta::new(devname), + inner: SpinLock::new(AhciDisk { + partitions: Vec::new(), ctrl_num, port_num, self_ref: self_ref.clone(), - })) + }), }); let table: MbrDiskPartionTable = result.read_mbr_table()?; // 求出有多少可用分区 let partitions = table.partitions(Arc::downgrade(&result) as Weak); - result.0.lock().partitions = partitions; + result.inner().partitions = partitions; return Ok(result); } /// @brief: 从磁盘中读取 MBR 分区表结构体 pub fn read_mbr_table(&self) -> Result { - let disk = self.0.lock().self_ref.upgrade().unwrap() as Arc; + let disk = self.inner().self_ref.upgrade().unwrap() as Arc; MbrDiskPartionTable::from_disk(disk) } } @@ -509,6 +512,18 @@ impl Device for LockedAhciDisk { } impl BlockDevice for LockedAhciDisk { + fn dev_name(&self) -> &BlockDevName { + &self.blkdev_meta.devname + } + + fn blkdev_meta(&self) -> &BlockDevMeta { + &self.blkdev_meta + } + + fn disk_range(&self) -> GeneralBlockRange { + todo!("Get ahci blk disk range") + } + #[inline] fn as_any_ref(&self) -> &dyn core::any::Any { self @@ -520,12 +535,12 @@ impl BlockDevice for LockedAhciDisk { } fn sync(&self) -> Result<(), SystemError> { - return self.0.lock().sync(); + return self.inner().sync(); } #[inline] fn device(&self) -> Arc { - return self.0.lock().self_ref.upgrade().unwrap(); + return self.inner().self_ref.upgrade().unwrap(); } fn block_size(&self) -> usize { @@ -533,7 +548,7 @@ impl BlockDevice for LockedAhciDisk { } fn partitions(&self) -> Vec> { - return self.0.lock().partitions.clone(); + return self.inner().partitions.clone(); } #[inline] @@ -543,7 +558,7 @@ impl BlockDevice for LockedAhciDisk { count: usize, // 读取lba的数量 buf: &mut [u8], ) -> Result { - self.0.lock().read_at(lba_id_start, count, buf) + self.inner().read_at(lba_id_start, count, buf) } #[inline] @@ -553,6 +568,6 @@ impl BlockDevice for LockedAhciDisk { count: usize, buf: &[u8], ) -> Result { - self.0.lock().write_at(lba_id_start, count, buf) + self.inner().write_at(lba_id_start, count, buf) } } diff --git a/kernel/src/driver/disk/ahci/mod.rs b/kernel/src/driver/disk/ahci/mod.rs index c72256efc..6fd31d859 100644 --- a/kernel/src/driver/disk/ahci/mod.rs +++ b/kernel/src/driver/disk/ahci/mod.rs @@ -4,31 +4,27 @@ pub mod ahcidisk; pub mod hba; use crate::arch::MMArch; -use crate::driver::base::block::disk_info::BLK_GF_AHCI; +use crate::driver::base::block::manager::block_dev_manager; use crate::driver::block::cache::cached_block_device::BlockCache; -// 依赖的rust工具包 +use crate::driver::disk::ahci::ahcidisk::LockedAhciDisk; use crate::driver::pci::pci::{ get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST, }; -use crate::filesystem::devfs::devfs_register; use crate::driver::disk::ahci::{ - ahcidisk::LockedAhciDisk, hba::HbaMem, hba::{HbaPort, HbaPortType}, }; use crate::libs::rwlock::RwLockWriteGuard; use crate::libs::spinlock::{SpinLock, SpinLockGuard}; use crate::mm::{MemoryManagementArch, VirtAddr}; -use ahci_inode::LockedAhciInode; -use alloc::{boxed::Box, collections::LinkedList, format, string::String, sync::Arc, vec::Vec}; +use alloc::{boxed::Box, collections::LinkedList, vec::Vec}; use core::sync::atomic::compiler_fence; -use log::{debug, error}; +use log::debug; use system_error::SystemError; // 仅module内可见 全局数据区 hbr_port, disks static LOCKED_HBA_MEM_LIST: SpinLock> = SpinLock::new(Vec::new()); -static LOCKED_DISKS_LIST: SpinLock>> = SpinLock::new(Vec::new()); const AHCI_CLASS: u8 = 0x1; const AHCI_SUBCLASS: u8 = 0x6; @@ -56,8 +52,6 @@ fn ahci_device_search<'a>( pub fn ahci_init() -> Result<(), SystemError> { let mut list = PCI_DEVICE_LINKEDLIST.write(); let ahci_device = ahci_device_search(&mut list)?; - // 全局数据 - 列表 - let mut disks_list = LOCKED_DISKS_LIST.lock(); for device in ahci_device { let standard_device = device.as_standard_device_mut().unwrap(); @@ -81,7 +75,6 @@ pub fn ahci_init() -> Result<(), SystemError> { let hba_mem_index = hba_mem_list.len() - 1; drop(hba_mem_list); // 初始化所有的port - let mut id = 0; for j in 0..32 { if (pi >> j) & 1 > 0 { let hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); @@ -124,31 +117,12 @@ pub fn ahci_init() -> Result<(), SystemError> { hba_mem_port.init(clb as u64, fb as u64, &ctbas); drop(hba_mem_list); compiler_fence(core::sync::atomic::Ordering::SeqCst); - // 创建 disk - disks_list.push(LockedAhciDisk::new( - format!("ahci_disk_{}", id), - BLK_GF_AHCI, - hba_mem_index as u8, - j as u8, - )?); - id += 1; // ID 从0开始 + let ahci_disk = LockedAhciDisk::new(hba_mem_index as u8, j as u8)?; + block_dev_manager() + .register(ahci_disk) + .expect("register ahci disk failed"); debug!("start register ahci device"); - - // 挂载到devfs上面去 - let ret = devfs_register( - format!("ahci_{}", id).as_str(), - LockedAhciInode::new(disks_list.last().unwrap().clone()), - ); - if let Err(err) = ret { - error!( - "Ahci_{} ctrl = {}, port = {} failed to register, error code = {:?}", - id, - hba_mem_index as u8, - j, - err - ); - } } } } @@ -160,24 +134,6 @@ pub fn ahci_init() -> Result<(), SystemError> { return Ok(()); } -/// @brief: 获取所有的 disk -#[allow(dead_code)] -pub fn disks() -> Vec> { - let disks_list = LOCKED_DISKS_LIST.lock(); - return disks_list.clone(); -} - -/// @brief: 通过 name 获取 disk -pub fn get_disks_by_name(name: String) -> Result, SystemError> { - let disks_list: SpinLockGuard>> = LOCKED_DISKS_LIST.lock(); - let result = disks_list - .iter() - .find(|x| x.0.lock().name == name) - .ok_or(SystemError::ENXIO)? - .clone(); - return Ok(result); -} - /// @brief: 通过 ctrl_num 和 port_num 获取 port fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort { let list: SpinLockGuard> = LOCKED_HBA_MEM_LIST.lock(); diff --git a/kernel/src/driver/mod.rs b/kernel/src/driver/mod.rs index c5ec23693..3b723b780 100644 --- a/kernel/src/driver/mod.rs +++ b/kernel/src/driver/mod.rs @@ -11,6 +11,7 @@ pub mod net; pub mod open_firmware; pub mod pci; pub mod rtc; +pub mod scsi; pub mod serial; pub mod timers; pub mod tty; diff --git a/kernel/src/driver/scsi/mod.rs b/kernel/src/driver/scsi/mod.rs new file mode 100644 index 000000000..83e6be572 --- /dev/null +++ b/kernel/src/driver/scsi/mod.rs @@ -0,0 +1,74 @@ +use bitmap::traits::BitMapOps; +use system_error::SystemError; +use unified_init::macros::unified_init; + +use crate::{ + init::initcall::INITCALL_POSTCORE, + libs::spinlock::{SpinLock, SpinLockGuard}, +}; + +use super::base::block::block_device::BlockDevName; + +static mut SCSI_MANAGER: Option = None; + +#[inline] +pub fn scsi_manager() -> &'static ScsiManager { + unsafe { SCSI_MANAGER.as_ref().unwrap() } +} + +#[unified_init(INITCALL_POSTCORE)] +fn scsi_manager_init() -> Result<(), SystemError> { + unsafe { + SCSI_MANAGER = Some(ScsiManager::new()); + } + Ok(()) +} + +pub struct ScsiManager { + inner: SpinLock, +} + +struct InnerScsiManager { + id_bmp: bitmap::StaticBitmap<{ ScsiManager::MAX_DEVICES }>, + devname: [Option; ScsiManager::MAX_DEVICES], +} + +impl ScsiManager { + pub const MAX_DEVICES: usize = 25; + + pub fn new() -> Self { + Self { + inner: SpinLock::new(InnerScsiManager { + id_bmp: bitmap::StaticBitmap::new(), + devname: [const { None }; Self::MAX_DEVICES], + }), + } + } + + fn inner(&self) -> SpinLockGuard { + self.inner.lock() + } + + pub fn alloc_id(&self) -> Option { + let mut inner = self.inner(); + let idx = inner.id_bmp.first_false_index()?; + inner.id_bmp.set(idx, true); + let name = Self::format_name(idx); + inner.devname[idx] = Some(name.clone()); + Some(name) + } + + /// Generate a new block device name like 'sda', 'sdb', etc. + fn format_name(id: usize) -> BlockDevName { + let x = (b'a' + id as u8) as char; + BlockDevName::new(format!("sd{}", x), id) + } + + pub fn free_id(&self, id: usize) { + if id >= Self::MAX_DEVICES { + return; + } + self.inner().id_bmp.set(id, false); + self.inner().devname[id] = None; + } +} diff --git a/kernel/src/driver/virtio/irq.rs b/kernel/src/driver/virtio/irq.rs index aa727670e..c5d075eb0 100644 --- a/kernel/src/driver/virtio/irq.rs +++ b/kernel/src/driver/virtio/irq.rs @@ -1,6 +1,5 @@ use alloc::sync::Arc; use hashbrown::HashMap; -use log::warn; use system_error::SystemError; use unified_init::macros::unified_init; @@ -121,7 +120,7 @@ impl IrqHandler for DefaultVirtioIrqHandler { return dev.handle_irq(irq); } else { // 未绑定具体设备,因此无法处理中断 - warn!("No device found for IRQ: {:?}", irq); + // warn!("No device found for IRQ: {:?}", irq); return Ok(IrqReturn::NotHandled); } } diff --git a/kernel/src/filesystem/fat/bpb.rs b/kernel/src/filesystem/fat/bpb.rs index 2f8d6ec77..c31e3a560 100644 --- a/kernel/src/filesystem/fat/bpb.rs +++ b/kernel/src/filesystem/fat/bpb.rs @@ -4,7 +4,7 @@ use log::error; use system_error::SystemError; use crate::{ - driver::base::block::{block_device::LBA_SIZE, disk_info::Partition, SeekFrom}, + driver::base::block::{block_device::LBA_SIZE, gendisk::GenDisk, SeekFrom}, libs::vec_cursor::VecCursor, }; @@ -219,14 +219,10 @@ impl BiosParameterBlockFAT32 { } impl BiosParameterBlock { - pub fn new(partition: Arc) -> Result { + pub fn new(gendisk: &Arc) -> Result { let mut v = vec![0; LBA_SIZE]; - // 读取分区的引导扇区 - partition - .disk() - .read_at_sync(partition.lba_start as usize, 1, &mut v)?; - + gendisk.read_at(&mut v, 0)?; // 获取指针对象 let mut cursor = VecCursor::new(v); diff --git a/kernel/src/filesystem/fat/entry.rs b/kernel/src/filesystem/fat/entry.rs index cafb3dc4c..0e825bf05 100644 --- a/kernel/src/filesystem/fat/entry.rs +++ b/kernel/src/filesystem/fat/entry.rs @@ -130,11 +130,9 @@ impl FATFile { // 从磁盘上读取数据 let offset = fs.cluster_bytes_offset(current_cluster) + in_cluster_offset; - let r = fs.partition.disk().read_at_bytes( - offset as usize, - end_len, - &mut buf[start..start + end_len], - )?; + let r = fs + .gendisk + .read_at_bytes(&mut buf[start..start + end_len], offset as usize)?; // 更新偏移量计数信息 read_ok += r; @@ -195,14 +193,12 @@ impl FATFile { buf.len() - write_ok, ); - // 计算本次写入位置在磁盘上的偏移量 + // 计算本次写入位置在分区上的偏移量 let offset = fs.cluster_bytes_offset(current_cluster) + in_cluster_bytes_offset; // 写入磁盘 - let w: usize = fs.partition.disk().write_at_bytes( - offset as usize, - end_len, - &buf[start..start + end_len], - )?; + let w = fs + .gendisk + .write_at_bytes(&buf[start..start + end_len], offset as usize)?; // 更新偏移量数据 write_ok += w; @@ -282,7 +278,7 @@ impl FATFile { let start_cluster: Cluster = fs .get_cluster_by_relative(self.first_cluster, start_cluster as usize) .unwrap(); - // 计算当前文件末尾在磁盘上的字节偏移量 + // 计算当前文件末尾在分区上的字节偏移量 let start_offset: u64 = fs.cluster_bytes_offset(start_cluster) + self.size() % fs.bytes_per_cluster(); // 扩展之前,最后一个簇内还剩下多少字节的空间 @@ -311,10 +307,10 @@ impl FATFile { return Ok(()); } - /// @brief 把磁盘上[range_start, range_end)范围的数据清零 + /// @brief 把分区上[range_start, range_end)范围的数据清零 /// - /// @param range_start 磁盘上起始位置(单位:字节) - /// @param range_end 磁盘上终止位置(单位:字节) + /// @param range_start 分区上起始位置(单位:字节) + /// @param range_end 分区上终止位置(单位:字节) fn zero_range( &self, fs: &Arc, @@ -326,9 +322,8 @@ impl FATFile { } let zeroes: Vec = vec![0u8; (range_end - range_start) as usize]; - fs.partition - .disk() - .write_at(range_start as usize, zeroes.len(), zeroes.as_slice())?; + fs.gendisk.write_at_bytes(&zeroes, range_start as usize)?; + return Ok(()); } @@ -357,7 +352,7 @@ impl FATFile { } self.set_size(new_size as u32); - // 计算短目录项在磁盘内的字节偏移量 + // 计算短目录项在分区内的字节偏移量 let short_entry_offset = fs.cluster_bytes_offset((self.loc.1).0) + (self.loc.1).1; self.short_dir_entry.flush(fs, short_entry_offset)?; @@ -370,7 +365,7 @@ impl FATFile { pub struct FATDir { /// 目录的第一个簇 pub first_cluster: Cluster, - /// 该字段仅对FAT12、FAT16生效 + /// 该字段仅对FAT12、FAT16生效,表示根目录在分区内的偏移量 pub root_offset: Option, /// 文件夹名称 pub dir_name: String, @@ -747,14 +742,14 @@ impl FATDir { for off in &offsets.as_slice()[..offsets.len() - 1] { // 获取生成的下一个长目录项 let long_entry: LongDirEntry = long_name_gen.next().unwrap(); - // 获取这个长目录项在磁盘内的字节偏移量 + // 获取这个长目录项在分区内的字节偏移量 let bytes_offset = fs.cluster_bytes_offset(off.0) + off.1; long_entry.flush(fs.clone(), bytes_offset)?; } let start: (Cluster, u64) = offsets[0]; let end: (Cluster, u64) = *offsets.last().unwrap(); - // 短目录项在磁盘上的字节偏移量 + // 短目录项在分区内的字节偏移量 let offset = fs.cluster_bytes_offset(end.0) + end.1; short_dentry.flush(&fs, offset)?; @@ -827,10 +822,10 @@ impl FATDir { .collect(); // 逐个设置这些目录项为“空闲”状态 for off in offsets { - let disk_bytes_offset = fs.cluster_bytes_offset(off.0) + off.1; + let gendisk_bytes_offset = fs.cluster_bytes_offset(off.0) + off.1; let mut short_entry = ShortDirEntry::default(); short_entry.name[0] = 0xe5; - short_entry.flush(&fs, disk_bytes_offset)?; + short_entry.flush(&fs, gendisk_bytes_offset)?; } return Ok(()); } @@ -1130,20 +1125,20 @@ impl LongDirEntry { /// @brief 把当前长目录项写入磁盘 /// /// @param fs 对应的文件系统 - /// @param disk_bytes_offset 长目录项所在位置对应的在磁盘上的字节偏移量 + /// @param disk_bytes_offset 长目录项所在位置对应的在分区内的字节偏移量 /// /// @return Ok(()) /// @return Err(SystemError) 错误码 - pub fn flush(&self, fs: Arc, disk_bytes_offset: u64) -> Result<(), SystemError> { + pub fn flush( + &self, + fs: Arc, + gendisk_bytes_offset: u64, + ) -> Result<(), SystemError> { // 从磁盘读取数据 - let blk_offset = fs.get_in_block_offset(disk_bytes_offset); - let lba = fs.get_lba_from_offset( - fs.bytes_to_sector(fs.get_in_partition_bytes_offset(disk_bytes_offset)), - ); + let blk_offset = fs.get_in_block_offset(gendisk_bytes_offset); + let lba = fs.gendisk_lba_from_offset(fs.bytes_to_sector(gendisk_bytes_offset)); let mut v: Vec = vec![0; fs.lba_per_sector() * LBA_SIZE]; - fs.partition - .disk() - .read_at(lba, fs.lba_per_sector(), &mut v)?; + fs.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); // 切换游标到对应位置 @@ -1170,10 +1165,9 @@ impl LongDirEntry { } // 把修改后的长目录项刷入磁盘 - fs.partition - .disk() - .write_at(lba, fs.lba_per_sector(), cursor.as_slice())?; - fs.partition.disk().sync()?; + fs.gendisk.write_at(cursor.as_slice(), lba)?; + + fs.gendisk.sync()?; return Ok(()); } @@ -1338,27 +1332,26 @@ impl ShortDirEntry { return result; } - /// @brief 把当前短目录项写入磁盘 + /// # 把当前短目录项写入磁盘 /// - /// @param fs 对应的文件系统 - /// @param disk_bytes_offset 短目录项所在位置对应的在磁盘上的字节偏移量 + /// ## 参数 /// - /// @return Ok(()) - /// @return Err(SystemError) 错误码 + /// - fs 对应的文件系统 + /// - gendisk_bytes_offset 短目录项所在位置对应的在分区内的字节偏移量 + /// + /// # 返回值 + /// - Ok(()) + /// - Err(SystemError) 错误码 pub fn flush( &self, fs: &Arc, - disk_bytes_offset: u64, + gendisk_bytes_offset: u64, ) -> Result<(), SystemError> { // 从磁盘读取数据 - let blk_offset = fs.get_in_block_offset(disk_bytes_offset); - let lba = fs.get_lba_from_offset( - fs.bytes_to_sector(fs.get_in_partition_bytes_offset(disk_bytes_offset)), - ); + let blk_offset = fs.get_in_block_offset(gendisk_bytes_offset); + let lba = fs.gendisk_lba_from_offset(fs.bytes_to_sector(gendisk_bytes_offset)); let mut v: Vec = vec![0; fs.lba_per_sector() * LBA_SIZE]; - fs.partition - .disk() - .read_at(lba, fs.lba_per_sector(), &mut v)?; + fs.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); // 切换游标到对应位置 @@ -1377,10 +1370,9 @@ impl ShortDirEntry { cursor.write_u32(self.file_size)?; // 把修改后的长目录项刷入磁盘 - fs.partition - .disk() - .write_at(lba, fs.lba_per_sector(), cursor.as_slice())?; - fs.partition.disk().sync()?; + fs.gendisk.write_at(cursor.as_slice(), lba)?; + + fs.gendisk.sync()?; return Ok(()); } @@ -1492,7 +1484,7 @@ impl FATDirIter { return Ok((self.current_cluster, self.offset, None)); } - // 获取簇在磁盘内的字节偏移量 + // 获取簇在分区内的字节偏移量 let offset: u64 = self.fs.cluster_bytes_offset(self.current_cluster) + self.offset; // 从磁盘读取原始的dentry @@ -1551,7 +1543,7 @@ impl FATDirIter { break; } - // 获取簇在磁盘内的字节偏移量 + // 获取簇在分区内的字节偏移量 let offset: u64 = self.fs.cluster_bytes_offset(self.current_cluster) + self.offset; // 从磁盘读取原始的dentry @@ -2398,24 +2390,18 @@ impl Iterator for FATDirEntryOffsetIter { } } -/// @brief 根据磁盘内字节偏移量,读取磁盘,并生成一个FATRawDirEntry对象 +/// 根据分区字节偏移量,读取磁盘,并生成一个FATRawDirEntry对象 pub fn get_raw_dir_entry( fs: &Arc, - in_disk_bytes_offset: u64, + gendisk_bytes_offset: u64, ) -> Result { // 块内偏移量 - let blk_offset: u64 = fs.get_in_block_offset(in_disk_bytes_offset); - let lba = fs.get_lba_from_offset( - fs.bytes_to_sector(fs.get_in_partition_bytes_offset(in_disk_bytes_offset)), - ); - - // let step1 = fs.get_in_partition_bytes_offset(in_disk_bytes_offset); - // let step2 = fs.bytes_to_sector(step1); - // let lba = fs.get_lba_from_offset(step2); - // debug!("step1={step1}, step2={step2}, lba={lba}"); + let blk_offset: u64 = fs.get_in_block_offset(gendisk_bytes_offset); + let lba = fs.gendisk_lba_from_offset(fs.bytes_to_sector(gendisk_bytes_offset)); + let mut v: Vec = vec![0; LBA_SIZE]; - fs.partition.disk().read_at(lba, 1, &mut v)?; + fs.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); // 切换游标到对应位置 diff --git a/kernel/src/filesystem/fat/fs.rs b/kernel/src/filesystem/fat/fs.rs index 61eb16174..64967b205 100644 --- a/kernel/src/filesystem/fat/fs.rs +++ b/kernel/src/filesystem/fat/fs.rs @@ -12,6 +12,7 @@ use alloc::{ vec::Vec, }; +use crate::driver::base::block::gendisk::GenDisk; use crate::driver::base::device::device_number::DeviceNumber; use crate::filesystem::vfs::utils::DName; use crate::filesystem::vfs::{Magic, SpecialNodeData, SuperBlock}; @@ -71,7 +72,7 @@ impl Eq for Cluster {} #[derive(Debug)] pub struct FATFileSystem { /// 当前文件系统所在的分区 - pub partition: Arc, + pub gendisk: Arc, /// 当前文件系统的BOPB pub bpb: BiosParameterBlock, /// 当前文件系统的第一个数据扇区(相对分区开始位置) @@ -281,17 +282,16 @@ impl FATFileSystem { /// FAT32允许的最大簇号 pub const FAT32_MAX_CLUSTER: u32 = 0x0FFFFFF7; - pub fn new(partition: Arc) -> Result, SystemError> { - let bpb = BiosParameterBlock::new(partition.clone())?; - + pub fn new(gendisk: Arc) -> Result, SystemError> { + let bpb = BiosParameterBlock::new(&gendisk)?; // 从磁盘上读取FAT32文件系统的FsInfo结构体 let fs_info: FATFsInfo = match bpb.fat_type { FATType::FAT32(bpb32) => { - let fs_info_in_disk_bytes_offset = partition.lba_start * LBA_SIZE as u64 - + bpb32.fs_info as u64 * bpb.bytes_per_sector as u64; + let fs_info_in_gendisk_bytes_offset = + bpb32.fs_info as usize * bpb.bytes_per_sector as usize; FATFsInfo::new( - partition.clone(), - fs_info_in_disk_bytes_offset, + &gendisk, + fs_info_in_gendisk_bytes_offset, bpb.bytes_per_sector as usize, )? } @@ -351,7 +351,7 @@ impl FATFileSystem { }))); let result: Arc = Arc::new(FATFileSystem { - partition, + gendisk, bpb, first_data_sector, fs_info: Arc::new(LockedFATFsInfo::new(fs_info)), @@ -398,17 +398,14 @@ impl FATFileSystem { let fat_bytes_offset = fat_type.get_fat_bytes_offset(cluster, fat_start_sector, bytes_per_sec); - // FAT表项所在的LBA地址 - // let fat_ent_lba = self.get_lba_from_offset(self.bytes_to_sector(fat_bytes_offset)); - let fat_ent_lba = self.partition.lba_start + fat_bytes_offset / LBA_SIZE as u64; + // FAT表项所在的分区内LBA地址 + let fat_ent_lba = fat_bytes_offset / LBA_SIZE as u64; // FAT表项在逻辑块内的字节偏移量 let blk_offset = self.get_in_block_offset(fat_bytes_offset); let mut v: Vec = vec![0; self.bpb.bytes_per_sector as usize]; - self.partition - .disk() - .read_at(fat_ent_lba as usize, self.lba_per_sector(), &mut v)?; + self.gendisk.read_at(&mut v, fat_ent_lba as usize)?; let mut cursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?; @@ -492,16 +489,14 @@ impl FATFileSystem { let fat_bytes_offset = fat_type.get_fat_bytes_offset(cluster, fat_start_sector, bytes_per_sec); - // FAT表项所在的LBA地址 - let fat_ent_lba = self.get_lba_from_offset(self.bytes_to_sector(fat_bytes_offset)); + // FAT表项所在的分区内LBA地址 + let fat_ent_lba = self.gendisk_lba_from_offset(self.bytes_to_sector(fat_bytes_offset)); // FAT表项在逻辑块内的字节偏移量 let blk_offset = self.get_in_block_offset(fat_bytes_offset); let mut v: Vec = vec![0; self.bpb.bytes_per_sector as usize]; - self.partition - .disk() - .read_at(fat_ent_lba, self.lba_per_sector(), &mut v)?; + self.gendisk.read_at(&mut v, fat_ent_lba)?; let mut cursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?; @@ -529,24 +524,24 @@ impl FATFileSystem { return Ok(res); } - /// @brief 获取当前文件系统的root inode,在磁盘上的字节偏移量 + /// @brief 获取当前文件系统的root inode,在分区内的字节偏移量 pub fn root_dir_bytes_offset(&self) -> u64 { match self.bpb.fat_type { FATType::FAT32(s) => { let first_sec_cluster: u64 = (s.root_cluster as u64 - 2) * (self.bpb.sector_per_cluster as u64) + self.first_data_sector; - return (self.get_lba_from_offset(first_sec_cluster) * LBA_SIZE) as u64; + return (self.gendisk_lba_from_offset(first_sec_cluster) * LBA_SIZE) as u64; } _ => { let root_sec = (self.bpb.rsvd_sec_cnt as u64) + (self.bpb.num_fats as u64) * (self.bpb.fat_size_16 as u64); - return (self.get_lba_from_offset(root_sec) * LBA_SIZE) as u64; + return (self.gendisk_lba_from_offset(root_sec) * LBA_SIZE) as u64; } } } - /// @brief 获取当前文件系统的根目录项区域的结束位置,在磁盘上的字节偏移量。 + /// @brief 获取当前文件系统的根目录项区域的结束位置,在分区内的字节偏移量。 /// 请注意,当前函数只对FAT12/FAT16生效。对于FAT32,返回None pub fn root_dir_end_bytes_offset(&self) -> Option { match self.bpb.fat_type { @@ -561,14 +556,14 @@ impl FATFileSystem { } } - /// @brief 获取簇在磁盘内的字节偏移量(相对磁盘起始位置。注意,不是分区内偏移量) + /// 获取簇在分区内的字节偏移量 pub fn cluster_bytes_offset(&self, cluster: Cluster) -> u64 { if cluster.cluster_num >= 2 { // 指定簇的第一个扇区号 let first_sec_of_cluster = (cluster.cluster_num - 2) * (self.bpb.sector_per_cluster as u64) + self.first_data_sector; - return (self.get_lba_from_offset(first_sec_of_cluster) * LBA_SIZE) as u64; + return first_sec_of_cluster * (self.bpb.bytes_per_sector as u64); } else { return 0; } @@ -727,11 +722,10 @@ impl FATFileSystem { } } - /// @brief 根据分区内的扇区偏移量,获得在磁盘上的LBA地址 + /// 获取分区内的扇区偏移量 #[inline] - pub fn get_lba_from_offset(&self, in_partition_sec_offset: u64) -> usize { - return (self.partition.lba_start - + in_partition_sec_offset * (self.bpb.bytes_per_sector as u64 / LBA_SIZE as u64)) + pub fn gendisk_lba_from_offset(&self, in_partition_sec_offset: u64) -> usize { + return (in_partition_sec_offset * (self.bpb.bytes_per_sector as u64 / LBA_SIZE as u64)) as usize; } @@ -747,12 +741,6 @@ impl FATFileSystem { return in_partition_bytes_offset / (self.bpb.bytes_per_sector as u64); } - /// @brief 根据磁盘上的字节偏移量,获取对应位置在分区内的字节偏移量 - #[inline] - pub fn get_in_partition_bytes_offset(&self, disk_bytes_offset: u64) -> u64 { - return disk_bytes_offset - (self.partition.lba_start * LBA_SIZE as u64); - } - /// @brief 根据字节偏移量计算在逻辑块内的字节偏移量 #[inline] pub fn get_in_block_offset(&self, bytes_offset: u64) -> u64 { @@ -888,13 +876,13 @@ impl FATFileSystem { /// @brief 执行文件系统卸载前的一些准备工作:设置好对应的标志位,并把缓存中的数据刷入磁盘 pub fn umount(&mut self) -> Result<(), SystemError> { - self.fs_info.0.lock().flush(&self.partition)?; + self.fs_info.0.lock().flush(&self.gendisk)?; self.set_shut_bit_ok()?; self.set_hard_error_bit_ok()?; - self.partition.disk().sync()?; + self.gendisk.sync()?; return Ok(()); } @@ -959,12 +947,12 @@ impl FATFileSystem { fat_type.get_fat_bytes_offset(start_cluster, fat_start_sector, bytes_per_sec); let in_block_offset = self.get_in_block_offset(part_bytes_offset); - let lba = self.get_lba_from_offset(self.bytes_to_sector(part_bytes_offset)); + let lba = self.gendisk_lba_from_offset(self.bytes_to_sector(part_bytes_offset)); // 由于FAT12的FAT表不大于6K,因此直接读取6K let num_lba = (6 * 1024) / LBA_SIZE; let mut v: Vec = vec![0; num_lba * LBA_SIZE]; - self.partition.disk().read_at(lba, num_lba, &mut v)?; + self.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; @@ -1006,12 +994,10 @@ impl FATFileSystem { ); let in_block_offset = self.get_in_block_offset(part_bytes_offset); - let lba = self.get_lba_from_offset(self.bytes_to_sector(part_bytes_offset)); + let lba = self.gendisk_lba_from_offset(self.bytes_to_sector(part_bytes_offset)); let mut v: Vec = vec![0; self.lba_per_sector() * LBA_SIZE]; - self.partition - .disk() - .read_at_sync(lba, self.lba_per_sector(), &mut v)?; + self.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; @@ -1037,12 +1023,10 @@ impl FATFileSystem { ); let in_block_offset = self.get_in_block_offset(part_bytes_offset); - let lba = self.get_lba_from_offset(self.bytes_to_sector(part_bytes_offset)); + let lba = self.gendisk_lba_from_offset(self.bytes_to_sector(part_bytes_offset)); let mut v: Vec = vec![0; self.lba_per_sector() * LBA_SIZE]; - self.partition - .disk() - .read_at_sync(lba, self.lba_per_sector(), &mut v)?; + self.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; @@ -1085,10 +1069,10 @@ impl FATFileSystem { let in_block_offset = self.get_in_block_offset(fat_part_bytes_offset); - let lba = self.get_lba_from_offset(self.bytes_to_sector(fat_part_bytes_offset)); + let lba = self.gendisk_lba_from_offset(self.bytes_to_sector(fat_part_bytes_offset)); let mut v: Vec = vec![0; LBA_SIZE]; - self.partition.disk().read_at_sync(lba, 1, &mut v)?; + self.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; @@ -1103,7 +1087,7 @@ impl FATFileSystem { // 写回数据到磁盘上 cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; cursor.write_u16(new_val)?; - self.partition.disk().write_at(lba, 1, cursor.as_slice())?; + self.gendisk.write_at(cursor.as_slice(), lba)?; return Ok(()); } FATType::FAT16(_) => { @@ -1117,16 +1101,16 @@ impl FATFileSystem { let in_block_offset = self.get_in_block_offset(fat_part_bytes_offset); - let lba = self.get_lba_from_offset(self.bytes_to_sector(fat_part_bytes_offset)); + let lba = self.gendisk_lba_from_offset(self.bytes_to_sector(fat_part_bytes_offset)); let mut v: Vec = vec![0; LBA_SIZE]; - self.partition.disk().read_at(lba, 1, &mut v)?; + self.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; cursor.write_u16(raw_val)?; - self.partition.disk().write_at(lba, 1, cursor.as_slice())?; + self.gendisk.write_at(cursor.as_slice(), lba)?; return Ok(()); } @@ -1142,11 +1126,11 @@ impl FATFileSystem { // 当前操作的FAT表在磁盘上的字节偏移量 let f_offset: u64 = fat_part_bytes_offset + i * fat_size; let in_block_offset: u64 = self.get_in_block_offset(f_offset); - let lba = self.get_lba_from_offset(self.bytes_to_sector(f_offset)); + let lba = self.gendisk_lba_from_offset(self.bytes_to_sector(f_offset)); // debug!("set entry, lba={lba}, in_block_offset={in_block_offset}"); let mut v: Vec = vec![0; LBA_SIZE]; - self.partition.disk().read_at(lba, 1, &mut v)?; + self.gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; @@ -1181,7 +1165,7 @@ impl FATFileSystem { cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; cursor.write_u32(raw_val)?; - self.partition.disk().write_at(lba, 1, cursor.as_slice())?; + self.gendisk.write_at(cursor.as_slice(), lba)?; } return Ok(()); @@ -1189,16 +1173,15 @@ impl FATFileSystem { } } - /// @brief 清空指定的簇 + /// # 清空指定的簇 /// - /// @param cluster 要被清空的簇 + /// # 参数 + /// - cluster 要被清空的簇 pub fn zero_cluster(&self, cluster: Cluster) -> Result<(), SystemError> { // 准备数据,用于写入 let zeros: Vec = vec![0u8; self.bytes_per_cluster() as usize]; - let offset: usize = self.cluster_bytes_offset(cluster) as usize; - self.partition - .disk() - .write_at_bytes(offset, zeros.len(), zeros.as_slice())?; + let offset = self.cluster_bytes_offset(cluster) as usize; + self.gendisk.write_at_bytes(&zeros, offset)?; return Ok(()); } } @@ -1225,19 +1208,18 @@ impl FATFsInfo { /// @brief 从磁盘上读取FAT文件系统的FSInfo结构体 /// /// @param partition 磁盘分区 - /// @param in_disk_fs_info_offset FSInfo扇区在磁盘内的字节偏移量(单位:字节) + /// @param in_gendisk_fs_info_offset FSInfo扇区在gendisk内的字节偏移量(单位:字节) /// @param bytes_per_sec 每扇区字节数 pub fn new( - partition: Arc, - in_disk_fs_info_offset: u64, + gendisk: &Arc, + in_gendisk_fs_info_offset: usize, bytes_per_sec: usize, ) -> Result { let mut v = vec![0; bytes_per_sec]; - // 计算fs_info扇区在磁盘上的字节偏移量,从磁盘读取数据 - partition - .disk() - .read_at_sync(in_disk_fs_info_offset as usize / LBA_SIZE, 1, &mut v)?; + // 读取磁盘上的FsInfo扇区 + gendisk.read_at_bytes(&mut v, in_gendisk_fs_info_offset)?; + let mut cursor = VecCursor::new(v); let mut fsinfo = FATFsInfo { @@ -1253,7 +1235,7 @@ impl FATFsInfo { fsinfo.trail_sig = cursor.read_u32()?; fsinfo.dirty = false; - fsinfo.offset = Some(in_disk_fs_info_offset); + fsinfo.offset = Some(gendisk.disk_bytes_offset(in_gendisk_fs_info_offset) as u64); if fsinfo.is_valid() { return Ok(fsinfo); @@ -1322,14 +1304,14 @@ impl FATFsInfo { /// @brief 把fs info刷入磁盘 /// /// @param partition fs info所在的分区 - pub fn flush(&self, partition: &Arc) -> Result<(), SystemError> { + pub fn flush(&self, gendisk: &Arc) -> Result<(), SystemError> { if let Some(off) = self.offset { let in_block_offset = off % LBA_SIZE as u64; let lba = off as usize / LBA_SIZE; let mut v: Vec = vec![0; LBA_SIZE]; - partition.disk().read_at(lba, 1, &mut v)?; + gendisk.read_at(&mut v, lba)?; let mut cursor: VecCursor = VecCursor::new(v); cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?; @@ -1342,7 +1324,7 @@ impl FATFsInfo { cursor.seek(SeekFrom::SeekCurrent(12))?; cursor.write_u32(self.trail_sig)?; - partition.disk().write_at(lba, 1, cursor.as_slice())?; + gendisk.write_at(cursor.as_slice(), lba)?; } return Ok(()); } diff --git a/kernel/src/filesystem/mbr.rs b/kernel/src/filesystem/mbr.rs index b3e900de3..843be8959 100644 --- a/kernel/src/filesystem/mbr.rs +++ b/kernel/src/filesystem/mbr.rs @@ -148,7 +148,45 @@ impl MbrDiskPartionTable { return partitions; } + /// # partitions_raw - 获取磁盘的分区信息,不包含磁盘设备信息 + pub fn partitions_raw(&self) -> MbrPartitionIter { + MbrPartitionIter::new(self) + } + pub fn is_valid(&self) -> bool { self.bs_trailsig == 0xAA55 } } + +pub struct MbrPartitionIter<'a> { + table: &'a MbrDiskPartionTable, + index: usize, +} + +impl<'a> MbrPartitionIter<'a> { + fn new(table: &'a MbrDiskPartionTable) -> Self { + MbrPartitionIter { table, index: 0 } + } +} + +impl<'a> Iterator for MbrPartitionIter<'a> { + type Item = Partition; + + fn next(&mut self) -> Option { + while self.index < 4 { + let entry = &self.table.dpte[self.index]; + let index = self.index; + self.index += 1; + if entry.is_valid() { + let p = Partition::new_raw( + self.table.dpte[index].starting_sector() as u64, + self.table.dpte[index].starting_lba as u64, + self.table.dpte[index].total_sectors as u64, + index as u16, + ); + return Some(p); + } + } + return None; + } +} diff --git a/kernel/src/filesystem/vfs/core.rs b/kernel/src/filesystem/vfs/core.rs index 5a1d55176..41984a715 100644 --- a/kernel/src/filesystem/vfs/core.rs +++ b/kernel/src/filesystem/vfs/core.rs @@ -5,7 +5,7 @@ use log::{error, info}; use system_error::SystemError; use crate::{ - driver::base::block::disk_info::Partition, + driver::base::block::manager::block_dev_manager, filesystem::{ devfs::devfs_init, fat::fs::FATFileSystem, @@ -26,6 +26,9 @@ use super::{ IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES, }; +/// 当没有指定根文件系统时,尝试的根文件系统列表 +const ROOTFS_TRY_LIST: [&str; 4] = ["/dev/sda1", "/dev/sda", "/dev/vda1", "/dev/vda"]; + /// @brief 原子地生成新的Inode号。 /// 请注意,所有的inode号都需要通过该函数来生成.全局的inode号,除了以下两个特殊的以外,都是唯一的 /// 特殊的两个inode号: @@ -113,39 +116,22 @@ fn migrate_virtual_filesystem(new_fs: Arc) -> Result<(), SystemE return Ok(()); } -fn root_partition() -> Arc { - #[cfg(target_arch = "x86_64")] - { - use alloc::string::ToString; - return crate::driver::disk::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() { - error!("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> { - info!("Try to mount FAT32 as root fs..."); - let partiton: Arc = root_partition(); + info!("Try to mount root fs..."); + block_dev_manager().print_gendisks(); + + let gendisk = ROOTFS_TRY_LIST + .iter() + .find_map(|&path| { + if let Some(gd) = block_dev_manager().lookup_gendisk_by_path(path) { + info!("Use {} as rootfs", path); + return Some(gd); + } + return None; + }) + .ok_or(SystemError::ENODEV)?; - let fatfs: Result, SystemError> = FATFileSystem::new(partiton); + let fatfs: Result, SystemError> = FATFileSystem::new(gendisk); if fatfs.is_err() { error!( "Failed to initialize fatfs, code={:?}", diff --git a/kernel/src/init/initial_kthread.rs b/kernel/src/init/initial_kthread.rs index 7c70ad8cc..0cc88de36 100644 --- a/kernel/src/init/initial_kthread.rs +++ b/kernel/src/init/initial_kthread.rs @@ -33,11 +33,11 @@ fn kernel_init() -> Result<(), SystemError> { // 由于目前加锁,速度过慢,所以先不开启双缓冲 // scm_enable_double_buffer().expect("Failed to enable double buffer"); - virtio_probe(); #[cfg(target_arch = "x86_64")] crate::driver::disk::ahci::ahci_init() - .inspect_err(|e| log::warn!("Failed to initialize AHCI: {e:?}")) + .inspect_err(|e| log::error!("ahci_init failed: {:?}", e)) .ok(); + virtio_probe(); mount_root_fs().expect("Failed to mount root fs"); e1000e_init(); net_init().unwrap_or_else(|err| {