Browse Source

feat: 添加gendisk抽象 (#903)

* feat: 添加gendisk抽象.

* 支持使用virtio磁盘作为根文件系统

* Update initial_kthread.rs to resolve conflict.

---------

Co-authored-by: Donkey Kane <[email protected]>
LoGin 6 months ago
parent
commit
9fa0e95eee

+ 115 - 3
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<Self> {
+        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<Self> {
+        // 检查是否相交
+        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<String>,
+    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<H: core::hash::Hasher>(&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<GenDisk>) -> Result<(), SystemError> {
+        Ok(())
+    }
 }
 
 /// @brief 块设备框架函数集

+ 34 - 12
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<dyn BlockDevice>, // 当前分区所属的磁盘
-    pub partno: u16,             // 在磁盘上的分区号
+    pub start_sector: SectorT,           // 该分区的起始扇区
+    pub lba_start: u64,                  // 起始LBA号
+    pub sectors_num: u64,                // 该分区的扇区数
+    disk: Option<Weak<dyn BlockDevice>>, // 当前分区所属的磁盘
+    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<dyn BlockDevice> {
-        return self.disk.upgrade().unwrap();
+        return self.disk.as_ref().unwrap().upgrade().unwrap();
+    }
+}
+
+impl TryInto<GeneralBlockRange> for Partition {
+    type Error = SystemError;
+
+    fn try_into(self) -> Result<GeneralBlockRange, Self::Error> {
+        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);
+        }
     }
 }

+ 195 - 0
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<dyn BlockDevice>,
+    range: GeneralBlockRange,
+    block_size_log2: u8,
+    idx: Option<u32>,
+}
+
+impl GenDisk {
+    /// 如果gendisk是整个磁盘,则idx为u32::MAX
+    pub const ENTIRE_DISK_IDX: u32 = u32::MAX;
+
+    pub fn new(
+        bdev: Weak<dyn BlockDevice>,
+        range: GeneralBlockRange,
+        idx: Option<u32>,
+    ) -> Arc<Self> {
+        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<dyn BlockDevice> {
+        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<usize, SystemError> {
+        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<usize, SystemError> {
+        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<usize, SystemError> {
+        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<usize, SystemError> {
+        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<u32, Arc<GenDisk>>,
+    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<u32, Arc<GenDisk>>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.data
+    }
+}
+
+impl DerefMut for GenDiskMap {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.data
+    }
+}

+ 238 - 0
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<BlockDevManager> = 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<InnerBlockDevManager>,
+}
+
+struct InnerBlockDevManager {
+    disks: HashMap<BlockDevName, Arc<dyn BlockDevice>>,
+}
+impl BlockDevManager {
+    pub fn new() -> Self {
+        BlockDevManager {
+            inner: SpinLock::new(InnerBlockDevManager {
+                disks: HashMap::new(),
+            }),
+        }
+    }
+
+    fn inner(&self) -> SpinLockGuard<InnerBlockDevManager> {
+        self.inner.lock()
+    }
+
+    /// 注册磁盘设备
+    pub fn register(&self, dev: Arc<dyn BlockDevice>) -> 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<dyn BlockDevice>) -> 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<dyn BlockDevice>) -> 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<dyn BlockDevice>,
+    ) -> Result<(), SystemError> {
+        let range = dev.disk_range();
+        self.register_gendisk_with_range(dev, range)
+    }
+
+    fn register_gendisk_with_range(
+        &self,
+        dev: &Arc<dyn BlockDevice>,
+        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<dyn BlockDevice>,
+        gendisk: Arc<GenDisk>,
+    ) -> 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<dyn BlockDevice>) {
+        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<Arc<GenDisk>> {
+        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<InnerBlockDevMeta>,
+}
+
+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<InnerBlockDevMeta> {
+        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()
+    }
+}

+ 3 - 0
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 {

+ 94 - 5
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<Arc<VirtIOBlkDevice>> {
 pub fn virtio_blk(transport: VirtIOTransport, dev_id: Arc<DeviceId>) {
     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<dyn VirtIODevice>)
             .expect("Add virtio blk failed");
     }
 }
 
