os/device/block/
ram_disk.rs

1use super::super::{DeviceType, Driver};
2use super::BlockDriver;
3use crate::sync::SpinLock;
4use alloc::string::String;
5use alloc::sync::Arc;
6use alloc::vec;
7use alloc::vec::Vec;
8
9/// 内存模拟的块设备
10///
11/// 用于测试和开发
12pub struct RamDisk {
13    /// 存储数据
14    data: SpinLock<Vec<u8>>,
15
16    /// 块大小
17    block_size: usize,
18
19    /// 设备 ID
20    device_id: usize,
21}
22
23impl RamDisk {
24    /// 创建指定大小的内存磁盘
25    pub fn new(size: usize, block_size: usize, device_id: usize) -> Arc<Self> {
26        Arc::new(Self {
27            data: SpinLock::new(vec![0u8; size]),
28            block_size,
29            device_id,
30        })
31    }
32
33    /// 从字节数组创建
34    pub fn from_bytes(data: Vec<u8>, block_size: usize, device_id: usize) -> Arc<Self> {
35        Arc::new(Self {
36            data: SpinLock::new(data),
37            block_size,
38            device_id,
39        })
40    }
41
42    /// 获取原始数据(用于调试)
43    pub fn raw_data(&self) -> Vec<u8> {
44        self.data.lock().clone()
45    }
46
47    /// 获取设备 ID
48    pub fn device_id(&self) -> usize {
49        self.device_id
50    }
51}
52
53impl Driver for RamDisk {
54    fn try_handle_interrupt(&self, _irq: Option<usize>) -> bool {
55        false // RamDisk 不处理中断
56    }
57
58    fn device_type(&self) -> DeviceType {
59        DeviceType::Block
60    }
61
62    fn get_id(&self) -> String {
63        alloc::format!("ramdisk_{}", self.device_id)
64    }
65
66    fn as_block(&self) -> Option<&dyn BlockDriver> {
67        Some(self)
68    }
69}
70
71// 实现 BlockDriver trait
72impl BlockDriver for RamDisk {
73    fn read_block(&self, block_id: usize, buf: &mut [u8]) -> bool {
74        if buf.len() != self.block_size {
75            return false;
76        }
77
78        let data = self.data.lock();
79        let offset = block_id * self.block_size;
80
81        if offset + self.block_size > data.len() {
82            return false;
83        }
84
85        buf.copy_from_slice(&data[offset..offset + self.block_size]);
86        true
87    }
88
89    fn write_block(&self, block_id: usize, buf: &[u8]) -> bool {
90        if buf.len() != self.block_size {
91            return false;
92        }
93
94        let mut data = self.data.lock();
95        let offset = block_id * self.block_size;
96
97        if offset + self.block_size > data.len() {
98            return false;
99        }
100
101        data[offset..offset + self.block_size].copy_from_slice(buf);
102        true
103    }
104
105    fn flush(&self) -> bool {
106        true // 内存设备无需 flush
107    }
108
109    fn block_size(&self) -> usize {
110        self.block_size
111    }
112
113    fn total_blocks(&self) -> usize {
114        self.data.lock().len() / self.block_size
115    }
116}