+static mut VIRTIOBLK_MANAGER: Option<VirtIOBlkManager> = 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<InnerVirtIOBlkManager>,
+}
+
+struct InnerVirtIOBlkManager {
+    id_bmp: bitmap::StaticBitmap<{ VirtIOBlkManager::MAX_DEVICES }>,
+    devname: [Option<BlockDevName>; 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<InnerVirtIOBlkManager> {
+        self.inner.lock()
+    }
+
+    pub fn alloc_id(&self) -> Option<BlockDevName> {
+        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<DeviceId>,
     inner: SpinLock<InnerVirtIOBlkDevice>,
     locked_kobj_state: LockedKObjectState,
@@ -87,6 +153,7 @@ unsafe impl Sync for VirtIOBlkDevice {}
 
 impl VirtIOBlkDevice {
     pub fn new(transport: VirtIOTransport, dev_id: Arc<DeviceId>) -> Option<Arc<Self>> {
+        let devname = virtioblk_manager().alloc_id()?;
         let irq = transport.irq().map(|irq| IrqNumber::new(irq.data()));
         let device_inner = VirtIOBlk::<HalImpl, VirtIOTransport>::new(transport);
         if let Err(e) = device_inner {
@@ -97,6 +164,7 @@ impl VirtIOBlkDevice {
         let mut device_inner: VirtIOBlk<HalImpl, VirtIOTransport> = 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<dyn VirtIODevice>) -> Result<(), SystemError> {
-        let _dev = device
+        let dev = device
             .clone()
             .arc_any()
             .downcast::<VirtIOBlkDevice>()
@@ -423,6 +511,7 @@ impl VirtIODriver for VirtIOBlkDriver {
                 SystemError::EINVAL
             })?;
 
+        block_dev_manager().register(dev as Arc<dyn BlockDevice>)?;
         return Ok(());
     }
 }

+ 46 - 31
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<Arc<Partition>>, // 磁盘分区数组
     // port: &'static mut HbaPort,      // 控制硬盘的端口
     pub ctrl_num: u8,
@@ -45,16 +48,21 @@ pub struct AhciDisk {
 
 /// @brief: 带锁的AhciDisk
 #[derive(Debug)]
-pub struct LockedAhciDisk(pub SpinLock<AhciDisk>);
+pub struct LockedAhciDisk {
+    blkdev_meta: BlockDevMeta,
+    inner: SpinLock<AhciDisk>,
+}
+
+impl LockedAhciDisk {
+    pub fn inner(&self) -> SpinLockGuard<AhciDisk> {
+        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<Arc<LockedAhciDisk>, SystemError> {
+    pub fn new(ctrl_num: u8, port_num: u8) -> Result<Arc<LockedAhciDisk>, SystemError> {
+        let devname = scsi_manager().alloc_id().ok_or(SystemError::EBUSY)?;
         // 构建磁盘结构体
-        let result: Arc<LockedAhciDisk> = Arc::new_cyclic(|self_ref| {
-            LockedAhciDisk(SpinLock::new(AhciDisk {
-                name,
-                flags,
-                partitions: Default::default(),
+        let result: Arc<LockedAhciDisk> = 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<dyn BlockDevice>);
-        result.0.lock().partitions = partitions;
+        result.inner().partitions = partitions;
 
         return Ok(result);
     }
 
     /// @brief: 从磁盘中读取 MBR 分区表结构体
     pub fn read_mbr_table(&self) -> Result<MbrDiskPartionTable, SystemError> {
-        let disk = self.0.lock().self_ref.upgrade().unwrap() as Arc<dyn BlockDevice>;
+        let disk = self.inner().self_ref.upgrade().unwrap() as Arc<dyn BlockDevice>;
         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<dyn Device> {
-        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<Arc<Partition>> {
-        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<usize, SystemError> {
-        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<usize, SystemError> {
-        self.0.lock().write_at(lba_id_start, count, buf)
+        self.inner().write_at(lba_id_start, count, buf)
     }
 }

+ 8 - 52
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<Vec<&mut HbaMem>> = SpinLock::new(Vec::new());
-static LOCKED_DISKS_LIST: SpinLock<Vec<Arc<LockedAhciDisk>>> = 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<Arc<LockedAhciDisk>> {
-    let disks_list = LOCKED_DISKS_LIST.lock();
-    return disks_list.clone();
-}
-
-/// @brief: 通过 name 获取 disk
-pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemError> {
-    let disks_list: SpinLockGuard<Vec<Arc<LockedAhciDisk>>> = 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<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock();

+ 1 - 0
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;

+ 74 - 0
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<ScsiManager> = 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<InnerScsiManager>,
+}
+
+struct InnerScsiManager {
+    id_bmp: bitmap::StaticBitmap<{ ScsiManager::MAX_DEVICES }>,
+    devname: [Option<BlockDevName>; 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<InnerScsiManager> {
+        self.inner.lock()
+    }
+
+    pub fn alloc_id(&self) -> Option<BlockDevName> {
+        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;
+    }
+}

+ 1 - 2
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);
         }
     }

+ 3 - 7
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<Partition>) -> Result<BiosParameterBlock, SystemError> {
+    pub fn new(gendisk: &Arc<GenDisk>) -> Result<BiosParameterBlock, SystemError> {
         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);
 

+ 54 - 68
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<FATFileSystem>,
@@ -326,9 +322,8 @@ impl FATFile {
         }
 
         let zeroes: Vec<u8> = 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<u64>,
     /// 文件夹名称
     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<FATFileSystem>, disk_bytes_offset: u64) -> Result<(), SystemError> {
+    pub fn flush(
+        &self,
+        fs: Arc<FATFileSystem>,
+        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<u8> = 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<FATFileSystem>,
-        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<u8> = 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<FATFileSystem>,
-    in_disk_bytes_offset: u64,
+    gendisk_bytes_offset: u64,
 ) -> Result<FATRawDirEntry, SystemError> {
     // 块内偏移量
-    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<u8> = 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);
     // 切换游标到对应位置

+ 56 - 74
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<Partition>,
+    pub gendisk: Arc<GenDisk>,
     /// 当前文件系统的BOPB
     pub bpb: BiosParameterBlock,
     /// 当前文件系统的第一个数据扇区(相对分区开始位置)
@@ -281,17 +282,16 @@ impl FATFileSystem {
     /// FAT32允许的最大簇号
     pub const FAT32_MAX_CLUSTER: u32 = 0x0FFFFFF7;
 
-    pub fn new(partition: Arc<Partition>) -> Result<Arc<FATFileSystem>, SystemError> {
-        let bpb = BiosParameterBlock::new(partition.clone())?;
-
+    pub fn new(gendisk: Arc<GenDisk>) -> Result<Arc<FATFileSystem>, 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<FATFileSystem> = 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<u8> = 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<u8> = 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<u64> {
         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<u8> = 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<u8> = 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<u8> = 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<u8> = 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<u8> = 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<u8> = 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<u8> = 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<Partition>,
-        in_disk_fs_info_offset: u64,
+        gendisk: &Arc<GenDisk>,
+        in_gendisk_fs_info_offset: usize,
         bytes_per_sec: usize,
     ) -> Result<Self, SystemError> {
         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<Partition>) -> Result<(), SystemError> {
+    pub fn flush(&self, gendisk: &Arc<GenDisk>) -> 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<u8> = 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(());
     }

+ 38 - 0
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<Self::Item> {
+        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;
+    }
+}

+ 18 - 32
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<dyn FileSystem>) -> Result<(), SystemE
     return Ok(());
 }
 
-fn root_partition() -> Arc<Partition> {
-    #[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<Partition> = 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<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton);
+    let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(gendisk);
     if fatfs.is_err() {
         error!(
             "Failed to initialize fatfs, code={:?}",

+ 2 - 2
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| {